@@ -3716,24 +3716,26 @@ static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
37163716 return err ;
37173717}
37183718
3719- static void devlink_nl_region_notify (struct devlink_region * region ,
3720- struct devlink_snapshot * snapshot ,
3721- enum devlink_command cmd )
3719+ static struct sk_buff *
3720+ devlink_nl_region_notify_build (struct devlink_region * region ,
3721+ struct devlink_snapshot * snapshot ,
3722+ enum devlink_command cmd , u32 portid , u32 seq )
37223723{
37233724 struct devlink * devlink = region -> devlink ;
37243725 struct sk_buff * msg ;
37253726 void * hdr ;
37263727 int err ;
37273728
3728- WARN_ON (cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL );
37293729
37303730 msg = nlmsg_new (NLMSG_DEFAULT_SIZE , GFP_KERNEL );
37313731 if (!msg )
3732- return ;
3732+ return ERR_PTR ( - ENOMEM ) ;
37333733
3734- hdr = genlmsg_put (msg , 0 , 0 , & devlink_nl_family , 0 , cmd );
3735- if (!hdr )
3734+ hdr = genlmsg_put (msg , portid , seq , & devlink_nl_family , 0 , cmd );
3735+ if (!hdr ) {
3736+ err = - EMSGSIZE ;
37363737 goto out_free_msg ;
3738+ }
37373739
37383740 err = devlink_nl_put_handle (msg , devlink );
37393741 if (err )
@@ -3757,15 +3759,30 @@ static void devlink_nl_region_notify(struct devlink_region *region,
37573759 }
37583760 genlmsg_end (msg , hdr );
37593761
3760- genlmsg_multicast_netns (& devlink_nl_family , devlink_net (devlink ),
3761- msg , 0 , DEVLINK_MCGRP_CONFIG , GFP_KERNEL );
3762-
3763- return ;
3762+ return msg ;
37643763
37653764out_cancel_msg :
37663765 genlmsg_cancel (msg , hdr );
37673766out_free_msg :
37683767 nlmsg_free (msg );
3768+ return ERR_PTR (err );
3769+ }
3770+
3771+ static void devlink_nl_region_notify (struct devlink_region * region ,
3772+ struct devlink_snapshot * snapshot ,
3773+ enum devlink_command cmd )
3774+ {
3775+ struct devlink * devlink = region -> devlink ;
3776+ struct sk_buff * msg ;
3777+
3778+ WARN_ON (cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL );
3779+
3780+ msg = devlink_nl_region_notify_build (region , snapshot , cmd , 0 , 0 );
3781+ if (IS_ERR (msg ))
3782+ return ;
3783+
3784+ genlmsg_multicast_netns (& devlink_nl_family , devlink_net (devlink ),
3785+ msg , 0 , DEVLINK_MCGRP_CONFIG , GFP_KERNEL );
37693786}
37703787
37713788/**
@@ -4069,6 +4086,8 @@ static int
40694086devlink_nl_cmd_region_new (struct sk_buff * skb , struct genl_info * info )
40704087{
40714088 struct devlink * devlink = info -> user_ptr [0 ];
4089+ struct devlink_snapshot * snapshot ;
4090+ struct nlattr * snapshot_id_attr ;
40724091 struct devlink_region * region ;
40734092 const char * region_name ;
40744093 u32 snapshot_id ;
@@ -4080,11 +4099,6 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
40804099 return - EINVAL ;
40814100 }
40824101
4083- if (!info -> attrs [DEVLINK_ATTR_REGION_SNAPSHOT_ID ]) {
4084- NL_SET_ERR_MSG_MOD (info -> extack , "No snapshot id provided" );
4085- return - EINVAL ;
4086- }
4087-
40884102 region_name = nla_data (info -> attrs [DEVLINK_ATTR_REGION_NAME ]);
40894103 region = devlink_region_get_by_name (devlink , region_name );
40904104 if (!region ) {
@@ -4102,16 +4116,25 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
41024116 return - ENOSPC ;
41034117 }
41044118
4105- snapshot_id = nla_get_u32 (info -> attrs [DEVLINK_ATTR_REGION_SNAPSHOT_ID ]);
4119+ snapshot_id_attr = info -> attrs [DEVLINK_ATTR_REGION_SNAPSHOT_ID ];
4120+ if (snapshot_id_attr ) {
4121+ snapshot_id = nla_get_u32 (snapshot_id_attr );
41064122
4107- if (devlink_region_snapshot_get_by_id (region , snapshot_id )) {
4108- NL_SET_ERR_MSG_MOD (info -> extack , "The requested snapshot id is already in use" );
4109- return - EEXIST ;
4110- }
4123+ if (devlink_region_snapshot_get_by_id (region , snapshot_id )) {
4124+ NL_SET_ERR_MSG_MOD (info -> extack , "The requested snapshot id is already in use" );
4125+ return - EEXIST ;
4126+ }
41114127
4112- err = __devlink_snapshot_id_insert (devlink , snapshot_id );
4113- if (err )
4114- return err ;
4128+ err = __devlink_snapshot_id_insert (devlink , snapshot_id );
4129+ if (err )
4130+ return err ;
4131+ } else {
4132+ err = __devlink_region_snapshot_id_get (devlink , & snapshot_id );
4133+ if (err ) {
4134+ NL_SET_ERR_MSG_MOD (info -> extack , "Failed to allocate a new snapshot id" );
4135+ return err ;
4136+ }
4137+ }
41154138
41164139 err = region -> ops -> snapshot (devlink , info -> extack , & data );
41174140 if (err )
@@ -4121,13 +4144,38 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
41214144 if (err )
41224145 goto err_snapshot_create ;
41234146
4147+ if (!snapshot_id_attr ) {
4148+ struct sk_buff * msg ;
4149+
4150+ snapshot = devlink_region_snapshot_get_by_id (region ,
4151+ snapshot_id );
4152+ if (WARN_ON (!snapshot ))
4153+ return - EINVAL ;
4154+
4155+ msg = devlink_nl_region_notify_build (region , snapshot ,
4156+ DEVLINK_CMD_REGION_NEW ,
4157+ info -> snd_portid ,
4158+ info -> snd_seq );
4159+ err = PTR_ERR_OR_ZERO (msg );
4160+ if (err )
4161+ goto err_notify ;
4162+
4163+ err = genlmsg_reply (msg , info );
4164+ if (err )
4165+ goto err_notify ;
4166+ }
4167+
41244168 return 0 ;
41254169
41264170err_snapshot_create :
41274171 region -> ops -> destructor (data );
41284172err_snapshot_capture :
41294173 __devlink_snapshot_id_decrement (devlink , snapshot_id );
41304174 return err ;
4175+
4176+ err_notify :
4177+ devlink_region_snapshot_del (region , snapshot );
4178+ return err ;
41314179}
41324180
41334181static int devlink_nl_cmd_region_read_chunk_fill (struct sk_buff * msg ,
0 commit comments