فهرست منبع

cifs: fix SMB1 breakage

SMB1 mounting broke in commit 35e2cc1ba755
("cifs: Use correct packet length in SMB2_TRANSFORM header")
Fix it and also rename smb2_rqst_len to smb_rqst_len
to make it less unobvious that the function is also called from
CIFS/SMB1

Good job by Paulo reviewing and cleaning up Ronnie's original patch.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
Signed-off-by: Steve French <stfrench@microsoft.com>
Ronnie Sahlberg 7 سال پیش
والد
کامیت
81f39f951b
5فایلهای تغییر یافته به همراه13 افزوده شده و 11 حذف شده
  1. 1 1
      fs/cifs/smb2ops.c
  2. 2 2
      fs/cifs/smb2proto.h
  3. 3 2
      fs/cifs/smbdirect.c
  4. 2 2
      fs/cifs/smbdirect.h
  5. 5 4
      fs/cifs/transport.c

+ 1 - 1
fs/cifs/smb2ops.c

@@ -2522,7 +2522,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq,
 	if (!tr_hdr)
 	if (!tr_hdr)
 		goto err_free_iov;
 		goto err_free_iov;
 
 
-	orig_len = smb2_rqst_len(old_rq, false);
+	orig_len = smb_rqst_len(server, old_rq);
 
 
 	/* fill the 2nd iov with a transform header */
 	/* fill the 2nd iov with a transform header */
 	fill_transform_hdr(tr_hdr, orig_len, old_rq);
 	fill_transform_hdr(tr_hdr, orig_len, old_rq);

+ 2 - 2
fs/cifs/smb2proto.h

@@ -113,8 +113,8 @@ extern int smb2_unlock_range(struct cifsFileInfo *cfile,
 extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
 extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
 extern void smb2_reconnect_server(struct work_struct *work);
 extern void smb2_reconnect_server(struct work_struct *work);
 extern int smb3_crypto_aead_allocate(struct TCP_Server_Info *server);
 extern int smb3_crypto_aead_allocate(struct TCP_Server_Info *server);
-extern unsigned long
-smb2_rqst_len(struct smb_rqst *rqst, bool skip_rfc1002_marker);
+extern unsigned long smb_rqst_len(struct TCP_Server_Info *server,
+				  struct smb_rqst *rqst);
 
 
 /*
 /*
  * SMB2 Worker functions - most of protocol specific implementation details
  * SMB2 Worker functions - most of protocol specific implementation details

+ 3 - 2
fs/cifs/smbdirect.c

@@ -2083,8 +2083,9 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
  * rqst: the data to write
  * rqst: the data to write
  * return value: 0 if successfully write, otherwise error code
  * return value: 0 if successfully write, otherwise error code
  */
  */
-int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
+int smbd_send(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 {
 {
+	struct smbd_connection *info = server->smbd_conn;
 	struct kvec vec;
 	struct kvec vec;
 	int nvecs;
 	int nvecs;
 	int size;
 	int size;
@@ -2118,7 +2119,7 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
 	 * rq_tailsz to PAGE_SIZE when the buffer has multiple pages and
 	 * rq_tailsz to PAGE_SIZE when the buffer has multiple pages and
 	 * ends at page boundary
 	 * ends at page boundary
 	 */
 	 */
-	buflen = smb2_rqst_len(rqst, true);
+	buflen = smb_rqst_len(server, rqst);
 
 
 	if (buflen + sizeof(struct smbd_data_transfer) >
 	if (buflen + sizeof(struct smbd_data_transfer) >
 		info->max_fragmented_send_size) {
 		info->max_fragmented_send_size) {

+ 2 - 2
fs/cifs/smbdirect.h

@@ -292,7 +292,7 @@ void smbd_destroy(struct smbd_connection *info);
 
 
 /* Interface for carrying upper layer I/O through send/recv */
 /* Interface for carrying upper layer I/O through send/recv */
 int smbd_recv(struct smbd_connection *info, struct msghdr *msg);
 int smbd_recv(struct smbd_connection *info, struct msghdr *msg);
-int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst);
+int smbd_send(struct TCP_Server_Info *server, struct smb_rqst *rqst);
 
 
 enum mr_state {
 enum mr_state {
 	MR_READY,
 	MR_READY,
@@ -332,7 +332,7 @@ static inline void *smbd_get_connection(
 static inline int smbd_reconnect(struct TCP_Server_Info *server) {return -1; }
 static inline int smbd_reconnect(struct TCP_Server_Info *server) {return -1; }
 static inline void smbd_destroy(struct smbd_connection *info) {}
 static inline void smbd_destroy(struct smbd_connection *info) {}
 static inline int smbd_recv(struct smbd_connection *info, struct msghdr *msg) {return -1; }
 static inline int smbd_recv(struct smbd_connection *info, struct msghdr *msg) {return -1; }
-static inline int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst) {return -1; }
+static inline int smbd_send(struct TCP_Server_Info *server, struct smb_rqst *rqst) {return -1; }
 #endif
 #endif
 
 
 #endif
 #endif

+ 5 - 4
fs/cifs/transport.c

@@ -218,14 +218,15 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
 }
 }
 
 
 unsigned long
 unsigned long
-smb2_rqst_len(struct smb_rqst *rqst, bool skip_rfc1002_marker)
+smb_rqst_len(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 {
 {
 	unsigned int i;
 	unsigned int i;
 	struct kvec *iov;
 	struct kvec *iov;
 	int nvec;
 	int nvec;
 	unsigned long buflen = 0;
 	unsigned long buflen = 0;
 
 
-	if (skip_rfc1002_marker && rqst->rq_iov[0].iov_len == 4) {
+	if (server->vals->header_preamble_size == 0 &&
+	    rqst->rq_nvec >= 2 && rqst->rq_iov[0].iov_len == 4) {
 		iov = &rqst->rq_iov[1];
 		iov = &rqst->rq_iov[1];
 		nvec = rqst->rq_nvec - 1;
 		nvec = rqst->rq_nvec - 1;
 	} else {
 	} else {
@@ -276,7 +277,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
 	__be32 rfc1002_marker;
 	__be32 rfc1002_marker;
 
 
 	if (cifs_rdma_enabled(server) && server->smbd_conn) {
 	if (cifs_rdma_enabled(server) && server->smbd_conn) {
-		rc = smbd_send(server->smbd_conn, rqst);
+		rc = smbd_send(server, rqst);
 		goto smbd_done;
 		goto smbd_done;
 	}
 	}
 	if (ssocket == NULL)
 	if (ssocket == NULL)
@@ -287,7 +288,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
 				(char *)&val, sizeof(val));
 				(char *)&val, sizeof(val));
 
 
 	for (j = 0; j < num_rqst; j++)
 	for (j = 0; j < num_rqst; j++)
-		send_length += smb2_rqst_len(&rqst[j], true);
+		send_length += smb_rqst_len(server, &rqst[j]);
 	rfc1002_marker = cpu_to_be32(send_length);
 	rfc1002_marker = cpu_to_be32(send_length);
 
 
 	/* Generate a rfc1002 marker for SMB2+ */
 	/* Generate a rfc1002 marker for SMB2+ */