@@ -6124,25 +6124,33 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work)
61246124 return err ;
61256125}
61266126
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 )
61306132{
6131- struct smb2_buffer_desc_v1 * desc =
6132- (struct smb2_buffer_desc_v1 * )& req -> Buffer [0 ];
6133- int err ;
6134-
61356133 if (work -> conn -> dialect == SMB30_PROT_ID &&
6136- req -> Channel != SMB2_CHANNEL_RDMA_V1 )
6134+ Channel != SMB2_CHANNEL_RDMA_V1 )
61376135 return - EINVAL ;
61386136
6139- if (req -> ReadChannelInfoOffset == 0 ||
6140- le16_to_cpu (req -> ReadChannelInfoLength ) < sizeof (* desc ))
6137+ if (ChannelInfoOffset == 0 ||
6138+ le16_to_cpu (ChannelInfoLength ) < sizeof (* desc ))
61416139 return - EINVAL ;
61426140
61436141 work -> need_invalidate_rkey =
6144- (req -> Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE );
6142+ (Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE );
61456143 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 ;
61466154
61476155 err = ksmbd_conn_rdma_write (work -> conn , data_buf , length ,
61486156 le32_to_cpu (desc -> token ),
@@ -6165,7 +6173,7 @@ int smb2_read(struct ksmbd_work *work)
61656173 struct ksmbd_conn * conn = work -> conn ;
61666174 struct smb2_read_req * req ;
61676175 struct smb2_read_rsp * rsp ;
6168- struct ksmbd_file * fp ;
6176+ struct ksmbd_file * fp = NULL ;
61696177 loff_t offset ;
61706178 size_t length , mincount ;
61716179 ssize_t nbytes = 0 , remain_bytes = 0 ;
@@ -6179,6 +6187,18 @@ int smb2_read(struct ksmbd_work *work)
61796187 return smb2_read_pipe (work );
61806188 }
61816189
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+
61826202 fp = ksmbd_lookup_fd_slow (work , le64_to_cpu (req -> VolatileFileId ),
61836203 le64_to_cpu (req -> PersistentFileId ));
61846204 if (!fp ) {
@@ -6364,21 +6384,6 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
63646384
63656385 desc = (struct smb2_buffer_desc_v1 * )& req -> Buffer [0 ];
63666386
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-
63826387 data_buf = kvmalloc (length , GFP_KERNEL | __GFP_ZERO );
63836388 if (!data_buf )
63846389 return - ENOMEM ;
@@ -6425,6 +6430,20 @@ int smb2_write(struct ksmbd_work *work)
64256430 return smb2_write_pipe (work );
64266431 }
64276432
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+
64286447 if (!test_tree_conn_flag (work -> tcon , KSMBD_TREE_CONN_FLAG_WRITABLE )) {
64296448 ksmbd_debug (SMB , "User does not have write permission\n" );
64306449 err = - EACCES ;
0 commit comments