@@ -6124,25 +6124,33 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work)
6124
6124
return err ;
6125
6125
}
6126
6126
6127
- static ssize_t smb2_read_rdma_channel (struct ksmbd_work * work ,
6128
- struct smb2_read_req * req , void * data_buf ,
6129
- size_t length )
6127
+ static int smb2_set_remote_key_for_rdma (struct ksmbd_work * work ,
6128
+ struct smb2_buffer_desc_v1 * desc ,
6129
+ __le32 Channel ,
6130
+ __le16 ChannelInfoOffset ,
6131
+ __le16 ChannelInfoLength )
6130
6132
{
6131
- struct smb2_buffer_desc_v1 * desc =
6132
- (struct smb2_buffer_desc_v1 * )& req -> Buffer [0 ];
6133
- int err ;
6134
-
6135
6133
if (work -> conn -> dialect == SMB30_PROT_ID &&
6136
- req -> Channel != SMB2_CHANNEL_RDMA_V1 )
6134
+ Channel != SMB2_CHANNEL_RDMA_V1 )
6137
6135
return - EINVAL ;
6138
6136
6139
- if (req -> ReadChannelInfoOffset == 0 ||
6140
- le16_to_cpu (req -> ReadChannelInfoLength ) < sizeof (* desc ))
6137
+ if (ChannelInfoOffset == 0 ||
6138
+ le16_to_cpu (ChannelInfoLength ) < sizeof (* desc ))
6141
6139
return - EINVAL ;
6142
6140
6143
6141
work -> need_invalidate_rkey =
6144
- (req -> Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE );
6142
+ (Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE );
6145
6143
work -> remote_key = le32_to_cpu (desc -> token );
6144
+ return 0 ;
6145
+ }
6146
+
6147
+ static ssize_t smb2_read_rdma_channel (struct ksmbd_work * work ,
6148
+ struct smb2_read_req * req , void * data_buf ,
6149
+ size_t length )
6150
+ {
6151
+ struct smb2_buffer_desc_v1 * desc =
6152
+ (struct smb2_buffer_desc_v1 * )& req -> Buffer [0 ];
6153
+ int err ;
6146
6154
6147
6155
err = ksmbd_conn_rdma_write (work -> conn , data_buf , length ,
6148
6156
le32_to_cpu (desc -> token ),
@@ -6165,7 +6173,7 @@ int smb2_read(struct ksmbd_work *work)
6165
6173
struct ksmbd_conn * conn = work -> conn ;
6166
6174
struct smb2_read_req * req ;
6167
6175
struct smb2_read_rsp * rsp ;
6168
- struct ksmbd_file * fp ;
6176
+ struct ksmbd_file * fp = NULL ;
6169
6177
loff_t offset ;
6170
6178
size_t length , mincount ;
6171
6179
ssize_t nbytes = 0 , remain_bytes = 0 ;
@@ -6179,6 +6187,18 @@ int smb2_read(struct ksmbd_work *work)
6179
6187
return smb2_read_pipe (work );
6180
6188
}
6181
6189
6190
+ if (req -> Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE ||
6191
+ req -> Channel == SMB2_CHANNEL_RDMA_V1 ) {
6192
+ err = smb2_set_remote_key_for_rdma (work ,
6193
+ (struct smb2_buffer_desc_v1 * )
6194
+ & req -> Buffer [0 ],
6195
+ req -> Channel ,
6196
+ req -> ReadChannelInfoOffset ,
6197
+ req -> ReadChannelInfoLength );
6198
+ if (err )
6199
+ goto out ;
6200
+ }
6201
+
6182
6202
fp = ksmbd_lookup_fd_slow (work , le64_to_cpu (req -> VolatileFileId ),
6183
6203
le64_to_cpu (req -> PersistentFileId ));
6184
6204
if (!fp ) {
@@ -6364,21 +6384,6 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
6364
6384
6365
6385
desc = (struct smb2_buffer_desc_v1 * )& req -> Buffer [0 ];
6366
6386
6367
- if (work -> conn -> dialect == SMB30_PROT_ID &&
6368
- req -> Channel != SMB2_CHANNEL_RDMA_V1 )
6369
- return - EINVAL ;
6370
-
6371
- if (req -> Length != 0 || req -> DataOffset != 0 )
6372
- return - EINVAL ;
6373
-
6374
- if (req -> WriteChannelInfoOffset == 0 ||
6375
- le16_to_cpu (req -> WriteChannelInfoLength ) < sizeof (* desc ))
6376
- return - EINVAL ;
6377
-
6378
- work -> need_invalidate_rkey =
6379
- (req -> Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE );
6380
- work -> remote_key = le32_to_cpu (desc -> token );
6381
-
6382
6387
data_buf = kvmalloc (length , GFP_KERNEL | __GFP_ZERO );
6383
6388
if (!data_buf )
6384
6389
return - ENOMEM ;
@@ -6425,6 +6430,20 @@ int smb2_write(struct ksmbd_work *work)
6425
6430
return smb2_write_pipe (work );
6426
6431
}
6427
6432
6433
+ if (req -> Channel == SMB2_CHANNEL_RDMA_V1 ||
6434
+ req -> Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE ) {
6435
+ if (req -> Length != 0 || req -> DataOffset != 0 )
6436
+ return - EINVAL ;
6437
+ err = smb2_set_remote_key_for_rdma (work ,
6438
+ (struct smb2_buffer_desc_v1 * )
6439
+ & req -> Buffer [0 ],
6440
+ req -> Channel ,
6441
+ req -> WriteChannelInfoOffset ,
6442
+ req -> WriteChannelInfoLength );
6443
+ if (err )
6444
+ goto out ;
6445
+ }
6446
+
6428
6447
if (!test_tree_conn_flag (work -> tcon , KSMBD_TREE_CONN_FLAG_WRITABLE )) {
6429
6448
ksmbd_debug (SMB , "User does not have write permission\n" );
6430
6449
err = - EACCES ;
0 commit comments