@@ -3716,24 +3716,26 @@ static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
3716
3716
return err ;
3717
3717
}
3718
3718
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 )
3722
3723
{
3723
3724
struct devlink * devlink = region -> devlink ;
3724
3725
struct sk_buff * msg ;
3725
3726
void * hdr ;
3726
3727
int err ;
3727
3728
3728
- WARN_ON (cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL );
3729
3729
3730
3730
msg = nlmsg_new (NLMSG_DEFAULT_SIZE , GFP_KERNEL );
3731
3731
if (!msg )
3732
- return ;
3732
+ return ERR_PTR ( - ENOMEM ) ;
3733
3733
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 ;
3736
3737
goto out_free_msg ;
3738
+ }
3737
3739
3738
3740
err = devlink_nl_put_handle (msg , devlink );
3739
3741
if (err )
@@ -3757,15 +3759,30 @@ static void devlink_nl_region_notify(struct devlink_region *region,
3757
3759
}
3758
3760
genlmsg_end (msg , hdr );
3759
3761
3760
- genlmsg_multicast_netns (& devlink_nl_family , devlink_net (devlink ),
3761
- msg , 0 , DEVLINK_MCGRP_CONFIG , GFP_KERNEL );
3762
-
3763
- return ;
3762
+ return msg ;
3764
3763
3765
3764
out_cancel_msg :
3766
3765
genlmsg_cancel (msg , hdr );
3767
3766
out_free_msg :
3768
3767
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 );
3769
3786
}
3770
3787
3771
3788
/**
@@ -4069,6 +4086,8 @@ static int
4069
4086
devlink_nl_cmd_region_new (struct sk_buff * skb , struct genl_info * info )
4070
4087
{
4071
4088
struct devlink * devlink = info -> user_ptr [0 ];
4089
+ struct devlink_snapshot * snapshot ;
4090
+ struct nlattr * snapshot_id_attr ;
4072
4091
struct devlink_region * region ;
4073
4092
const char * region_name ;
4074
4093
u32 snapshot_id ;
@@ -4080,11 +4099,6 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
4080
4099
return - EINVAL ;
4081
4100
}
4082
4101
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
-
4088
4102
region_name = nla_data (info -> attrs [DEVLINK_ATTR_REGION_NAME ]);
4089
4103
region = devlink_region_get_by_name (devlink , region_name );
4090
4104
if (!region ) {
@@ -4102,16 +4116,25 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
4102
4116
return - ENOSPC ;
4103
4117
}
4104
4118
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 );
4106
4122
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
+ }
4111
4127
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
+ }
4115
4138
4116
4139
err = region -> ops -> snapshot (devlink , info -> extack , & data );
4117
4140
if (err )
@@ -4121,13 +4144,38 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
4121
4144
if (err )
4122
4145
goto err_snapshot_create ;
4123
4146
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
+
4124
4168
return 0 ;
4125
4169
4126
4170
err_snapshot_create :
4127
4171
region -> ops -> destructor (data );
4128
4172
err_snapshot_capture :
4129
4173
__devlink_snapshot_id_decrement (devlink , snapshot_id );
4130
4174
return err ;
4175
+
4176
+ err_notify :
4177
+ devlink_region_snapshot_del (region , snapshot );
4178
+ return err ;
4131
4179
}
4132
4180
4133
4181
static int devlink_nl_cmd_region_read_chunk_fill (struct sk_buff * msg ,
0 commit comments