From nobody Tue Dec 2 00:25:46 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4713729A9E9 for ; Mon, 1 Dec 2025 22:57:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629880; cv=none; b=KE6jUeFolFl8jISnxMLB8ekg7TES2t3Dw9T0QGR2bisczVK3Ts+LuUsmbYKzk2ibUs+vzRe1RY2gYbOiflRuCuMLG5OkxmCZ2f2yGx8LLZBl8w1TT4kGBsekNkGJ4uF1fTuS64figgdB6f8z12M+wQZOoPHmDPzYJ+vneeRV6mA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629880; c=relaxed/simple; bh=gxIn+nuTbIc6+LJf/YgGHDidY2D6bLg5msCXwY/+eQY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=V/kXp4nz3vmtnjLurVeY0SsOFdMB8hjNSDkLo7Su5yVSDXBc83+MeMJbDowaEsapepbu8ghxBkn4J93ES1cJzV3GlC4PdHU2Bffdy34ZjOqnXO7qyzKHio00mesnKQHjQzUBlpzvfRyti8Ad6MweW2IH/dVNZBZJLv4OZYmFuXg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=XH+Y1DXu; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="XH+Y1DXu" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764629871; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eFai0thyF4uwfdjCkhvCcHVS3Y25wLrVUd6WgDN3AAw=; b=XH+Y1DXu6DVjEH5xN01+AXKPFeM3e/f3BpjrKtq2f9f2IW4B4YufIZIowo/8JivAgHXIzq R9mLDtPP2GQNXUEB8+P3P6aETAlAyVjv6bHyeSjTgbMJ9X1xrdF+njo+kGeqC7ZR7l2LSC frthh3NefmZKLn5eYBnjCWn6SJq+RCs= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-214-olT1TKfSMy66_nU85fwyeQ-1; Mon, 01 Dec 2025 17:57:45 -0500 X-MC-Unique: olT1TKfSMy66_nU85fwyeQ-1 X-Mimecast-MFC-AGG-ID: olT1TKfSMy66_nU85fwyeQ_1764629864 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A93181800343; Mon, 1 Dec 2025 22:57:43 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.14]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4602C19560A7; Mon, 1 Dec 2025 22:57:39 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Stefan Metzmacher , Tom Talpey , linux-cifs@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 1/9] cifs: Remove the RFC1002 header from smb_hdr Date: Mon, 1 Dec 2025 22:57:22 +0000 Message-ID: <20251201225732.1520128-2-dhowells@redhat.com> In-Reply-To: <20251201225732.1520128-1-dhowells@redhat.com> References: <20251201225732.1520128-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Remove the RFC1002 header from struct smb_hdr as used for SMB-1.0. This simplifies the SMB-1.0 code by simplifying a lot of places that have to add or subtract 4 to work around the fact that the RFC1002 header isn't really part of the message and the base for various offsets within the message is from the base of the smb_hdr, not the RFC1002 header. Further, clean up a bunch of places that require an extra kvec struct specifically pointing to the RFC1002 header, such that kvec[0].iov_base must be exactly 4 bytes before kvec[1].iov_base. This allows the header preamble size stuff to be removed too. The size of the request and response message are then handed around either directly or by summing the size of all the iov_len members in the kvec array for which we have a count. Also, this simplifies and cleans up the common transmission and receive paths for SMB1 and SMB2/3 as there no longer needs to be special handling casing for SMB1 messages as the RFC1002 header is now generated on the fly for SMB1 as it is for SMB2/3. Signed-off-by: David Howells Reviewed-by: Tom Talpey cc: Steve French cc: Paulo Alcantara cc: Shyam Prasad N cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org --- fs/smb/client/cifs_debug.c | 10 +- fs/smb/client/cifs_debug.h | 6 +- fs/smb/client/cifsencrypt.c | 36 +- fs/smb/client/cifsglob.h | 23 +- fs/smb/client/cifspdu.h | 2 +- fs/smb/client/cifsproto.h | 51 ++- fs/smb/client/cifssmb.c | 735 +++++++++++++++++++--------------- fs/smb/client/cifstransport.c | 208 ++++------ fs/smb/client/connect.c | 36 +- fs/smb/client/misc.c | 34 +- fs/smb/client/sess.c | 8 +- fs/smb/client/smb1ops.c | 21 +- fs/smb/client/smb2misc.c | 3 +- fs/smb/client/smb2ops.c | 11 +- fs/smb/client/smb2proto.h | 2 +- fs/smb/client/transport.c | 80 ++-- fs/smb/common/smb2pdu.h | 3 - fs/smb/common/smbglob.h | 1 - 18 files changed, 645 insertions(+), 625 deletions(-) diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c index 7fdcaf9feb16..881d3a88d683 100644 --- a/fs/smb/client/cifs_debug.c +++ b/fs/smb/client/cifs_debug.c @@ -37,7 +37,7 @@ cifs_dump_mem(char *label, void *data, int length) data, length, true); } =20 -void cifs_dump_detail(void *buf, struct TCP_Server_Info *server) +void cifs_dump_detail(void *buf, size_t buf_len, struct TCP_Server_Info *s= erver) { #ifdef CONFIG_CIFS_DEBUG2 struct smb_hdr *smb =3D buf; @@ -45,7 +45,7 @@ void cifs_dump_detail(void *buf, struct TCP_Server_Info *= server) cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d = Wct: %d\n", smb->Command, smb->Status.CifsError, smb->Flags, smb->Flags2, smb->Mid, smb->Pid, smb->WordCount); - if (!server->ops->check_message(buf, server->total_read, server)) { + if (!server->ops->check_message(buf, buf_len, server->total_read, server)= ) { cifs_dbg(VFS, "smb buf %p len %u\n", smb, server->ops->calc_smb_size(smb)); } @@ -79,9 +79,9 @@ void cifs_dump_mids(struct TCP_Server_Info *server) cifs_dbg(VFS, "IsMult: %d IsEnd: %d\n", mid_entry->multiRsp, mid_entry->multiEnd); if (mid_entry->resp_buf) { - cifs_dump_detail(mid_entry->resp_buf, server); - cifs_dump_mem("existing buf: ", - mid_entry->resp_buf, 62); + cifs_dump_detail(mid_entry->resp_buf, + mid_entry->response_pdu_len, server); + cifs_dump_mem("existing buf: ", mid_entry->resp_buf, 62); } } spin_unlock(&server->mid_queue_lock); diff --git a/fs/smb/client/cifs_debug.h b/fs/smb/client/cifs_debug.h index ce5cfd236fdb..e0035ff42dba 100644 --- a/fs/smb/client/cifs_debug.h +++ b/fs/smb/client/cifs_debug.h @@ -15,10 +15,10 @@ #define pr_fmt(fmt) "CIFS: " fmt =20 void cifs_dump_mem(char *label, void *data, int length); -void cifs_dump_detail(void *buf, struct TCP_Server_Info *ptcp_info); -void cifs_dump_mids(struct TCP_Server_Info *); +void cifs_dump_detail(void *buf, size_t buf_len, struct TCP_Server_Info *s= erver); +void cifs_dump_mids(struct TCP_Server_Info *server); extern bool traceSMB; /* flag which enables the function below */ -void dump_smb(void *, int); +void dump_smb(void *buf, int smb_buf_length); #define CIFS_INFO 0x01 #define CIFS_RC 0x02 #define CIFS_TIMER 0x04 diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c index 801824825ecf..1e0ac87c6686 100644 --- a/fs/smb/client/cifsencrypt.c +++ b/fs/smb/client/cifsencrypt.c @@ -91,18 +91,7 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct = TCP_Server_Info *server, struct kvec *iov =3D rqst->rq_iov; int n_vec =3D rqst->rq_nvec; =20 - /* iov[0] is actual data and not the rfc1002 length for SMB2+ */ - if (!is_smb1(server)) { - if (iov[0].iov_len <=3D 4) - return -EIO; - i =3D 0; - } else { - if (n_vec < 2 || iov[0].iov_len !=3D 4) - return -EIO; - i =3D 1; /* skip rfc1002 length */ - } - - for (; i < n_vec; i++) { + for (i =3D 0; i < n_vec; i++) { if (iov[i].iov_len =3D=3D 0) continue; if (iov[i].iov_base =3D=3D NULL) { @@ -165,10 +154,6 @@ int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_S= erver_Info *server, char smb_signature[20]; struct smb_hdr *cifs_pdu =3D (struct smb_hdr *)rqst->rq_iov[0].iov_base; =20 - if (rqst->rq_iov[0].iov_len !=3D 4 || - rqst->rq_iov[0].iov_base + 4 !=3D rqst->rq_iov[1].iov_base) - return -EIO; - if ((cifs_pdu =3D=3D NULL) || (server =3D=3D NULL)) return -EINVAL; =20 @@ -211,17 +196,16 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struc= t TCP_Server_Info *server, } =20 /* must be called with server->srv_mutex held */ -int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, +int cifs_sign_smb(struct smb_hdr *cifs_pdu, unsigned int pdu_len, + struct TCP_Server_Info *server, __u32 *pexpected_response_sequence_number) { - struct kvec iov[2]; + struct kvec iov[1] =3D { + [0].iov_base =3D (char *)cifs_pdu, + [0].iov_len =3D pdu_len, + }; =20 - iov[0].iov_base =3D cifs_pdu; - iov[0].iov_len =3D 4; - iov[1].iov_base =3D (char *)cifs_pdu + 4; - iov[1].iov_len =3D be32_to_cpu(cifs_pdu->smb_buf_length); - - return cifs_sign_smbv(iov, 2, server, + return cifs_sign_smbv(iov, ARRAY_SIZE(iov), server, pexpected_response_sequence_number); } =20 @@ -234,10 +218,6 @@ int cifs_verify_signature(struct smb_rqst *rqst, char what_we_think_sig_should_be[20]; struct smb_hdr *cifs_pdu =3D (struct smb_hdr *)rqst->rq_iov[0].iov_base; =20 - if (rqst->rq_iov[0].iov_len !=3D 4 || - rqst->rq_iov[0].iov_base + 4 !=3D rqst->rq_iov[1].iov_base) - return -EIO; - if (cifs_pdu =3D=3D NULL || server =3D=3D NULL) return -EINVAL; =20 diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 0c76e0a31386..1255e43a4d82 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -346,13 +346,14 @@ struct smb_version_operations { /* map smb to linux error */ int (*map_error)(char *, bool); /* find mid corresponding to the response message */ - struct mid_q_entry * (*find_mid)(struct TCP_Server_Info *, char *); - void (*dump_detail)(void *buf, struct TCP_Server_Info *ptcp_info); + struct mid_q_entry *(*find_mid)(struct TCP_Server_Info *server, char *buf= ); + void (*dump_detail)(void *buf, size_t buf_len, struct TCP_Server_Info *pt= cp_info); void (*clear_stats)(struct cifs_tcon *); void (*print_stats)(struct seq_file *m, struct cifs_tcon *); void (*dump_share_caps)(struct seq_file *, struct cifs_tcon *); /* verify the message */ - int (*check_message)(char *, unsigned int, struct TCP_Server_Info *); + int (*check_message)(char *buf, unsigned int pdu_len, unsigned int len, + struct TCP_Server_Info *server); bool (*is_oplock_break)(char *, struct TCP_Server_Info *); int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info = *); void (*downgrade_oplock)(struct TCP_Server_Info *server, @@ -636,8 +637,7 @@ struct smb_version_operations { =20 #define HEADER_SIZE(server) (server->vals->header_size) #define MAX_HEADER_SIZE(server) (server->vals->max_header_size) -#define HEADER_PREAMBLE_SIZE(server) (server->vals->header_preamble_size) -#define MID_HEADER_SIZE(server) (HEADER_SIZE(server) - 1 - HEADER_PREAMBLE= _SIZE(server)) +#define MID_HEADER_SIZE(server) (HEADER_SIZE(server) - 1) =20 /** * CIFS superblock mount flags (mnt_cifs_flags) to consider when @@ -832,9 +832,9 @@ struct TCP_Server_Info { char dns_dom[CIFS_MAX_DOMAINNAME_LEN + 1]; }; =20 -static inline bool is_smb1(struct TCP_Server_Info *server) +static inline bool is_smb1(const struct TCP_Server_Info *server) { - return HEADER_PREAMBLE_SIZE(server) !=3D 0; + return server->vals->protocol_id =3D=3D SMB10_PROT_ID; } =20 static inline void cifs_server_lock(struct TCP_Server_Info *server) @@ -973,16 +973,16 @@ compare_mid(__u16 mid, const struct smb_hdr *smb) * of kvecs to handle the receive, though that should only need to be done * once. */ -#define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4) -#define CIFS_MAX_RSIZE ((1<<24) - sizeof(READ_RSP) + 4) +#define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ)) +#define CIFS_MAX_RSIZE ((1<<24) - sizeof(READ_RSP)) =20 /* * When the server doesn't allow large posix writes, only allow a rsize/ws= ize * of 2^17-1 minus the size of the call header. That allows for a read or * write up to the maximum size described by RFC1002. */ -#define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4) -#define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP) + 4) +#define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ)) +#define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP)) =20 /* * Windows only supports a max of 60kb reads and 65535 byte writes. Defaul= t to @@ -1701,6 +1701,7 @@ struct mid_q_entry { struct task_struct *creator; void *resp_buf; /* pointer to received SMB header */ unsigned int resp_buf_size; + u32 response_pdu_len; int mid_state; /* wish this were enum but can not pass to wait_event */ int mid_rc; /* rc for MID_RC */ __le16 command; /* smb command code */ diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h index 49f35cb3cf2e..37b23664ddf3 100644 --- a/fs/smb/client/cifspdu.h +++ b/fs/smb/client/cifspdu.h @@ -90,7 +90,7 @@ =20 /* future chained NTCreateXReadX bigger, but for time being NTCreateX bigg= est */ /* among the requests (NTCreateX response is bigger with wct of 34) */ -#define MAX_CIFS_HDR_SIZE 0x58 /* 4 len + 32 hdr + (2*24 wct) + 2 bct + 2 = pad */ +#define MAX_CIFS_HDR_SIZE 0x54 /* 32 hdr + (2*24 wct) + 2 bct + 2 pad */ #define CIFS_SMALL_PATH 120 /* allows for (448-88)/3 */ =20 /* internal cifs vfs structures */ diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index 3528c365a452..7fb40684a584 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -111,18 +111,16 @@ extern int compound_send_recv(const unsigned int xid,= struct cifs_ses *ses, const int flags, const int num_rqst, struct smb_rqst *rqst, int *resp_buf_type, struct kvec *resp_iov); -extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *, - struct smb_hdr * /* input */ , - struct smb_hdr * /* out */ , - int * /* bytes returned */ , const int); -extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, - char *in_buf, int flags); +int SendReceive(const unsigned int xid, struct cifs_ses *ses, + struct smb_hdr *in_buf, unsigned int in_len, + struct smb_hdr *out_buf, int *pbytes_returned, const int flags); +int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, + char *in_buf, unsigned int in_len, int flags); int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *= server); -extern struct mid_q_entry *cifs_setup_request(struct cifs_ses *, - struct TCP_Server_Info *, - struct smb_rqst *); -extern struct mid_q_entry *cifs_setup_async_request(struct TCP_Server_Info= *, - struct smb_rqst *); +struct mid_q_entry *cifs_setup_request(struct cifs_ses *ses, struct TCP_Se= rver_Info *ignored, + struct smb_rqst *rqst); +struct mid_q_entry *cifs_setup_async_request(struct TCP_Server_Info *serve= r, + struct smb_rqst *rqst); int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, struct smb_rqst *rqst); extern int cifs_check_receive(struct mid_q_entry *mid, @@ -146,11 +144,9 @@ extern int SendReceive2(const unsigned int /* xid */ ,= struct cifs_ses *, struct kvec *, int /* nvec to send */, int * /* type of buf returned */, const int flags, struct kvec * /* resp vec */); -extern int SendReceiveBlockingLock(const unsigned int xid, - struct cifs_tcon *ptcon, - struct smb_hdr *in_buf, - struct smb_hdr *out_buf, - int *bytes_returned); +int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, + struct smb_hdr *in_buf, unsigned int in_len, + struct smb_hdr *out_buf, int *pbytes_returned); =20 void smb2_query_server_interfaces(struct work_struct *work); void @@ -161,7 +157,8 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server= _Info *server, bool mark_smb_session); extern int cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session); -extern int checkSMB(char *buf, unsigned int len, struct TCP_Server_Info *s= rvr); +int checkSMB(char *buf, unsigned int pdu_len, unsigned int len, + struct TCP_Server_Info *srvr); extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *); extern bool backup_cred(struct cifs_sb_info *); extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 = eof, @@ -188,9 +185,9 @@ extern int cifs_convert_address(struct sockaddr *dst, c= onst char *src, int len); extern void cifs_set_port(struct sockaddr *addr, const unsigned short int = port); extern int map_smb_to_linux_error(char *buf, bool logErr); extern int map_and_check_smb_error(struct mid_q_entry *mid, bool logErr); -extern void header_assemble(struct smb_hdr *, char /* command */ , - const struct cifs_tcon *, int /* length of - fixed section (word count) in two byte units */); +unsigned int header_assemble(struct smb_hdr *buffer, char smb_command, + const struct cifs_tcon *treeCon, int word_count + /* length of fixed section word count in two byte units */); extern int small_smb_init_no_tc(const int smb_cmd, const int wct, struct cifs_ses *ses, void **request_buf); @@ -565,12 +562,14 @@ extern void tconInfoFree(struct cifs_tcon *tcon, enum= smb3_tcon_ref_trace trace) =20 extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *s= erver, __u32 *pexpected_response_sequence_number); -extern int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_I= nfo *, - __u32 *); -extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32= *); -extern int cifs_verify_signature(struct smb_rqst *rqst, - struct TCP_Server_Info *server, - __u32 expected_sequence_number); +int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *se= rver, + __u32 *pexpected_response_sequence); +int cifs_sign_smb(struct smb_hdr *cifs_pdu, unsigned int pdu_len, + struct TCP_Server_Info *server, + __u32 *pexpected_response_sequence_number); +int cifs_verify_signature(struct smb_rqst *rqst, + struct TCP_Server_Info *server, + __u32 expected_sequence_number); extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); extern void cifs_crypto_secmech_release(struct TCP_Server_Info *server); extern int calc_seckey(struct cifs_ses *); diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c index 428e582e0414..645831708e1b 100644 --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -226,6 +226,7 @@ static int small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon, void **request_buf) { + unsigned int in_len; int rc; =20 rc =3D cifs_reconnect_tcon(tcon, smb_command); @@ -238,13 +239,13 @@ small_smb_init(int smb_command, int wct, struct cifs_= tcon *tcon, return -ENOMEM; } =20 - header_assemble((struct smb_hdr *) *request_buf, smb_command, - tcon, wct); + in_len =3D header_assemble((struct smb_hdr *) *request_buf, smb_command, + tcon, wct); =20 if (tcon !=3D NULL) cifs_stats_inc(&tcon->num_smbs_sent); =20 - return 0; + return in_len; } =20 int @@ -255,7 +256,7 @@ small_smb_init_no_tc(const int smb_command, const int w= ct, struct smb_hdr *buffer; =20 rc =3D small_smb_init(smb_command, wct, NULL, request_buf); - if (rc) + if (rc < 0) return rc; =20 buffer =3D (struct smb_hdr *)*request_buf; @@ -278,6 +279,8 @@ static int __smb_init(int smb_command, int wct, struct cifs_tcon *tcon, void **request_buf, void **response_buf) { + unsigned int in_len; + *request_buf =3D cifs_buf_get(); if (*request_buf =3D=3D NULL) { /* BB should we add a retry in here if not a writepage? */ @@ -290,13 +293,13 @@ __smb_init(int smb_command, int wct, struct cifs_tcon= *tcon, if (response_buf) *response_buf =3D *request_buf; =20 - header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, - wct); + in_len =3D header_assemble((struct smb_hdr *)*request_buf, smb_command, t= con, + wct); =20 if (tcon !=3D NULL) cifs_stats_inc(&tcon->num_smbs_sent); =20 - return 0; + return in_len; } =20 /* If the return code is zero, this function must fill in request_buf poin= ter */ @@ -421,6 +424,7 @@ CIFSSMBNegotiate(const unsigned int xid, { SMB_NEGOTIATE_REQ *pSMB; SMB_NEGOTIATE_RSP *pSMBr; + unsigned int in_len; int rc =3D 0; int bytes_returned; int i; @@ -433,8 +437,9 @@ CIFSSMBNegotiate(const unsigned int xid, =20 rc =3D smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ , (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->hdr.Mid =3D get_next_mid(server); pSMB->hdr.Flags2 |=3D SMBFLG2_ERR_STATUS; @@ -458,10 +463,10 @@ CIFSSMBNegotiate(const unsigned int xid, memcpy(&pSMB->DialectsArray[count], protocols[i].name, len); count +=3D len; } - inc_rfc1001_len(pSMB, count); + in_len +=3D count; pSMB->ByteCount =3D cpu_to_le16(count); =20 - rc =3D SendReceive(xid, ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc !=3D 0) goto neg_err_exit; @@ -530,6 +535,7 @@ int CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon) { struct smb_hdr *smb_buffer; + unsigned int in_len; int rc =3D 0; =20 cifs_dbg(FYI, "In tree disconnect\n"); @@ -553,10 +559,11 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon = *tcon) =20 rc =3D small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, (void **)&smb_buffer); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 - rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0); + rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, in_len, 0); cifs_small_buf_release(smb_buffer); if (rc) cifs_dbg(FYI, "Tree disconnect failed %d\n", rc); @@ -591,15 +598,19 @@ CIFSSMBEcho(struct TCP_Server_Info *server) { ECHO_REQ *smb; int rc =3D 0; - struct kvec iov[2]; - struct smb_rqst rqst =3D { .rq_iov =3D iov, - .rq_nvec =3D 2 }; + struct kvec iov[1]; + struct smb_rqst rqst =3D { + .rq_iov =3D iov, + .rq_nvec =3D ARRAY_SIZE(iov), + }; + unsigned int in_len; =20 cifs_dbg(FYI, "In echo request\n"); =20 rc =3D small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (server->capabilities & CAP_UNICODE) smb->hdr.Flags2 |=3D SMBFLG2_UNICODE; @@ -610,12 +621,10 @@ CIFSSMBEcho(struct TCP_Server_Info *server) put_unaligned_le16(1, &smb->EchoCount); put_bcc(1, &smb->hdr); smb->Data[0] =3D 'a'; - inc_rfc1001_len(smb, 3); + in_len +=3D 3; =20 - iov[0].iov_len =3D 4; + iov[0].iov_len =3D in_len; iov[0].iov_base =3D smb; - iov[1].iov_len =3D get_rfc1002_len(smb); - iov[1].iov_base =3D (char *)smb + 4; =20 rc =3D cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL, server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL); @@ -631,6 +640,7 @@ int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses) { LOGOFF_ANDX_REQ *pSMB; + unsigned int in_len; int rc =3D 0; =20 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n"); @@ -653,10 +663,11 @@ CIFSSMBLogoff(const unsigned int xid, struct cifs_ses= *ses) spin_unlock(&ses->chan_lock); =20 rc =3D small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB); - if (rc) { + if (rc < 0) { mutex_unlock(&ses->session_mutex); return rc; } + in_len =3D rc; =20 pSMB->hdr.Mid =3D get_next_mid(ses->server); =20 @@ -666,7 +677,7 @@ CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *= ses) pSMB->hdr.Uid =3D ses->Suid; =20 pSMB->AndXCommand =3D 0xFF; - rc =3D SendReceiveNoRsp(xid, ses, (char *) pSMB, 0); + rc =3D SendReceiveNoRsp(xid, ses, (char *) pSMB, in_len, 0); cifs_small_buf_release(pSMB); session_already_dead: mutex_unlock(&ses->session_mutex); @@ -687,6 +698,7 @@ CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tc= on *tcon, TRANSACTION2_SPI_REQ *pSMB =3D NULL; TRANSACTION2_SPI_RSP *pSMBr =3D NULL; struct unlink_psx_rq *pRqD; + unsigned int in_len; int name_len; int rc =3D 0; int bytes_returned =3D 0; @@ -696,8 +708,9 @@ CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tc= on *tcon, PsxDelete: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -718,14 +731,11 @@ CIFSPOSIXDelFile(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; param_offset =3D offsetof(struct smb_com_transaction2_spi_req, - InformationLevel) - 4; + InformationLevel); offset =3D param_offset + params; =20 - /* Setup pointer to Request Data (inode type). - * Note that SMB offsets are from the beginning of SMB which is 4 bytes - * in, after RFC1001 field - */ - pRqD =3D (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4); + /* Setup pointer to Request Data (inode type). */ + pRqD =3D (struct unlink_psx_rq *)((char *)(pSMB) + offset); pRqD->type =3D cpu_to_le16(type); pSMB->ParameterOffset =3D cpu_to_le16(param_offset); pSMB->DataOffset =3D cpu_to_le16(offset); @@ -740,9 +750,9 @@ CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tc= on *tcon, pSMB->TotalParameterCount =3D pSMB->ParameterCount; pSMB->InformationLevel =3D cpu_to_le16(SMB_POSIX_UNLINK); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) cifs_dbg(FYI, "Posix delete returned %d\n", rc); @@ -762,6 +772,7 @@ CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon= *tcon, const char *name, { DELETE_FILE_REQ *pSMB =3D NULL; DELETE_FILE_RSP *pSMBr =3D NULL; + unsigned int in_len; int rc =3D 0; int bytes_returned; int name_len; @@ -770,8 +781,9 @@ CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon= *tcon, const char *name, DelFileRetry: rc =3D smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D cifsConvertToUTF16((__le16 *) pSMB->fileName, name, @@ -785,9 +797,9 @@ CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon= *tcon, const char *name, pSMB->SearchAttributes =3D cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM); pSMB->BufferFormat =3D 0x04; - inc_rfc1001_len(pSMB, name_len + 1); + in_len +=3D name_len + 1; pSMB->ByteCount =3D cpu_to_le16(name_len + 1); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes); if (rc) @@ -806,6 +818,7 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *= tcon, const char *name, { DELETE_DIRECTORY_REQ *pSMB =3D NULL; DELETE_DIRECTORY_RSP *pSMBr =3D NULL; + unsigned int in_len; int rc =3D 0; int bytes_returned; int name_len; @@ -815,8 +828,9 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *= tcon, const char *name, RmDirRetry: rc =3D smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D cifsConvertToUTF16((__le16 *) pSMB->DirName, name, @@ -829,9 +843,9 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *= tcon, const char *name, } =20 pSMB->BufferFormat =3D 0x04; - inc_rfc1001_len(pSMB, name_len + 1); + in_len +=3D name_len + 1; pSMB->ByteCount =3D cpu_to_le16(name_len + 1); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs); if (rc) @@ -851,6 +865,7 @@ CIFSSMBMkDir(const unsigned int xid, struct inode *inod= e, umode_t mode, int rc =3D 0; CREATE_DIRECTORY_REQ *pSMB =3D NULL; CREATE_DIRECTORY_RSP *pSMBr =3D NULL; + unsigned int in_len; int bytes_returned; int name_len; int remap =3D cifs_remap(cifs_sb); @@ -859,8 +874,9 @@ CIFSSMBMkDir(const unsigned int xid, struct inode *inod= e, umode_t mode, MkDirRetry: rc =3D smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D cifsConvertToUTF16((__le16 *) pSMB->DirName, name, @@ -873,9 +889,9 @@ CIFSSMBMkDir(const unsigned int xid, struct inode *inod= e, umode_t mode, } =20 pSMB->BufferFormat =3D 0x04; - inc_rfc1001_len(pSMB, name_len + 1); + in_len +=3D name_len + 1; pSMB->ByteCount =3D cpu_to_le16(name_len + 1); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs); if (rc) @@ -896,6 +912,7 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tco= n *tcon, { TRANSACTION2_SPI_REQ *pSMB =3D NULL; TRANSACTION2_SPI_RSP *pSMBr =3D NULL; + unsigned int in_len; int name_len; int rc =3D 0; int bytes_returned =3D 0; @@ -907,8 +924,9 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tco= n *tcon, PsxCreat: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -930,10 +948,9 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tc= on *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; param_offset =3D offsetof(struct smb_com_transaction2_spi_req, - InformationLevel) - 4; + InformationLevel); offset =3D param_offset + params; - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after R= FC1001 field */ - pdata =3D (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4); + pdata =3D (OPEN_PSX_REQ *)((char *)(pSMB) + offset); pdata->Level =3D cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); pdata->Permissions =3D cpu_to_le64(mode); pdata->PosixOpenFlags =3D cpu_to_le32(posix_flags); @@ -951,9 +968,9 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tco= n *tcon, pSMB->TotalParameterCount =3D pSMB->ParameterCount; pSMB->InformationLevel =3D cpu_to_le16(SMB_POSIX_OPEN); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Posix create returned %d\n", rc); @@ -969,8 +986,8 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tco= n *tcon, } =20 /* copy return information to pRetData */ - psx_rsp =3D (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol - + le16_to_cpu(pSMBr->t2.DataOffset)); + psx_rsp =3D (OPEN_PSX_RSP *) + ((char *)pSMBr + le16_to_cpu(pSMBr->t2.DataOffset)); =20 *pOplock =3D le16_to_cpu(psx_rsp->OplockFlags); if (netfid) @@ -990,9 +1007,9 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tc= on *tcon, pRetData->Type =3D cpu_to_le32(-1); goto psx_create_err; } - memcpy((char *) pRetData, - (char *)psx_rsp + sizeof(OPEN_PSX_RSP), - sizeof(FILE_UNIX_BASIC_INFO)); + memcpy(pRetData, + (char *)psx_rsp + sizeof(OPEN_PSX_RSP), + sizeof(*pRetData)); } =20 psx_create_err: @@ -1079,6 +1096,7 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tco= n *tcon, int rc; OPENX_REQ *pSMB =3D NULL; OPENX_RSP *pSMBr =3D NULL; + unsigned int in_len; int bytes_returned; int name_len; __u16 count; @@ -1086,8 +1104,9 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tco= n *tcon, OldOpenRetry: rc =3D smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->AndXCommand =3D 0xFF; /* none */ =20 @@ -1130,10 +1149,10 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_t= con *tcon, pSMB->Sattr =3D cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY); pSMB->OpenFunction =3D cpu_to_le16(convert_disposition(openDisposition)); count +=3D name_len; - inc_rfc1001_len(pSMB, count); + in_len +=3D count; =20 pSMB->ByteCount =3D cpu_to_le16(count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *)pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_opens); if (rc) { @@ -1191,12 +1210,14 @@ CIFS_open(const unsigned int xid, struct cifs_open_= parms *oparms, int *oplock, int desired_access =3D oparms->desired_access; int disposition =3D oparms->disposition; const char *path =3D oparms->path; + unsigned int in_len; =20 openRetry: rc =3D smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req, (void **)&rsp); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 /* no commands go after this */ req->AndXCommand =3D 0xFF; @@ -1254,10 +1275,10 @@ CIFS_open(const unsigned int xid, struct cifs_open_= parms *oparms, int *oplock, req->SecurityFlags =3D SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY; =20 count +=3D name_len; - inc_rfc1001_len(req, count); + in_len +=3D count; =20 req->ByteCount =3D cpu_to_le16(count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *)req, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *)req, in_len, (struct smb_hdr *)rsp, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_opens); if (rc) { @@ -1303,7 +1324,7 @@ cifs_readv_callback(struct mid_q_entry *mid) struct cifs_tcon *tcon =3D tlink_tcon(rdata->req->cfile->tlink); struct TCP_Server_Info *server =3D tcon->ses->server; struct smb_rqst rqst =3D { .rq_iov =3D rdata->iov, - .rq_nvec =3D 2, + .rq_nvec =3D 1, .rq_iter =3D rdata->subreq.io_iter }; struct cifs_credits credits =3D { .value =3D 1, @@ -1415,7 +1436,8 @@ cifs_async_readv(struct cifs_io_subrequest *rdata) int wct; struct cifs_tcon *tcon =3D tlink_tcon(rdata->req->cfile->tlink); struct smb_rqst rqst =3D { .rq_iov =3D rdata->iov, - .rq_nvec =3D 2 }; + .rq_nvec =3D 1 }; + unsigned int in_len; =20 cifs_dbg(FYI, "%s: offset=3D%llu bytes=3D%zu\n", __func__, rdata->subreq.start, rdata->subreq.len); @@ -1431,8 +1453,9 @@ cifs_async_readv(struct cifs_io_subrequest *rdata) } =20 rc =3D small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 smb->hdr.Pid =3D cpu_to_le16((__u16)rdata->req->pid); smb->hdr.PidHigh =3D cpu_to_le16((__u16)(rdata->req->pid >> 16)); @@ -1456,9 +1479,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata) =20 /* 4 for RFC1001 length + 1 for BCC */ rdata->iov[0].iov_base =3D smb; - rdata->iov[0].iov_len =3D 4; - rdata->iov[1].iov_base =3D (char *)smb + 4; - rdata->iov[1].iov_len =3D get_rfc1002_len(smb); + rdata->iov[0].iov_len =3D in_len; =20 trace_smb3_read_enter(rdata->rreq->debug_id, rdata->subreq.debug_index, @@ -1492,6 +1513,7 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_pa= rms *io_parms, __u16 netfid =3D io_parms->netfid; __u64 offset =3D io_parms->offset; struct cifs_tcon *tcon =3D io_parms->tcon; + unsigned int in_len; unsigned int count =3D io_parms->length; =20 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid); @@ -1507,8 +1529,9 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_pa= rms *io_parms, =20 *nbytes =3D 0; rc =3D small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->hdr.Pid =3D cpu_to_le16((__u16)pid); pSMB->hdr.PidHigh =3D cpu_to_le16((__u16)(pid >> 16)); @@ -1536,7 +1559,7 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_pa= rms *io_parms, } =20 iov[0].iov_base =3D (char *)pSMB; - iov[0].iov_len =3D be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; + iov[0].iov_len =3D in_len; rc =3D SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type, CIFS_LOG_ERROR, &rsp_iov); cifs_small_buf_release(pSMB); @@ -1600,7 +1623,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_p= arms *io_parms, __u16 netfid =3D io_parms->netfid; __u64 offset =3D io_parms->offset; struct cifs_tcon *tcon =3D io_parms->tcon; - unsigned int count =3D io_parms->length; + unsigned int count =3D io_parms->length, in_len; =20 *nbytes =3D 0; =20 @@ -1620,8 +1643,9 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_p= arms *io_parms, =20 rc =3D smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->hdr.Pid =3D cpu_to_le16((__u16)pid); pSMB->hdr.PidHigh =3D cpu_to_le16((__u16)(pid >> 16)); @@ -1654,7 +1678,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_p= arms *io_parms, if (bytes_sent > count) bytes_sent =3D count; pSMB->DataOffset =3D - cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); + cpu_to_le16(offsetof(struct smb_com_write_req, Data)); if (buf) memcpy(pSMB->Data, buf, bytes_sent); else if (count !=3D 0) { @@ -1669,7 +1693,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_p= arms *io_parms, =20 pSMB->DataLengthLow =3D cpu_to_le16(bytes_sent & 0xFFFF); pSMB->DataLengthHigh =3D cpu_to_le16(bytes_sent >> 16); - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; =20 if (wct =3D=3D 14) pSMB->ByteCount =3D cpu_to_le16(byte_count); @@ -1680,7 +1704,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_p= arms *io_parms, pSMBW->ByteCount =3D cpu_to_le16(byte_count); } =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); if (rc) { @@ -1791,11 +1815,12 @@ void cifs_async_writev(struct cifs_io_subrequest *wdata) { int rc =3D -EACCES; - WRITE_REQ *smb =3D NULL; + WRITE_REQ *req =3D NULL; int wct; struct cifs_tcon *tcon =3D tlink_tcon(wdata->req->cfile->tlink); - struct kvec iov[2]; + struct kvec iov[1]; struct smb_rqst rqst =3D { }; + unsigned int in_len; =20 if (tcon->ses->capabilities & CAP_LARGE_FILES) { wct =3D 14; @@ -1808,51 +1833,49 @@ cifs_async_writev(struct cifs_io_subrequest *wdata) } } =20 - rc =3D small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb); - if (rc) + rc =3D small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&req); + if (rc < 0) goto async_writev_out; + in_len =3D rc; =20 - smb->hdr.Pid =3D cpu_to_le16((__u16)wdata->req->pid); - smb->hdr.PidHigh =3D cpu_to_le16((__u16)(wdata->req->pid >> 16)); + req->hdr.Pid =3D cpu_to_le16((__u16)wdata->req->pid); + req->hdr.PidHigh =3D cpu_to_le16((__u16)(wdata->req->pid >> 16)); =20 - smb->AndXCommand =3D 0xFF; /* none */ - smb->Fid =3D wdata->req->cfile->fid.netfid; - smb->OffsetLow =3D cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF); + req->AndXCommand =3D 0xFF; /* none */ + req->Fid =3D wdata->req->cfile->fid.netfid; + req->OffsetLow =3D cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF); if (wct =3D=3D 14) - smb->OffsetHigh =3D cpu_to_le32(wdata->subreq.start >> 32); - smb->Reserved =3D 0xFFFFFFFF; - smb->WriteMode =3D 0; - smb->Remaining =3D 0; + req->OffsetHigh =3D cpu_to_le32(wdata->subreq.start >> 32); + req->Reserved =3D 0xFFFFFFFF; + req->WriteMode =3D 0; + req->Remaining =3D 0; =20 - smb->DataOffset =3D - cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); + req->DataOffset =3D + cpu_to_le16(offsetof(struct smb_com_write_req, Data)); =20 - /* 4 for RFC1001 length + 1 for BCC */ - iov[0].iov_len =3D 4; - iov[0].iov_base =3D smb; - iov[1].iov_len =3D get_rfc1002_len(smb) + 1; - iov[1].iov_base =3D (char *)smb + 4; + iov[0].iov_base =3D req; + iov[0].iov_len =3D in_len + 1; /* +1 for BCC */ =20 rqst.rq_iov =3D iov; - rqst.rq_nvec =3D 2; + rqst.rq_nvec =3D 1; rqst.rq_iter =3D wdata->subreq.io_iter; =20 cifs_dbg(FYI, "async write at %llu %zu bytes\n", wdata->subreq.start, wdata->subreq.len); =20 - smb->DataLengthLow =3D cpu_to_le16(wdata->subreq.len & 0xFFFF); - smb->DataLengthHigh =3D cpu_to_le16(wdata->subreq.len >> 16); + req->DataLengthLow =3D cpu_to_le16(wdata->subreq.len & 0xFFFF); + req->DataLengthHigh =3D cpu_to_le16(wdata->subreq.len >> 16); =20 if (wct =3D=3D 14) { - inc_rfc1001_len(&smb->hdr, wdata->subreq.len + 1); - put_bcc(wdata->subreq.len + 1, &smb->hdr); + in_len +=3D wdata->subreq.len + 1; + put_bcc(wdata->subreq.len + 1, &req->hdr); } else { /* wct =3D=3D 12 */ - struct smb_com_writex_req *smbw =3D - (struct smb_com_writex_req *)smb; - inc_rfc1001_len(&smbw->hdr, wdata->subreq.len + 5); - put_bcc(wdata->subreq.len + 5, &smbw->hdr); - iov[1].iov_len +=3D 4; /* pad bigger by four bytes */ + struct smb_com_writex_req *reqw =3D + (struct smb_com_writex_req *)req; + in_len +=3D wdata->subreq.len + 5; + put_bcc(wdata->subreq.len + 5, &reqw->hdr); + iov[0].iov_len +=3D 4; /* pad bigger by four bytes */ } =20 rc =3D cifs_call_async(tcon->ses->server, &rqst, NULL, @@ -1862,7 +1885,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata) cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); =20 async_writev_out: - cifs_small_buf_release(smb); + cifs_small_buf_release(req); out: if (rc) { add_credits_and_wake_if(wdata->server, &wdata->credits, 0); @@ -1885,6 +1908,7 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_= parms *io_parms, struct cifs_tcon *tcon =3D io_parms->tcon; unsigned int count =3D io_parms->length; struct kvec rsp_iov; + unsigned int in_len; =20 *nbytes =3D 0; =20 @@ -1900,8 +1924,9 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_= parms *io_parms, } } rc =3D small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->hdr.Pid =3D cpu_to_le16((__u16)pid); pSMB->hdr.PidHigh =3D cpu_to_le16((__u16)(pid >> 16)); @@ -1920,16 +1945,16 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_i= o_parms *io_parms, pSMB->Remaining =3D 0; =20 pSMB->DataOffset =3D - cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); + cpu_to_le16(offsetof(struct smb_com_write_req, Data)); =20 pSMB->DataLengthLow =3D cpu_to_le16(count & 0xFFFF); pSMB->DataLengthHigh =3D cpu_to_le16(count >> 16); /* header + 1 byte pad */ - smb_hdr_len =3D be32_to_cpu(pSMB->hdr.smb_buf_length) + 1; + smb_hdr_len =3D in_len + 1; if (wct =3D=3D 14) - inc_rfc1001_len(pSMB, count + 1); + in_len +=3D count + 1; else /* wct =3D=3D 12 */ - inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */ + in_len +=3D count + 5; /* smb data starts later */ if (wct =3D=3D 14) pSMB->ByteCount =3D cpu_to_le16(count + 1); else /* wct =3D=3D 12 */ /* bigger pad, smaller smb hdr, keep offset ok *= / { @@ -1983,6 +2008,7 @@ int cifs_lockv(const unsigned int xid, struct cifs_tc= on *tcon, LOCK_REQ *pSMB =3D NULL; struct kvec iov[2]; struct kvec rsp_iov; + unsigned int in_len; int resp_buf_type; __u16 count; =20 @@ -1990,8 +2016,9 @@ int cifs_lockv(const unsigned int xid, struct cifs_tc= on *tcon, num_lock, num_unlock); =20 rc =3D small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->Timeout =3D 0; pSMB->NumberOfLocks =3D cpu_to_le16(num_lock); @@ -2001,11 +2028,11 @@ int cifs_lockv(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->Fid =3D netfid; /* netfid stays le */ =20 count =3D (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); - inc_rfc1001_len(pSMB, count); + in_len +=3D count; pSMB->ByteCount =3D cpu_to_le16(count); =20 iov[0].iov_base =3D (char *)pSMB; - iov[0].iov_len =3D be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 - + iov[0].iov_len =3D in_len - (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); iov[1].iov_base =3D (char *)buf; iov[1].iov_len =3D (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); @@ -2030,6 +2057,7 @@ CIFSSMBLock(const unsigned int xid, struct cifs_tcon = *tcon, int rc =3D 0; LOCK_REQ *pSMB =3D NULL; /* LOCK_RSP *pSMBr =3D NULL; */ /* No response data other than rc to parse= */ + unsigned int in_len; int bytes_returned; int flags =3D 0; __u16 count; @@ -2038,8 +2066,9 @@ CIFSSMBLock(const unsigned int xid, struct cifs_tcon = *tcon, (int)waitFlag, numLock); rc =3D small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); =20 - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (lockType =3D=3D LOCKING_ANDX_OPLOCK_RELEASE) { /* no response expected */ @@ -2071,14 +2100,14 @@ CIFSSMBLock(const unsigned int xid, struct cifs_tco= n *tcon, /* oplock break */ count =3D 0; } - inc_rfc1001_len(pSMB, count); + in_len +=3D count; pSMB->ByteCount =3D cpu_to_le16(count); =20 if (waitFlag) - rc =3D SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, + rc =3D SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, in_le= n, (struct smb_hdr *) pSMB, &bytes_returned); else - rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags); + rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, in_len, flags); cifs_small_buf_release(pSMB); cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); if (rc) @@ -2099,6 +2128,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_= tcon *tcon, struct smb_com_transaction2_sfi_req *pSMB =3D NULL; struct smb_com_transaction2_sfi_rsp *pSMBr =3D NULL; struct cifs_posix_lock *parm_data; + unsigned int in_len; int rc =3D 0; int timeout =3D 0; int bytes_returned =3D 0; @@ -2110,9 +2140,9 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_= tcon *tcon, cifs_dbg(FYI, "Posix Lock\n"); =20 rc =3D small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); - - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMBr =3D (struct smb_com_transaction2_sfi_rsp *)pSMB; =20 @@ -2121,7 +2151,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->Reserved =3D 0; pSMB->Flags =3D 0; pSMB->Reserved2 =3D 0; - param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; + param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid); offset =3D param_offset + params; =20 count =3D sizeof(struct cifs_posix_lock); @@ -2139,9 +2169,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->TotalDataCount =3D pSMB->DataCount; pSMB->TotalParameterCount =3D pSMB->ParameterCount; pSMB->ParameterOffset =3D cpu_to_le16(param_offset); - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after R= FC1001 field */ - parm_data =3D (struct cifs_posix_lock *) - (((char *)pSMB) + offset + 4); + parm_data =3D (struct cifs_posix_lock *)(((char *)pSMB) + offset); =20 parm_data->lock_type =3D cpu_to_le16(lock_type); if (waitFlag) { @@ -2159,14 +2187,14 @@ CIFSSMBPosixLock(const unsigned int xid, struct cif= s_tcon *tcon, pSMB->Fid =3D smb_file_id; pSMB->InformationLevel =3D cpu_to_le16(SMB_SET_POSIX_LOCK); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); if (waitFlag) { - rc =3D SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, + rc =3D SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, in_le= n, (struct smb_hdr *) pSMBr, &bytes_returned); } else { iov[0].iov_base =3D (char *)pSMB; - iov[0].iov_len =3D be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; + iov[0].iov_len =3D in_len; rc =3D SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, &resp_buf_type, timeout, &rsp_iov); pSMBr =3D (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base; @@ -2226,19 +2254,22 @@ CIFSSMBClose(const unsigned int xid, struct cifs_tc= on *tcon, int smb_file_id) { int rc =3D 0; CLOSE_REQ *pSMB =3D NULL; + unsigned int in_len; + cifs_dbg(FYI, "In CIFSSMBClose\n"); =20 /* do not retry on dead session on close */ rc =3D small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB); if (rc =3D=3D -EAGAIN) return 0; - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->FileID =3D (__u16) smb_file_id; pSMB->LastWriteTime =3D 0xFFFFFFFF; pSMB->ByteCount =3D 0; - rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); cifs_small_buf_release(pSMB); cifs_stats_inc(&tcon->stats.cifs_stats.num_closes); if (rc) { @@ -2260,15 +2291,18 @@ CIFSSMBFlush(const unsigned int xid, struct cifs_tc= on *tcon, int smb_file_id) { int rc =3D 0; FLUSH_REQ *pSMB =3D NULL; + unsigned int in_len; + cifs_dbg(FYI, "In CIFSSMBFlush\n"); =20 rc =3D small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->FileID =3D (__u16) smb_file_id; pSMB->ByteCount =3D 0; - rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); cifs_small_buf_release(pSMB); cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes); if (rc) @@ -2285,6 +2319,7 @@ int CIFSSMBRename(const unsigned int xid, struct cifs= _tcon *tcon, int rc =3D 0; RENAME_REQ *pSMB =3D NULL; RENAME_RSP *pSMBr =3D NULL; + unsigned int in_len; int bytes_returned; int name_len, name_len2; __u16 count; @@ -2294,8 +2329,9 @@ int CIFSSMBRename(const unsigned int xid, struct cifs= _tcon *tcon, renameRetry: rc =3D smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->BufferFormat =3D 0x04; pSMB->SearchAttributes =3D @@ -2325,10 +2361,10 @@ int CIFSSMBRename(const unsigned int xid, struct ci= fs_tcon *tcon, } =20 count =3D 1 /* 1st signature byte */ + name_len + name_len2; - inc_rfc1001_len(pSMB, count); + in_len +=3D count; pSMB->ByteCount =3D cpu_to_le16(count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_renames); if (rc) @@ -2349,6 +2385,7 @@ int CIFSSMBRenameOpenFile(const unsigned int xid, str= uct cifs_tcon *pTcon, struct smb_com_transaction2_sfi_req *pSMB =3D NULL; struct smb_com_transaction2_sfi_rsp *pSMBr =3D NULL; struct set_file_rename *rename_info; + unsigned int in_len; char *data_offset; char dummy_string[30]; int rc =3D 0; @@ -2359,8 +2396,9 @@ int CIFSSMBRenameOpenFile(const unsigned int xid, str= uct cifs_tcon *pTcon, cifs_dbg(FYI, "Rename to File by handle\n"); rc =3D smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 6; pSMB->MaxSetupCount =3D 0; @@ -2368,11 +2406,10 @@ int CIFSSMBRenameOpenFile(const unsigned int xid, s= truct cifs_tcon *pTcon, pSMB->Flags =3D 0; pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; - param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; + param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid); offset =3D param_offset + params; =20 - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after R= FC1001 field */ - data_offset =3D (char *)(pSMB) + offset + 4; + data_offset =3D (char *)(pSMB) + offset; rename_info =3D (struct set_file_rename *) data_offset; pSMB->MaxParameterCount =3D cpu_to_le16(2); pSMB->MaxDataCount =3D cpu_to_le16(1000); /* BB find max SMB from sess */ @@ -2408,9 +2445,9 @@ int CIFSSMBRenameOpenFile(const unsigned int xid, str= uct cifs_tcon *pTcon, pSMB->InformationLevel =3D cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames); if (rc) @@ -2432,6 +2469,7 @@ CIFSUnixCreateSymLink(const unsigned int xid, struct = cifs_tcon *tcon, { TRANSACTION2_SPI_REQ *pSMB =3D NULL; TRANSACTION2_SPI_RSP *pSMBr =3D NULL; + unsigned int in_len; char *data_offset; int name_len; int name_len_target; @@ -2443,8 +2481,9 @@ CIFSUnixCreateSymLink(const unsigned int xid, struct = cifs_tcon *tcon, createSymLinkRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -2464,11 +2503,10 @@ CIFSUnixCreateSymLink(const unsigned int xid, struc= t cifs_tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; param_offset =3D offsetof(struct smb_com_transaction2_spi_req, - InformationLevel) - 4; + InformationLevel); offset =3D param_offset + params; =20 - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after R= FC1001 field */ - data_offset =3D (char *)pSMB + offset + 4; + data_offset =3D (char *)pSMB + offset; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len_target =3D cifsConvertToUTF16((__le16 *) data_offset, toName, @@ -2495,9 +2533,9 @@ CIFSUnixCreateSymLink(const unsigned int xid, struct = cifs_tcon *tcon, pSMB->DataOffset =3D cpu_to_le16(offset); pSMB->InformationLevel =3D cpu_to_le16(SMB_SET_FILE_UNIX_LINK); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks); if (rc) @@ -2519,6 +2557,7 @@ CIFSUnixCreateHardLink(const unsigned int xid, struct= cifs_tcon *tcon, { TRANSACTION2_SPI_REQ *pSMB =3D NULL; TRANSACTION2_SPI_RSP *pSMBr =3D NULL; + unsigned int in_len; char *data_offset; int name_len; int name_len_target; @@ -2530,8 +2569,9 @@ CIFSUnixCreateHardLink(const unsigned int xid, struct= cifs_tcon *tcon, createHardLinkRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D cifsConvertToUTF16((__le16 *) pSMB->FileName, toName, @@ -2549,11 +2589,10 @@ CIFSUnixCreateHardLink(const unsigned int xid, stru= ct cifs_tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; param_offset =3D offsetof(struct smb_com_transaction2_spi_req, - InformationLevel) - 4; + InformationLevel); offset =3D param_offset + params; =20 - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after R= FC1001 field */ - data_offset =3D (char *)pSMB + offset + 4; + data_offset =3D (char *)pSMB + offset; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len_target =3D cifsConvertToUTF16((__le16 *) data_offset, fromName, @@ -2579,9 +2618,9 @@ CIFSUnixCreateHardLink(const unsigned int xid, struct= cifs_tcon *tcon, pSMB->DataOffset =3D cpu_to_le16(offset); pSMB->InformationLevel =3D cpu_to_le16(SMB_SET_FILE_UNIX_HLINK); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); if (rc) @@ -2604,6 +2643,7 @@ int CIFSCreateHardLink(const unsigned int xid, int rc =3D 0; NT_RENAME_REQ *pSMB =3D NULL; RENAME_RSP *pSMBr =3D NULL; + unsigned int in_len; int bytes_returned; int name_len, name_len2; __u16 count; @@ -2614,8 +2654,9 @@ int CIFSCreateHardLink(const unsigned int xid, =20 rc =3D smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->SearchAttributes =3D cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | @@ -2649,10 +2690,10 @@ int CIFSCreateHardLink(const unsigned int xid, } =20 count =3D 1 /* string type byte */ + name_len + name_len2; - inc_rfc1001_len(pSMB, count); + in_len +=3D count; pSMB->ByteCount =3D cpu_to_le16(count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); if (rc) @@ -2673,6 +2714,7 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struc= t cifs_tcon *tcon, /* SMB_QUERY_FILE_UNIX_LINK */ TRANSACTION2_QPI_REQ *pSMB =3D NULL; TRANSACTION2_QPI_RSP *pSMBr =3D NULL; + unsigned int in_len; int rc =3D 0; int bytes_returned; int name_len; @@ -2684,8 +2726,9 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struc= t cifs_tcon *tcon, querySymLinkRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -2708,7 +2751,7 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struc= t cifs_tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; pSMB->ParameterOffset =3D cpu_to_le16(offsetof( - struct smb_com_transaction2_qpi_req, InformationLevel) - 4); + struct smb_com_transaction2_qpi_req, InformationLevel)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; @@ -2719,10 +2762,10 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, str= uct cifs_tcon *tcon, pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in QuerySymLinkInfo =3D %d\n", rc); @@ -2770,6 +2813,7 @@ int cifs_query_reparse_point(const unsigned int xid, TRANSACT_IOCTL_REQ *io_req =3D NULL; TRANSACT_IOCTL_RSP *io_rsp =3D NULL; struct cifs_fid fid; + unsigned int in_len; __u32 data_offset, data_count, len; __u8 *start, *end; int io_rsp_len; @@ -2801,8 +2845,9 @@ int cifs_query_reparse_point(const unsigned int xid, =20 rc =3D smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **)&io_req, (void **)&io_rsp); - if (rc) + if (rc < 0) goto error; + in_len =3D rc; =20 io_req->TotalParameterCount =3D 0; io_req->TotalDataCount =3D 0; @@ -2823,7 +2868,7 @@ int cifs_query_reparse_point(const unsigned int xid, io_req->Fid =3D fid.netfid; io_req->ByteCount =3D 0; =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req, in_len, (struct smb_hdr *)io_rsp, &io_rsp_len, 0); if (rc) goto error; @@ -2897,7 +2942,7 @@ struct inode *cifs_create_reparse_inode(struct cifs_o= pen_info_data *data, struct kvec in_iov[2]; struct kvec out_iov; struct cifs_fid fid; - int io_req_len; + unsigned int in_len; int oplock =3D 0; int buf_type =3D 0; int rc; @@ -2953,12 +2998,10 @@ struct inode *cifs_create_reparse_inode(struct cifs= _open_info_data *data, #endif =20 rc =3D smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **)&io_req, NULL); - if (rc) + if (rc < 0) goto out_close; - - inc_rfc1001_len(io_req, sizeof(io_req->Pad)); - - io_req_len =3D be32_to_cpu(io_req->hdr.smb_buf_length) + sizeof(io_req->h= dr.smb_buf_length); + in_len =3D rc; + in_len +=3D sizeof(io_req->Pad); =20 /* NT IOCTL response contains one-word long output setup buffer with size= of output data. */ io_req->MaxSetupCount =3D 1; @@ -2972,8 +3015,7 @@ struct inode *cifs_create_reparse_inode(struct cifs_o= pen_info_data *data, io_req->ParameterCount =3D io_req->TotalParameterCount; io_req->ParameterOffset =3D cpu_to_le32(0); io_req->DataCount =3D io_req->TotalDataCount; - io_req->DataOffset =3D cpu_to_le32(offsetof(typeof(*io_req), Data) - - sizeof(io_req->hdr.smb_buf_length)); + io_req->DataOffset =3D cpu_to_le32(offsetof(typeof(*io_req), Data)); io_req->SetupCount =3D 4; io_req->SubCommand =3D cpu_to_le16(NT_TRANSACT_IOCTL); io_req->FunctionCode =3D cpu_to_le32(FSCTL_SET_REPARSE_POINT); @@ -2982,10 +3024,8 @@ struct inode *cifs_create_reparse_inode(struct cifs_= open_info_data *data, io_req->IsRootFlag =3D 0; io_req->ByteCount =3D cpu_to_le16(le32_to_cpu(io_req->DataCount) + sizeof= (io_req->Pad)); =20 - inc_rfc1001_len(io_req, reparse_iov->iov_len); - in_iov[0].iov_base =3D (char *)io_req; - in_iov[0].iov_len =3D io_req_len; + in_iov[0].iov_len =3D in_len; in_iov[1] =3D *reparse_iov; rc =3D SendReceive2(xid, tcon->ses, in_iov, ARRAY_SIZE(in_iov), &buf_type, CIFS_NO_RSP_BUF, &out_iov); @@ -3017,12 +3057,14 @@ CIFSSMB_set_compression(const unsigned int xid, str= uct cifs_tcon *tcon, int bytes_returned; struct smb_com_transaction_compr_ioctl_req *pSMB; struct smb_com_transaction_ioctl_rsp *pSMBr; + unsigned int in_len; =20 cifs_dbg(FYI, "Set compression for %u\n", fid); rc =3D smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->compression_state =3D cpu_to_le16(COMPRESSION_FORMAT_DEFAULT); =20 @@ -3036,7 +3078,7 @@ CIFSSMB_set_compression(const unsigned int xid, struc= t cifs_tcon *tcon, pSMB->DataCount =3D cpu_to_le32(2); pSMB->DataOffset =3D cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req, - compression_state) - 4); /* 84 */ + compression_state)); /* 84 */ pSMB->SetupCount =3D 4; pSMB->SubCommand =3D cpu_to_le16(NT_TRANSACT_IOCTL); pSMB->ParameterCount =3D 0; @@ -3046,9 +3088,9 @@ CIFSSMB_set_compression(const unsigned int xid, struc= t cifs_tcon *tcon, pSMB->Fid =3D fid; /* file handle always le */ /* 3 byte pad, followed by 2 byte compress state */ pSMB->ByteCount =3D cpu_to_le16(5); - inc_rfc1001_len(pSMB, 5); + in_len +=3D 5; =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) cifs_dbg(FYI, "Send error in SetCompression =3D %d\n", rc); @@ -3246,6 +3288,7 @@ int cifs_do_get_acl(const unsigned int xid, struct ci= fs_tcon *tcon, /* SMB_QUERY_POSIX_ACL */ TRANSACTION2_QPI_REQ *pSMB =3D NULL; TRANSACTION2_QPI_RSP *pSMBr =3D NULL; + unsigned int in_len; int rc =3D 0; int bytes_returned; int name_len; @@ -3256,8 +3299,9 @@ int cifs_do_get_acl(const unsigned int xid, struct ci= fs_tcon *tcon, queryAclRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -3284,7 +3328,7 @@ int cifs_do_get_acl(const unsigned int xid, struct ci= fs_tcon *tcon, pSMB->Reserved2 =3D 0; pSMB->ParameterOffset =3D cpu_to_le16( offsetof(struct smb_com_transaction2_qpi_req, - InformationLevel) - 4); + InformationLevel)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; @@ -3295,10 +3339,10 @@ int cifs_do_get_acl(const unsigned int xid, struct = cifs_tcon *tcon, pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_POSIX_ACL); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); if (rc) { @@ -3336,6 +3380,7 @@ int cifs_do_set_acl(const unsigned int xid, struct ci= fs_tcon *tcon, { struct smb_com_transaction2_spi_req *pSMB =3D NULL; struct smb_com_transaction2_spi_rsp *pSMBr =3D NULL; + unsigned int in_len; char *parm_data; int name_len; int rc =3D 0; @@ -3346,8 +3391,9 @@ int cifs_do_set_acl(const unsigned int xid, struct ci= fs_tcon *tcon, setAclRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, @@ -3367,9 +3413,9 @@ int cifs_do_set_acl(const unsigned int xid, struct ci= fs_tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; param_offset =3D offsetof(struct smb_com_transaction2_spi_req, - InformationLevel) - 4; + InformationLevel); offset =3D param_offset + params; - parm_data =3D ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset; + parm_data =3D ((char *)pSMB) + offset; pSMB->ParameterOffset =3D cpu_to_le16(param_offset); =20 /* convert to on the wire format for POSIX ACL */ @@ -3390,9 +3436,9 @@ int cifs_do_set_acl(const unsigned int xid, struct ci= fs_tcon *tcon, pSMB->ParameterCount =3D cpu_to_le16(params); pSMB->TotalParameterCount =3D pSMB->ParameterCount; pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc); @@ -3428,6 +3474,7 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tc= on *tcon, int rc =3D 0; struct smb_t2_qfi_req *pSMB =3D NULL; struct smb_t2_qfi_rsp *pSMBr =3D NULL; + unsigned int in_len; int bytes_returned; __u16 params, byte_count; =20 @@ -3438,8 +3485,9 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tc= on *tcon, GetExtAttrRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 2 /* level */ + 2 /* fid */; pSMB->t2.TotalDataCount =3D 0; @@ -3452,7 +3500,7 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tc= on *tcon, pSMB->t2.Timeout =3D 0; pSMB->t2.Reserved2 =3D 0; pSMB->t2.ParameterOffset =3D cpu_to_le16(offsetof(struct smb_t2_qfi_req, - Fid) - 4); + Fid)); pSMB->t2.DataCount =3D 0; pSMB->t2.DataOffset =3D 0; pSMB->t2.SetupCount =3D 1; @@ -3464,10 +3512,10 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_ATTR_FLAGS); pSMB->Pad =3D 0; pSMB->Fid =3D netfid; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->t2.ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "error %d in GetExtAttr\n", rc); @@ -3520,11 +3568,13 @@ smb_init_nttransact(const __u16 sub_command, const = int setup_count, int rc; __u32 temp_offset; struct smb_com_ntransact_req *pSMB; + unsigned int in_len; =20 rc =3D small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, (void **)&pSMB); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; *ret_buf =3D (void *)pSMB; pSMB->Reserved =3D 0; pSMB->TotalParameterCount =3D cpu_to_le32(parm_len); @@ -3533,12 +3583,12 @@ smb_init_nttransact(const __u16 sub_command, const = int setup_count, pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->DataCount =3D pSMB->TotalDataCount; temp_offset =3D offsetof(struct smb_com_ntransact_req, Parms) + - (setup_count * 2) - 4 /* for rfc1001 length itself */; + (setup_count * 2); pSMB->ParameterOffset =3D cpu_to_le32(temp_offset); pSMB->DataOffset =3D cpu_to_le32(temp_offset + parm_len); pSMB->SetupCount =3D setup_count; /* no need to le convert byte fields */ pSMB->SubCommand =3D cpu_to_le16(sub_command); - return 0; + return in_len; } =20 static int @@ -3604,6 +3654,7 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs= _tcon *tcon, __u16 fid, QUERY_SEC_DESC_REQ *pSMB; struct kvec iov[1]; struct kvec rsp_iov; + unsigned int in_len; =20 cifs_dbg(FYI, "GetCifsACL\n"); =20 @@ -3612,8 +3663,9 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs= _tcon *tcon, __u16 fid, =20 rc =3D smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 8 /* parm len */, tcon, (void **) &pSMB); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->MaxParameterCount =3D cpu_to_le32(4); /* BB TEST with big acls that might need to be e.g. larger than 16K */ @@ -3621,9 +3673,9 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs= _tcon *tcon, __u16 fid, pSMB->Fid =3D fid; /* file handle always le */ pSMB->AclFlags =3D cpu_to_le32(info); pSMB->ByteCount =3D cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ - inc_rfc1001_len(pSMB, 11); + in_len +=3D 11; iov[0].iov_base =3D (char *)pSMB; - iov[0].iov_len =3D be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; + iov[0].iov_len =3D in_len; =20 rc =3D SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0, &rsp_iov); @@ -3692,18 +3744,20 @@ CIFSSMBSetCIFSACL(const unsigned int xid, struct ci= fs_tcon *tcon, __u16 fid, int rc =3D 0; int bytes_returned =3D 0; SET_SEC_DESC_REQ *pSMB =3D NULL; + unsigned int in_len; void *pSMBr; =20 setCifsAclRetry: rc =3D smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->MaxSetupCount =3D 0; pSMB->Reserved =3D 0; =20 param_count =3D 8; - param_offset =3D offsetof(struct smb_com_transaction_ssec_req, Fid) - 4; + param_offset =3D offsetof(struct smb_com_transaction_ssec_req, Fid); data_count =3D acllen; data_offset =3D param_offset + param_count; byte_count =3D 3 /* pad */ + param_count; @@ -3725,13 +3779,12 @@ CIFSSMBSetCIFSACL(const unsigned int xid, struct ci= fs_tcon *tcon, __u16 fid, pSMB->AclFlags =3D cpu_to_le32(aclflag); =20 if (pntsd && acllen) { - memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) + - data_offset, pntsd, acllen); - inc_rfc1001_len(pSMB, byte_count + data_count); + memcpy((char *)pSMBr + data_offset, pntsd, acllen); + in_len +=3D byte_count + data_count; } else - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); =20 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n", @@ -3756,6 +3809,7 @@ SMBQueryInformation(const unsigned int xid, struct ci= fs_tcon *tcon, { QUERY_INFORMATION_REQ *pSMB; QUERY_INFORMATION_RSP *pSMBr; + unsigned int in_len; int rc =3D 0; int bytes_returned; int name_len; @@ -3764,8 +3818,9 @@ SMBQueryInformation(const unsigned int xid, struct ci= fs_tcon *tcon, QInfRetry: rc =3D smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -3779,10 +3834,10 @@ SMBQueryInformation(const unsigned int xid, struct = cifs_tcon *tcon, } pSMB->BufferFormat =3D 0x04; name_len++; /* account for buffer type byte */ - inc_rfc1001_len(pSMB, (__u16)name_len); + in_len +=3D name_len; pSMB->ByteCount =3D cpu_to_le16(name_len); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in QueryInfo =3D %d\n", rc); @@ -3821,6 +3876,7 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_= tcon *tcon, { struct smb_t2_qfi_req *pSMB =3D NULL; struct smb_t2_qfi_rsp *pSMBr =3D NULL; + unsigned int in_len; int rc =3D 0; int bytes_returned; __u16 params, byte_count; @@ -3828,8 +3884,9 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_= tcon *tcon, QFileInfoRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 2 /* level */ + 2 /* fid */; pSMB->t2.TotalDataCount =3D 0; @@ -3842,7 +3899,7 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->t2.Timeout =3D 0; pSMB->t2.Reserved2 =3D 0; pSMB->t2.ParameterOffset =3D cpu_to_le16(offsetof(struct smb_t2_qfi_req, - Fid) - 4); + Fid)); pSMB->t2.DataCount =3D 0; pSMB->t2.DataOffset =3D 0; pSMB->t2.SetupCount =3D 1; @@ -3854,10 +3911,10 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cif= s_tcon *tcon, pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); pSMB->Pad =3D 0; pSMB->Fid =3D netfid; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->t2.ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in QFileInfo =3D %d\n", rc); @@ -3892,6 +3949,7 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_= tcon *tcon, /* level 263 SMB_QUERY_FILE_ALL_INFO */ TRANSACTION2_QPI_REQ *pSMB =3D NULL; TRANSACTION2_QPI_RSP *pSMBr =3D NULL; + unsigned int in_len; int rc =3D 0; int bytes_returned; int name_len; @@ -3901,8 +3959,9 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_= tcon *tcon, QPathInfoRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -3925,7 +3984,7 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; pSMB->ParameterOffset =3D cpu_to_le16(offsetof( - struct smb_com_transaction2_qpi_req, InformationLevel) - 4); + struct smb_com_transaction2_qpi_req, InformationLevel)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; @@ -3939,10 +3998,10 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cif= s_tcon *tcon, else pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in QPathInfo =3D %d\n", rc); @@ -3988,6 +4047,7 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct c= ifs_tcon *tcon, { struct smb_t2_qfi_req *pSMB =3D NULL; struct smb_t2_qfi_rsp *pSMBr =3D NULL; + unsigned int in_len; int rc =3D 0; int bytes_returned; __u16 params, byte_count; @@ -3995,8 +4055,9 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct c= ifs_tcon *tcon, UnixQFileInfoRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 2 /* level */ + 2 /* fid */; pSMB->t2.TotalDataCount =3D 0; @@ -4009,7 +4070,7 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct c= ifs_tcon *tcon, pSMB->t2.Timeout =3D 0; pSMB->t2.Reserved2 =3D 0; pSMB->t2.ParameterOffset =3D cpu_to_le16(offsetof(struct smb_t2_qfi_req, - Fid) - 4); + Fid)); pSMB->t2.DataCount =3D 0; pSMB->t2.DataOffset =3D 0; pSMB->t2.SetupCount =3D 1; @@ -4021,10 +4082,10 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct= cifs_tcon *tcon, pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); pSMB->Pad =3D 0; pSMB->Fid =3D netfid; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->t2.ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in UnixQFileInfo =3D %d\n", rc); @@ -4059,6 +4120,7 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct c= ifs_tcon *tcon, /* SMB_QUERY_FILE_UNIX_BASIC */ TRANSACTION2_QPI_REQ *pSMB =3D NULL; TRANSACTION2_QPI_RSP *pSMBr =3D NULL; + unsigned int in_len; int rc =3D 0; int bytes_returned =3D 0; int name_len; @@ -4068,8 +4130,9 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct c= ifs_tcon *tcon, UnixQPathInfoRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -4092,7 +4155,7 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct c= ifs_tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; pSMB->ParameterOffset =3D cpu_to_le16(offsetof( - struct smb_com_transaction2_qpi_req, InformationLevel) - 4); + struct smb_com_transaction2_qpi_req, InformationLevel)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; @@ -4103,10 +4166,10 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct= cifs_tcon *tcon, pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in UnixQPathInfo =3D %d\n", rc); @@ -4143,7 +4206,7 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tco= n *tcon, TRANSACTION2_FFIRST_RSP *pSMBr =3D NULL; T2_FFIRST_RSP_PARMS *parms; struct nls_table *nls_codepage; - unsigned int lnoff; + unsigned int in_len, lnoff; __u16 params, byte_count; int bytes_returned =3D 0; int name_len, remap; @@ -4154,8 +4217,9 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tco= n *tcon, findFirstRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 nls_codepage =3D cifs_sb->local_nls; remap =3D cifs_remap(cifs_sb); @@ -4215,8 +4279,7 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tco= n *tcon, pSMB->TotalParameterCount =3D cpu_to_le16(params); pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->ParameterOffset =3D cpu_to_le16( - offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) - - 4); + offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; /* one byte, no need to make endian neutral */ @@ -4231,10 +4294,10 @@ CIFSFindFirst(const unsigned int xid, struct cifs_t= con *tcon, =20 /* BB what should we set StorageType to? Does it matter? BB */ pSMB->SearchStorageType =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst); =20 @@ -4293,7 +4356,7 @@ int CIFSFindNext(const unsigned int xid, struct cifs_= tcon *tcon, TRANSACTION2_FNEXT_REQ *pSMB =3D NULL; TRANSACTION2_FNEXT_RSP *pSMBr =3D NULL; T2_FNEXT_RSP_PARMS *parms; - unsigned int name_len; + unsigned int name_len, in_len; unsigned int lnoff; __u16 params, byte_count; char *response_data; @@ -4307,8 +4370,9 @@ int CIFSFindNext(const unsigned int xid, struct cifs_= tcon *tcon, =20 rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 14; /* includes 2 bytes of null string, converted to LE below*/ byte_count =3D 0; @@ -4321,7 +4385,7 @@ int CIFSFindNext(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; pSMB->ParameterOffset =3D cpu_to_le16( - offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4); + offsetof(struct smb_com_transaction2_fnext_req, SearchHandle)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; @@ -4349,10 +4413,10 @@ int CIFSFindNext(const unsigned int xid, struct cif= s_tcon *tcon, byte_count =3D params + 1 /* pad */ ; pSMB->TotalParameterCount =3D cpu_to_le16(params); pSMB->ParameterCount =3D pSMB->TotalParameterCount; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext); =20 @@ -4418,6 +4482,7 @@ CIFSFindClose(const unsigned int xid, struct cifs_tco= n *tcon, { int rc =3D 0; FINDCLOSE_REQ *pSMB =3D NULL; + unsigned int in_len; =20 cifs_dbg(FYI, "In CIFSSMBFindClose\n"); rc =3D small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); @@ -4426,12 +4491,13 @@ CIFSFindClose(const unsigned int xid, struct cifs_t= con *tcon, as file handle has been closed */ if (rc =3D=3D -EAGAIN) return 0; - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->FileID =3D searchHandle; pSMB->ByteCount =3D 0; - rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); cifs_small_buf_release(pSMB); if (rc) cifs_dbg(VFS, "Send error in FindClose =3D %d\n", rc); @@ -4453,6 +4519,7 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct = cifs_tcon *tcon, int rc =3D 0; TRANSACTION2_QPI_REQ *pSMB =3D NULL; TRANSACTION2_QPI_RSP *pSMBr =3D NULL; + unsigned int in_len; int name_len, bytes_returned; __u16 params, byte_count; =20 @@ -4463,8 +4530,9 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct = cifs_tcon *tcon, GetInodeNumberRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -4488,7 +4556,7 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct = cifs_tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; pSMB->ParameterOffset =3D cpu_to_le16(offsetof( - struct smb_com_transaction2_qpi_req, InformationLevel) - 4); + struct smb_com_transaction2_qpi_req, InformationLevel)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; @@ -4499,10 +4567,10 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struc= t cifs_tcon *tcon, pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc); @@ -4545,6 +4613,7 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_s= es *ses, /* TRANS2_GET_DFS_REFERRAL */ TRANSACTION2_GET_DFS_REFER_REQ *pSMB =3D NULL; TRANSACTION2_GET_DFS_REFER_RSP *pSMBr =3D NULL; + unsigned int in_len; int rc =3D 0; int bytes_returned; int name_len; @@ -4564,8 +4633,9 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_s= es *ses, */ rc =3D smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **)&pSMB, (void **)&pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 /* server pointer checked in called function, but should never be null here anyway */ @@ -4607,7 +4677,7 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_s= es *ses, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; pSMB->ParameterOffset =3D cpu_to_le16(offsetof( - struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4); + struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel)); pSMB->SetupCount =3D 1; pSMB->Reserved3 =3D 0; pSMB->SubCommand =3D cpu_to_le16(TRANS2_GET_DFS_REFERRAL); @@ -4615,10 +4685,10 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs= _ses *ses, pSMB->ParameterCount =3D cpu_to_le16(params); pSMB->TotalParameterCount =3D pSMB->ParameterCount; pSMB->MaxReferralLevel =3D cpu_to_le16(3); - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in GetDFSRefer =3D %d\n", rc); @@ -4660,6 +4730,7 @@ SMBOldQFSInfo(const unsigned int xid, struct cifs_tco= n *tcon, TRANSACTION2_QFSI_REQ *pSMB =3D NULL; TRANSACTION2_QFSI_RSP *pSMBr =3D NULL; FILE_SYSTEM_ALLOC_INFO *response_data; + unsigned int in_len; int rc =3D 0; int bytes_returned =3D 0; __u16 params, byte_count; @@ -4668,8 +4739,9 @@ SMBOldQFSInfo(const unsigned int xid, struct cifs_tco= n *tcon, oldQFSInfoRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 2; /* level */ pSMB->TotalDataCount =3D 0; @@ -4684,17 +4756,17 @@ SMBOldQFSInfo(const unsigned int xid, struct cifs_t= con *tcon, pSMB->TotalParameterCount =3D cpu_to_le16(params); pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->ParameterOffset =3D cpu_to_le16(offsetof( - struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); + struct smb_com_transaction2_qfsi_req, InformationLevel)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; pSMB->Reserved3 =3D 0; pSMB->SubCommand =3D cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); pSMB->InformationLevel =3D cpu_to_le16(SMB_INFO_ALLOCATION); - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in QFSInfo =3D %d\n", rc); @@ -4747,6 +4819,7 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tc= on *tcon, TRANSACTION2_QFSI_REQ *pSMB =3D NULL; TRANSACTION2_QFSI_RSP *pSMBr =3D NULL; FILE_SYSTEM_SIZE_INFO *response_data; + unsigned int in_len; int rc =3D 0; int bytes_returned =3D 0; __u16 params, byte_count; @@ -4755,8 +4828,9 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tc= on *tcon, QFSInfoRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 2; /* level */ pSMB->TotalDataCount =3D 0; @@ -4771,17 +4845,17 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->TotalParameterCount =3D cpu_to_le16(params); pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->ParameterOffset =3D cpu_to_le16(offsetof( - struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); + struct smb_com_transaction2_qfsi_req, InformationLevel)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; pSMB->Reserved3 =3D 0; pSMB->SubCommand =3D cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_FS_SIZE_INFO); - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in QFSInfo =3D %d\n", rc); @@ -4833,6 +4907,7 @@ CIFSSMBQFSAttributeInfo(const unsigned int xid, struc= t cifs_tcon *tcon) TRANSACTION2_QFSI_REQ *pSMB =3D NULL; TRANSACTION2_QFSI_RSP *pSMBr =3D NULL; FILE_SYSTEM_ATTRIBUTE_INFO *response_data; + unsigned int in_len; int rc =3D 0; int bytes_returned =3D 0; __u16 params, byte_count; @@ -4841,8 +4916,9 @@ CIFSSMBQFSAttributeInfo(const unsigned int xid, struc= t cifs_tcon *tcon) QFSAttributeRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 2; /* level */ pSMB->TotalDataCount =3D 0; @@ -4858,17 +4934,17 @@ CIFSSMBQFSAttributeInfo(const unsigned int xid, str= uct cifs_tcon *tcon) pSMB->TotalParameterCount =3D cpu_to_le16(params); pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->ParameterOffset =3D cpu_to_le16(offsetof( - struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); + struct smb_com_transaction2_qfsi_req, InformationLevel)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; pSMB->Reserved3 =3D 0; pSMB->SubCommand =3D cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO); - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(VFS, "Send error in QFSAttributeInfo =3D %d\n", rc); @@ -4903,6 +4979,7 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct c= ifs_tcon *tcon) TRANSACTION2_QFSI_REQ *pSMB =3D NULL; TRANSACTION2_QFSI_RSP *pSMBr =3D NULL; FILE_SYSTEM_DEVICE_INFO *response_data; + unsigned int in_len; int rc =3D 0; int bytes_returned =3D 0; __u16 params, byte_count; @@ -4911,8 +4988,9 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct c= ifs_tcon *tcon) QFSDeviceRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 2; /* level */ pSMB->TotalDataCount =3D 0; @@ -4928,7 +5006,7 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct c= ifs_tcon *tcon) pSMB->TotalParameterCount =3D cpu_to_le16(params); pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->ParameterOffset =3D cpu_to_le16(offsetof( - struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); + struct smb_com_transaction2_qfsi_req, InformationLevel)); =20 pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; @@ -4936,10 +5014,10 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct= cifs_tcon *tcon) pSMB->Reserved3 =3D 0; pSMB->SubCommand =3D cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO); - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in QFSDeviceInfo =3D %d\n", rc); @@ -4974,6 +5052,7 @@ CIFSSMBQFSUnixInfo(const unsigned int xid, struct cif= s_tcon *tcon) TRANSACTION2_QFSI_REQ *pSMB =3D NULL; TRANSACTION2_QFSI_RSP *pSMBr =3D NULL; FILE_SYSTEM_UNIX_INFO *response_data; + unsigned int in_len; int rc =3D 0; int bytes_returned =3D 0; __u16 params, byte_count; @@ -4982,8 +5061,9 @@ CIFSSMBQFSUnixInfo(const unsigned int xid, struct cif= s_tcon *tcon) QFSUnixRetry: rc =3D smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 2; /* level */ pSMB->TotalDataCount =3D 0; @@ -5001,15 +5081,15 @@ CIFSSMBQFSUnixInfo(const unsigned int xid, struct c= ifs_tcon *tcon) pSMB->ParameterCount =3D cpu_to_le16(params); pSMB->TotalParameterCount =3D pSMB->ParameterCount; pSMB->ParameterOffset =3D cpu_to_le16(offsetof(struct - smb_com_transaction2_qfsi_req, InformationLevel) - 4); + smb_com_transaction2_qfsi_req, InformationLevel)); pSMB->SetupCount =3D 1; pSMB->Reserved3 =3D 0; pSMB->SubCommand =3D cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO); - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(VFS, "Send error in QFSUnixInfo =3D %d\n", rc); @@ -5043,6 +5123,7 @@ CIFSSMBSetFSUnixInfo(const unsigned int xid, struct c= ifs_tcon *tcon, __u64 cap) /* level 0x200 SMB_SET_CIFS_UNIX_INFO */ TRANSACTION2_SETFSI_REQ *pSMB =3D NULL; TRANSACTION2_SETFSI_RSP *pSMBr =3D NULL; + unsigned int in_len; int rc =3D 0; int bytes_returned =3D 0; __u16 params, param_offset, offset, byte_count; @@ -5052,8 +5133,9 @@ CIFSSMBSetFSUnixInfo(const unsigned int xid, struct c= ifs_tcon *tcon, __u64 cap) /* BB switch to small buf init to save memory */ rc =3D smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 4; /* 2 bytes zero followed by info level. */ pSMB->MaxSetupCount =3D 0; @@ -5061,8 +5143,7 @@ CIFSSMBSetFSUnixInfo(const unsigned int xid, struct c= ifs_tcon *tcon, __u64 cap) pSMB->Flags =3D 0; pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; - param_offset =3D offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - - 4; + param_offset =3D offsetof(struct smb_com_transaction2_setfsi_req, FileNum= ); offset =3D param_offset + params; =20 pSMB->MaxParameterCount =3D cpu_to_le16(4); @@ -5089,10 +5170,10 @@ CIFSSMBSetFSUnixInfo(const unsigned int xid, struct= cifs_tcon *tcon, __u64 cap) pSMB->ClientUnixMinor =3D cpu_to_le16(CIFS_UNIX_MINOR_VERSION); pSMB->ClientUnixCap =3D cpu_to_le64(cap); =20 - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(VFS, "Send error in SETFSUnixInfo =3D %d\n", rc); @@ -5119,6 +5200,7 @@ CIFSSMBQFSPosixInfo(const unsigned int xid, struct ci= fs_tcon *tcon, TRANSACTION2_QFSI_REQ *pSMB =3D NULL; TRANSACTION2_QFSI_RSP *pSMBr =3D NULL; FILE_SYSTEM_POSIX_INFO *response_data; + unsigned int in_len; int rc =3D 0; int bytes_returned =3D 0; __u16 params, byte_count; @@ -5127,8 +5209,9 @@ CIFSSMBQFSPosixInfo(const unsigned int xid, struct ci= fs_tcon *tcon, QFSPosixRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 params =3D 2; /* level */ pSMB->TotalDataCount =3D 0; @@ -5146,15 +5229,15 @@ CIFSSMBQFSPosixInfo(const unsigned int xid, struct = cifs_tcon *tcon, pSMB->ParameterCount =3D cpu_to_le16(params); pSMB->TotalParameterCount =3D pSMB->ParameterCount; pSMB->ParameterOffset =3D cpu_to_le16(offsetof(struct - smb_com_transaction2_qfsi_req, InformationLevel) - 4); + smb_com_transaction2_qfsi_req, InformationLevel)); pSMB->SetupCount =3D 1; pSMB->Reserved3 =3D 0; pSMB->SubCommand =3D cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); pSMB->InformationLevel =3D cpu_to_le16(SMB_QUERY_POSIX_FS_INFO); - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in QFSUnixInfo =3D %d\n", rc); @@ -5219,6 +5302,7 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_tco= n *tcon, struct smb_com_transaction2_spi_req *pSMB =3D NULL; struct smb_com_transaction2_spi_rsp *pSMBr =3D NULL; struct file_end_of_file_info *parm_data; + unsigned int in_len; int name_len; int rc =3D 0; int bytes_returned =3D 0; @@ -5230,8 +5314,9 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_tco= n *tcon, SetEOFRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -5252,7 +5337,7 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_tco= n *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; param_offset =3D offsetof(struct smb_com_transaction2_spi_req, - InformationLevel) - 4; + InformationLevel); offset =3D param_offset + params; if (set_allocation) { if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) @@ -5284,10 +5369,10 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_t= con *tcon, pSMB->ParameterCount =3D cpu_to_le16(params); pSMB->TotalParameterCount =3D pSMB->ParameterCount; pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; parm_data->FileSize =3D cpu_to_le64(size); pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc); @@ -5306,15 +5391,16 @@ CIFSSMBSetFileSize(const unsigned int xid, struct c= ifs_tcon *tcon, { struct smb_com_transaction2_sfi_req *pSMB =3D NULL; struct file_end_of_file_info *parm_data; + unsigned int in_len; int rc =3D 0; __u16 params, param_offset, offset, byte_count, count; =20 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n", (long long)size); rc =3D small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); - - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->hdr.Pid =3D cpu_to_le16((__u16)cfile->pid); pSMB->hdr.PidHigh =3D cpu_to_le16((__u16)(cfile->pid >> 16)); @@ -5325,7 +5411,7 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cif= s_tcon *tcon, pSMB->Flags =3D 0; pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; - param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; + param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid); offset =3D param_offset + params; =20 count =3D sizeof(struct file_end_of_file_info); @@ -5341,9 +5427,8 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cif= s_tcon *tcon, pSMB->TotalDataCount =3D pSMB->DataCount; pSMB->TotalParameterCount =3D pSMB->ParameterCount; pSMB->ParameterOffset =3D cpu_to_le16(param_offset); - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after R= FC1001 field */ parm_data =3D - (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4); + (struct file_end_of_file_info *)(((char *)pSMB) + offset); pSMB->DataOffset =3D cpu_to_le16(offset); parm_data->FileSize =3D cpu_to_le64(size); pSMB->Fid =3D cfile->fid.netfid; @@ -5363,9 +5448,9 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cif= s_tcon *tcon, cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); } pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); cifs_small_buf_release(pSMB); if (rc) { cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) =3D %d\n", @@ -5387,6 +5472,7 @@ SMBSetInformation(const unsigned int xid, struct cifs= _tcon *tcon, SETATTR_REQ *pSMB; SETATTR_RSP *pSMBr; struct timespec64 ts; + unsigned int in_len; int bytes_returned; int name_len; int rc; @@ -5396,8 +5482,9 @@ SMBSetInformation(const unsigned int xid, struct cifs= _tcon *tcon, retry: rc =3D smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -5419,10 +5506,10 @@ SMBSetInformation(const unsigned int xid, struct ci= fs_tcon *tcon, } pSMB->BufferFormat =3D 0x04; name_len++; /* account for buffer type byte */ - inc_rfc1001_len(pSMB, (__u16)name_len); + in_len +=3D name_len; pSMB->ByteCount =3D cpu_to_le16(name_len); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) cifs_dbg(FYI, "Send error in %s =3D %d\n", __func__, rc); @@ -5446,15 +5533,16 @@ CIFSSMBSetFileInfo(const unsigned int xid, struct c= ifs_tcon *tcon, const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener) { struct smb_com_transaction2_sfi_req *pSMB =3D NULL; + unsigned int in_len; char *data_offset; int rc =3D 0; __u16 params, param_offset, offset, byte_count, count; =20 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n"); rc =3D small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); - - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->hdr.Pid =3D cpu_to_le16((__u16)pid_of_opener); pSMB->hdr.PidHigh =3D cpu_to_le16((__u16)(pid_of_opener >> 16)); @@ -5465,11 +5553,10 @@ CIFSSMBSetFileInfo(const unsigned int xid, struct c= ifs_tcon *tcon, pSMB->Flags =3D 0; pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; - param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; + param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid); offset =3D param_offset + params; =20 - data_offset =3D (char *)pSMB + - offsetof(struct smb_hdr, Protocol) + offset; + data_offset =3D (char *)pSMB + offset; =20 count =3D sizeof(FILE_BASIC_INFO); pSMB->MaxParameterCount =3D cpu_to_le16(2); @@ -5491,10 +5578,10 @@ CIFSSMBSetFileInfo(const unsigned int xid, struct c= ifs_tcon *tcon, else pSMB->InformationLevel =3D cpu_to_le16(SMB_SET_FILE_BASIC_INFO); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); - rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); cifs_small_buf_release(pSMB); if (rc) cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) =3D %d\n", @@ -5511,15 +5598,16 @@ CIFSSMBSetFileDisposition(const unsigned int xid, s= truct cifs_tcon *tcon, bool delete_file, __u16 fid, __u32 pid_of_opener) { struct smb_com_transaction2_sfi_req *pSMB =3D NULL; + unsigned int in_len; char *data_offset; int rc =3D 0; __u16 params, param_offset, offset, byte_count, count; =20 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n"); rc =3D small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); - - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->hdr.Pid =3D cpu_to_le16((__u16)pid_of_opener); pSMB->hdr.PidHigh =3D cpu_to_le16((__u16)(pid_of_opener >> 16)); @@ -5530,11 +5618,9 @@ CIFSSMBSetFileDisposition(const unsigned int xid, st= ruct cifs_tcon *tcon, pSMB->Flags =3D 0; pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; - param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; + param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid); offset =3D param_offset + params; - - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after R= FC1001 field */ - data_offset =3D (char *)(pSMB) + offset + 4; + data_offset =3D (char *)(pSMB) + offset; =20 count =3D 1; pSMB->MaxParameterCount =3D cpu_to_le16(2); @@ -5553,10 +5639,10 @@ CIFSSMBSetFileDisposition(const unsigned int xid, s= truct cifs_tcon *tcon, pSMB->Fid =3D fid; pSMB->InformationLevel =3D cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); *data_offset =3D delete_file ? 1 : 0; - rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); cifs_small_buf_release(pSMB); if (rc) cifs_dbg(FYI, "Send error in SetFileDisposition =3D %d\n", rc); @@ -5604,6 +5690,7 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct cif= s_tcon *tcon, { TRANSACTION2_SPI_REQ *pSMB =3D NULL; TRANSACTION2_SPI_RSP *pSMBr =3D NULL; + unsigned int in_len; int name_len; int rc =3D 0; int bytes_returned =3D 0; @@ -5616,8 +5703,9 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct cif= s_tcon *tcon, SetTimesRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -5640,7 +5728,7 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct cif= s_tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; param_offset =3D offsetof(struct smb_com_transaction2_spi_req, - InformationLevel) - 4; + InformationLevel); offset =3D param_offset + params; data_offset =3D (char *)pSMB + offsetof(typeof(*pSMB), hdr.Protocol) + of= fset; pSMB->ParameterOffset =3D cpu_to_le16(param_offset); @@ -5659,10 +5747,10 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct c= ifs_tcon *tcon, else pSMB->InformationLevel =3D cpu_to_le16(SMB_SET_FILE_BASIC_INFO); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc); @@ -5732,15 +5820,16 @@ CIFSSMBUnixSetFileInfo(const unsigned int xid, stru= ct cifs_tcon *tcon, u16 fid, u32 pid_of_opener) { struct smb_com_transaction2_sfi_req *pSMB =3D NULL; + unsigned int in_len; char *data_offset; int rc =3D 0; u16 params, param_offset, offset, byte_count, count; =20 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n"); rc =3D small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); - - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 pSMB->hdr.Pid =3D cpu_to_le16((__u16)pid_of_opener); pSMB->hdr.PidHigh =3D cpu_to_le16((__u16)(pid_of_opener >> 16)); @@ -5751,11 +5840,10 @@ CIFSSMBUnixSetFileInfo(const unsigned int xid, stru= ct cifs_tcon *tcon, pSMB->Flags =3D 0; pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; - param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; + param_offset =3D offsetof(struct smb_com_transaction2_sfi_req, Fid); offset =3D param_offset + params; =20 - data_offset =3D (char *)pSMB + - offsetof(struct smb_hdr, Protocol) + offset; + data_offset =3D (char *)pSMB + offset; =20 count =3D sizeof(FILE_UNIX_BASIC_INFO); =20 @@ -5775,12 +5863,12 @@ CIFSSMBUnixSetFileInfo(const unsigned int xid, stru= ct cifs_tcon *tcon, pSMB->Fid =3D fid; pSMB->InformationLevel =3D cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args); =20 - rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0); cifs_small_buf_release(pSMB); if (rc) cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) =3D %d\n", @@ -5800,6 +5888,7 @@ CIFSSMBUnixSetPathInfo(const unsigned int xid, struct= cifs_tcon *tcon, { TRANSACTION2_SPI_REQ *pSMB =3D NULL; TRANSACTION2_SPI_RSP *pSMBr =3D NULL; + unsigned int in_len; int name_len; int rc =3D 0; int bytes_returned =3D 0; @@ -5810,8 +5899,9 @@ CIFSSMBUnixSetPathInfo(const unsigned int xid, struct= cifs_tcon *tcon, setPermsRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -5834,10 +5924,9 @@ CIFSSMBUnixSetPathInfo(const unsigned int xid, struc= t cifs_tcon *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; param_offset =3D offsetof(struct smb_com_transaction2_spi_req, - InformationLevel) - 4; + InformationLevel); offset =3D param_offset + params; - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after R= FC1001 field */ - data_offset =3D (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4); + data_offset =3D (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset); memset(data_offset, 0, count); pSMB->DataOffset =3D cpu_to_le16(offset); pSMB->ParameterOffset =3D cpu_to_le16(param_offset); @@ -5851,12 +5940,12 @@ CIFSSMBUnixSetPathInfo(const unsigned int xid, stru= ct cifs_tcon *tcon, pSMB->TotalDataCount =3D pSMB->DataCount; pSMB->InformationLevel =3D cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; =20 cifs_fill_unix_set_info(data_offset, args); =20 pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc); @@ -5888,6 +5977,7 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tc= on *tcon, TRANSACTION2_QPI_RSP *pSMBr =3D NULL; int remap =3D cifs_remap(cifs_sb); struct nls_table *nls_codepage =3D cifs_sb->local_nls; + unsigned int in_len; int rc =3D 0; int bytes_returned; int list_len; @@ -5902,8 +5992,9 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tc= on *tcon, QAllEAsRetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { list_len =3D @@ -5926,7 +6017,7 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tc= on *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; pSMB->ParameterOffset =3D cpu_to_le16(offsetof( - struct smb_com_transaction2_qpi_req, InformationLevel) - 4); + struct smb_com_transaction2_qpi_req, InformationLevel)); pSMB->DataCount =3D 0; pSMB->DataOffset =3D 0; pSMB->SetupCount =3D 1; @@ -5937,10 +6028,10 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->ParameterCount =3D pSMB->TotalParameterCount; pSMB->InformationLevel =3D cpu_to_le16(SMB_INFO_QUERY_ALL_EAS); pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); =20 - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cifs_dbg(FYI, "Send error in QueryAllEAs =3D %d\n", rc); @@ -6072,6 +6163,7 @@ CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon= *tcon, struct smb_com_transaction2_spi_req *pSMB =3D NULL; struct smb_com_transaction2_spi_rsp *pSMBr =3D NULL; struct fealist *parm_data; + unsigned int in_len; int name_len; int rc =3D 0; int bytes_returned =3D 0; @@ -6082,8 +6174,9 @@ CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon= *tcon, SetEARetry: rc =3D smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); - if (rc) + if (rc < 0) return rc; + in_len =3D rc; =20 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len =3D @@ -6115,12 +6208,12 @@ CIFSSMBSetEA(const unsigned int xid, struct cifs_tc= on *tcon, pSMB->Timeout =3D 0; pSMB->Reserved2 =3D 0; param_offset =3D offsetof(struct smb_com_transaction2_spi_req, - InformationLevel) - 4; + InformationLevel); offset =3D param_offset + params; pSMB->InformationLevel =3D cpu_to_le16(SMB_SET_FILE_EA); =20 - parm_data =3D (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset; + parm_data =3D (void *)pSMB + offset; pSMB->ParameterOffset =3D cpu_to_le16(param_offset); pSMB->DataOffset =3D cpu_to_le16(offset); pSMB->SetupCount =3D 1; @@ -6149,9 +6242,9 @@ CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon= *tcon, pSMB->ParameterCount =3D cpu_to_le16(params); pSMB->TotalParameterCount =3D pSMB->ParameterCount; pSMB->Reserved4 =3D 0; - inc_rfc1001_len(pSMB, byte_count); + in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); - rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc); diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c index 4c4f5befb6d3..d12578b37179 100644 --- a/fs/smb/client/cifstransport.c +++ b/fs/smb/client/cifstransport.c @@ -74,14 +74,14 @@ int smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, unsigned int smb_buf_length) { - struct kvec iov[2]; - struct smb_rqst rqst =3D { .rq_iov =3D iov, - .rq_nvec =3D 2 }; - - iov[0].iov_base =3D smb_buffer; - iov[0].iov_len =3D 4; - iov[1].iov_base =3D (char *)smb_buffer + 4; - iov[1].iov_len =3D smb_buf_length; + struct kvec iov[1] =3D { + [0].iov_base =3D smb_buffer, + [0].iov_len =3D smb_buf_length, + }; + struct smb_rqst rqst =3D { + .rq_iov =3D iov, + .rq_nvec =3D ARRAY_SIZE(iov), + }; =20 return __smb_send_rqst(server, 1, &rqst); } @@ -125,10 +125,6 @@ cifs_setup_async_request(struct TCP_Server_Info *serve= r, struct smb_rqst *rqst) struct smb_hdr *hdr =3D (struct smb_hdr *)rqst->rq_iov[0].iov_base; struct mid_q_entry *mid; =20 - if (rqst->rq_iov[0].iov_len !=3D 4 || - rqst->rq_iov[0].iov_base + 4 !=3D rqst->rq_iov[1].iov_base) - return ERR_PTR(-EIO); - /* enable signing if server requires it */ if (server->sign) hdr->Flags2 |=3D SMBFLG2_SECURITY_SIGNATURE; @@ -157,7 +153,7 @@ cifs_setup_async_request(struct TCP_Server_Info *server= , struct smb_rqst *rqst) */ int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, - char *in_buf, int flags) + char *in_buf, unsigned int in_len, int flags) { int rc; struct kvec iov[1]; @@ -165,7 +161,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifs_se= s *ses, int resp_buf_type; =20 iov[0].iov_base =3D in_buf; - iov[0].iov_len =3D get_rfc1002_len(in_buf) + 4; + iov[0].iov_len =3D in_len; flags |=3D CIFS_NO_RSP_BUF; rc =3D SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov); cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc); @@ -177,21 +173,19 @@ int cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, bool log_error) { - unsigned int len =3D get_rfc1002_len(mid->resp_buf) + 4; + unsigned int len =3D mid->response_pdu_len; =20 dump_smb(mid->resp_buf, min_t(u32, 92, len)); =20 /* convert the length into a more usable form */ if (server->sign) { - struct kvec iov[2]; + struct kvec iov[1]; int rc =3D 0; struct smb_rqst rqst =3D { .rq_iov =3D iov, - .rq_nvec =3D 2 }; + .rq_nvec =3D ARRAY_SIZE(iov) }; =20 iov[0].iov_base =3D mid->resp_buf; - iov[0].iov_len =3D 4; - iov[1].iov_base =3D (char *)mid->resp_buf + 4; - iov[1].iov_len =3D len - 4; + iov[0].iov_len =3D len; /* FIXME: add code to kill session */ rc =3D cifs_verify_signature(&rqst, server, mid->sequence_number); @@ -212,10 +206,6 @@ cifs_setup_request(struct cifs_ses *ses, struct TCP_Se= rver_Info *ignored, struct smb_hdr *hdr =3D (struct smb_hdr *)rqst->rq_iov[0].iov_base; struct mid_q_entry *mid; =20 - if (rqst->rq_iov[0].iov_len !=3D 4 || - rqst->rq_iov[0].iov_base + 4 !=3D rqst->rq_iov[1].iov_base) - return ERR_PTR(-EIO); - rc =3D allocate_mid(ses, hdr, &mid); if (rc) return ERR_PTR(rc); @@ -232,53 +222,29 @@ SendReceive2(const unsigned int xid, struct cifs_ses = *ses, struct kvec *iov, int n_vec, int *resp_buf_type /* ret */, const int flags, struct kvec *resp_iov) { - struct smb_rqst rqst; - struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov; - int rc; - - if (n_vec + 1 > CIFS_MAX_IOV_SIZE) { - new_iov =3D kmalloc_array(n_vec + 1, sizeof(struct kvec), - GFP_KERNEL); - if (!new_iov) { - /* otherwise cifs_send_recv below sets resp_buf_type */ - *resp_buf_type =3D CIFS_NO_BUFFER; - return -ENOMEM; - } - } else - new_iov =3D s_iov; - - /* 1st iov is a RFC1001 length followed by the rest of the packet */ - memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec)); - - new_iov[0].iov_base =3D new_iov[1].iov_base; - new_iov[0].iov_len =3D 4; - new_iov[1].iov_base +=3D 4; - new_iov[1].iov_len -=3D 4; - - memset(&rqst, 0, sizeof(struct smb_rqst)); - rqst.rq_iov =3D new_iov; - rqst.rq_nvec =3D n_vec + 1; + struct smb_rqst rqst =3D { + .rq_iov =3D iov, + .rq_nvec =3D n_vec, + }; =20 - rc =3D cifs_send_recv(xid, ses, ses->server, - &rqst, resp_buf_type, flags, resp_iov); - if (n_vec + 1 > CIFS_MAX_IOV_SIZE) - kfree(new_iov); - return rc; + return cifs_send_recv(xid, ses, ses->server, + &rqst, resp_buf_type, flags, resp_iov); } =20 int SendReceive(const unsigned int xid, struct cifs_ses *ses, - struct smb_hdr *in_buf, struct smb_hdr *out_buf, - int *pbytes_returned, const int flags) + struct smb_hdr *in_buf, unsigned int in_len, + struct smb_hdr *out_buf, int *pbytes_returned, const int flags) { int rc =3D 0; - struct mid_q_entry *midQ; - unsigned int len =3D be32_to_cpu(in_buf->smb_buf_length); - struct kvec iov =3D { .iov_base =3D in_buf, .iov_len =3D len }; + struct mid_q_entry *mid; + struct kvec iov =3D { .iov_base =3D in_buf, .iov_len =3D in_len }; struct smb_rqst rqst =3D { .rq_iov =3D &iov, .rq_nvec =3D 1 }; struct cifs_credits credits =3D { .value =3D 1, .instance =3D 0 }; struct TCP_Server_Info *server; =20 + if (WARN_ON_ONCE(in_len > 0xffffff)) + return -EIO; if (ses =3D=3D NULL) { cifs_dbg(VFS, "Null smb session\n"); return -EIO; @@ -300,9 +266,9 @@ SendReceive(const unsigned int xid, struct cifs_ses *se= s, to the same server. We may make this configurable later or use ses->maxReq */ =20 - if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { + if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { cifs_server_dbg(VFS, "Invalid length, greater than maximum frame, %d\n", - len); + in_len); return -EIO; } =20 @@ -316,7 +282,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *se= s, =20 cifs_server_lock(server); =20 - rc =3D allocate_mid(ses, in_buf, &midQ); + rc =3D allocate_mid(ses, in_buf, &mid); if (rc) { cifs_server_unlock(server); /* Update # of requests on wire to server */ @@ -324,16 +290,16 @@ SendReceive(const unsigned int xid, struct cifs_ses *= ses, return rc; } =20 - rc =3D cifs_sign_smb(in_buf, server, &midQ->sequence_number); + rc =3D cifs_sign_smb(in_buf, in_len, server, &mid->sequence_number); if (rc) { cifs_server_unlock(server); goto out; } =20 - midQ->mid_state =3D MID_REQUEST_SUBMITTED; + mid->mid_state =3D MID_REQUEST_SUBMITTED; =20 - rc =3D smb_send(server, in_buf, len); - cifs_save_when_sent(midQ); + rc =3D smb_send(server, in_buf, in_len); + cifs_save_when_sent(mid); =20 if (rc < 0) server->sequence_number -=3D 2; @@ -343,38 +309,38 @@ SendReceive(const unsigned int xid, struct cifs_ses *= ses, if (rc < 0) goto out; =20 - rc =3D wait_for_response(server, midQ); + rc =3D wait_for_response(server, mid); if (rc !=3D 0) { - send_cancel(server, &rqst, midQ); - spin_lock(&midQ->mid_lock); - if (midQ->callback) { + send_cancel(server, &rqst, mid); + spin_lock(&mid->mid_lock); + if (mid->callback) { /* no longer considered to be "in-flight" */ - midQ->callback =3D release_mid; - spin_unlock(&midQ->mid_lock); + mid->callback =3D release_mid; + spin_unlock(&mid->mid_lock); add_credits(server, &credits, 0); return rc; } - spin_unlock(&midQ->mid_lock); + spin_unlock(&mid->mid_lock); } =20 - rc =3D cifs_sync_mid_result(midQ, server); + rc =3D cifs_sync_mid_result(mid, server); if (rc !=3D 0) { add_credits(server, &credits, 0); return rc; } =20 - if (!midQ->resp_buf || !out_buf || - midQ->mid_state !=3D MID_RESPONSE_READY) { + if (!mid->resp_buf || !out_buf || + mid->mid_state !=3D MID_RESPONSE_READY) { rc =3D -EIO; cifs_server_dbg(VFS, "Bad MID state?\n"); goto out; } =20 - *pbytes_returned =3D get_rfc1002_len(midQ->resp_buf); - memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); - rc =3D cifs_check_receive(midQ, server, 0); + *pbytes_returned =3D mid->response_pdu_len; + memcpy(out_buf, mid->resp_buf, *pbytes_returned); + rc =3D cifs_check_receive(mid, server, 0); out: - delete_mid(midQ); + delete_mid(mid); add_credits(server, &credits, 0); =20 return rc; @@ -385,8 +351,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *se= s, =20 static int send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon, - struct smb_hdr *in_buf, - struct smb_hdr *out_buf) + struct smb_hdr *in_buf, unsigned int in_len, + struct smb_hdr *out_buf) { int bytes_returned; struct cifs_ses *ses =3D tcon->ses; @@ -401,25 +367,25 @@ send_lock_cancel(const unsigned int xid, struct cifs_= tcon *tcon, pSMB->Timeout =3D 0; pSMB->hdr.Mid =3D get_next_mid(ses->server); =20 - return SendReceive(xid, ses, in_buf, out_buf, + return SendReceive(xid, ses, in_buf, in_len, out_buf, &bytes_returned, 0); } =20 -int -SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, - struct smb_hdr *in_buf, struct smb_hdr *out_buf, - int *pbytes_returned) +int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, + struct smb_hdr *in_buf, unsigned int in_len, + struct smb_hdr *out_buf, int *pbytes_returned) { int rc =3D 0; int rstart =3D 0; - struct mid_q_entry *midQ; + struct mid_q_entry *mid; struct cifs_ses *ses; - unsigned int len =3D be32_to_cpu(in_buf->smb_buf_length); - struct kvec iov =3D { .iov_base =3D in_buf, .iov_len =3D len }; + struct kvec iov =3D { .iov_base =3D in_buf, .iov_len =3D in_len }; struct smb_rqst rqst =3D { .rq_iov =3D &iov, .rq_nvec =3D 1 }; unsigned int instance; struct TCP_Server_Info *server; =20 + if (WARN_ON_ONCE(in_len > 0xffffff)) + return -EIO; if (tcon =3D=3D NULL || tcon->ses =3D=3D NULL) { cifs_dbg(VFS, "Null smb session\n"); return -EIO; @@ -443,9 +409,9 @@ SendReceiveBlockingLock(const unsigned int xid, struct = cifs_tcon *tcon, to the same server. We may make this configurable later or use ses->maxReq */ =20 - if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { + if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { cifs_tcon_dbg(VFS, "Invalid length, greater than maximum frame, %d\n", - len); + in_len); return -EIO; } =20 @@ -459,22 +425,22 @@ SendReceiveBlockingLock(const unsigned int xid, struc= t cifs_tcon *tcon, =20 cifs_server_lock(server); =20 - rc =3D allocate_mid(ses, in_buf, &midQ); + rc =3D allocate_mid(ses, in_buf, &mid); if (rc) { cifs_server_unlock(server); return rc; } =20 - rc =3D cifs_sign_smb(in_buf, server, &midQ->sequence_number); + rc =3D cifs_sign_smb(in_buf, in_len, server, &mid->sequence_number); if (rc) { - delete_mid(midQ); + delete_mid(mid); cifs_server_unlock(server); return rc; } =20 - midQ->mid_state =3D MID_REQUEST_SUBMITTED; - rc =3D smb_send(server, in_buf, len); - cifs_save_when_sent(midQ); + mid->mid_state =3D MID_REQUEST_SUBMITTED; + rc =3D smb_send(server, in_buf, in_len); + cifs_save_when_sent(mid); =20 if (rc < 0) server->sequence_number -=3D 2; @@ -482,22 +448,22 @@ SendReceiveBlockingLock(const unsigned int xid, struc= t cifs_tcon *tcon, cifs_server_unlock(server); =20 if (rc < 0) { - delete_mid(midQ); + delete_mid(mid); return rc; } =20 /* Wait for a reply - allow signals to interrupt. */ rc =3D wait_event_interruptible(server->response_q, - (!(midQ->mid_state =3D=3D MID_REQUEST_SUBMITTED || - midQ->mid_state =3D=3D MID_RESPONSE_RECEIVED)) || + (!(mid->mid_state =3D=3D MID_REQUEST_SUBMITTED || + mid->mid_state =3D=3D MID_RESPONSE_RECEIVED)) || ((server->tcpStatus !=3D CifsGood) && (server->tcpStatus !=3D CifsNew))); =20 /* Were we interrupted by a signal ? */ spin_lock(&server->srv_lock); if ((rc =3D=3D -ERESTARTSYS) && - (midQ->mid_state =3D=3D MID_REQUEST_SUBMITTED || - midQ->mid_state =3D=3D MID_RESPONSE_RECEIVED) && + (mid->mid_state =3D=3D MID_REQUEST_SUBMITTED || + mid->mid_state =3D=3D MID_RESPONSE_RECEIVED) && ((server->tcpStatus =3D=3D CifsGood) || (server->tcpStatus =3D=3D CifsNew))) { spin_unlock(&server->srv_lock); @@ -505,36 +471,36 @@ SendReceiveBlockingLock(const unsigned int xid, struc= t cifs_tcon *tcon, if (in_buf->Command =3D=3D SMB_COM_TRANSACTION2) { /* POSIX lock. We send a NT_CANCEL SMB to cause the blocking lock to return. */ - rc =3D send_cancel(server, &rqst, midQ); + rc =3D send_cancel(server, &rqst, mid); if (rc) { - delete_mid(midQ); + delete_mid(mid); return rc; } } else { /* Windows lock. We send a LOCKINGX_CANCEL_LOCK to cause the blocking lock to return. */ =20 - rc =3D send_lock_cancel(xid, tcon, in_buf, out_buf); + rc =3D send_lock_cancel(xid, tcon, in_buf, in_len, out_buf); =20 /* If we get -ENOLCK back the lock may have already been removed. Don't exit in this case. */ if (rc && rc !=3D -ENOLCK) { - delete_mid(midQ); + delete_mid(mid); return rc; } } =20 - rc =3D wait_for_response(server, midQ); + rc =3D wait_for_response(server, mid); if (rc) { - send_cancel(server, &rqst, midQ); - spin_lock(&midQ->mid_lock); - if (midQ->callback) { + send_cancel(server, &rqst, mid); + spin_lock(&mid->mid_lock); + if (mid->callback) { /* no longer considered to be "in-flight" */ - midQ->callback =3D release_mid; - spin_unlock(&midQ->mid_lock); + mid->callback =3D release_mid; + spin_unlock(&mid->mid_lock); return rc; } - spin_unlock(&midQ->mid_lock); + spin_unlock(&mid->mid_lock); } =20 /* We got the response - restart system call. */ @@ -543,22 +509,22 @@ SendReceiveBlockingLock(const unsigned int xid, struc= t cifs_tcon *tcon, } spin_unlock(&server->srv_lock); =20 - rc =3D cifs_sync_mid_result(midQ, server); + rc =3D cifs_sync_mid_result(mid, server); if (rc !=3D 0) return rc; =20 /* rcvd frame is ok */ - if (out_buf =3D=3D NULL || midQ->mid_state !=3D MID_RESPONSE_READY) { + if (out_buf =3D=3D NULL || mid->mid_state !=3D MID_RESPONSE_READY) { rc =3D -EIO; cifs_tcon_dbg(VFS, "Bad MID state?\n"); goto out; } =20 - *pbytes_returned =3D get_rfc1002_len(midQ->resp_buf); - memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); - rc =3D cifs_check_receive(midQ, server, 0); + *pbytes_returned =3D mid->response_pdu_len; + memcpy(out_buf, mid->resp_buf, *pbytes_returned); + rc =3D cifs_check_receive(mid, server, 0); out: - delete_mid(midQ); + delete_mid(mid); if (rstart && rc =3D=3D -EACCES) return -ERESTARTSYS; return rc; diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index ab42235b2955..d10fe1b11377 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -1155,15 +1155,14 @@ standard_receive3(struct TCP_Server_Info *server, s= truct mid_q_entry *mid) unsigned int pdu_length =3D server->pdu_size; =20 /* make sure this will fit in a large buffer */ - if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - - HEADER_PREAMBLE_SIZE(server)) { + if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) { cifs_server_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length); cifs_reconnect(server, true); return -ECONNABORTED; } =20 /* switch to large buffer if too big for a small one */ - if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { + if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE) { server->large_buf =3D true; memcpy(server->bigbuf, buf, server->total_read); buf =3D server->bigbuf; @@ -1196,7 +1195,8 @@ cifs_handle_standard(struct TCP_Server_Info *server, = struct mid_q_entry *mid) * 48 bytes is enough to display the header and a little bit * into the payload for debugging purposes. */ - rc =3D server->ops->check_message(buf, server->total_read, server); + rc =3D server->ops->check_message(buf, server->pdu_size, + server->total_read, server); if (rc) cifs_dump_mem("Bad SMB: ", buf, min_t(unsigned int, server->total_read, 48)); @@ -1286,16 +1286,13 @@ cifs_demultiplex_thread(void *p) if (length < 0) continue; =20 - if (is_smb1(server)) - server->total_read =3D length; - else - server->total_read =3D 0; + server->total_read =3D 0; =20 /* * The right amount was read from socket - 4 bytes, * so we can now interpret the length field. */ - pdu_length =3D get_rfc1002_len(buf); + pdu_length =3D be32_to_cpup(((__be32 *)buf)) & 0xffffff; =20 cifs_dbg(FYI, "RFC1002 header 0x%x\n", pdu_length); if (!is_smb_response(server, buf[0])) @@ -1314,9 +1311,8 @@ cifs_demultiplex_thread(void *p) } =20 /* read down to the MID */ - length =3D cifs_read_from_socket(server, - buf + HEADER_PREAMBLE_SIZE(server), - MID_HEADER_SIZE(server)); + length =3D cifs_read_from_socket(server, buf, + MID_HEADER_SIZE(server)); if (length < 0) continue; server->total_read +=3D length; @@ -1348,6 +1344,8 @@ cifs_demultiplex_thread(void *p) bufs[0] =3D buf; num_mids =3D 1; =20 + if (mids[0]) + mids[0]->response_pdu_len =3D pdu_length; if (!mids[0] || !mids[0]->receive) length =3D standard_receive3(server, mids[0]); else @@ -1406,7 +1404,7 @@ cifs_demultiplex_thread(void *p) smb2_add_credits_from_hdr(bufs[i], server); #ifdef CONFIG_CIFS_DEBUG2 if (server->ops->dump_detail) - server->ops->dump_detail(bufs[i], + server->ops->dump_detail(bufs[i], pdu_length, server); cifs_dump_mids(server); #endif /* CIFS_DEBUG2 */ @@ -3999,7 +3997,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses, TCONX_RSP *pSMBr; unsigned char *bcc_ptr; int rc =3D 0; - int length; + int length, in_len; __u16 bytes_left, count; =20 if (ses =3D=3D NULL) @@ -4011,8 +4009,8 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses, =20 smb_buffer_response =3D smb_buffer; =20 - header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, - NULL /*no tid */, 4 /*wct */); + in_len =3D header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, + NULL /*no tid */, 4 /*wct */); =20 smb_buffer->Mid =3D get_next_mid(ses->server); smb_buffer->Uid =3D ses->Suid; @@ -4053,11 +4051,11 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *s= es, bcc_ptr +=3D strlen("?????"); bcc_ptr +=3D 1; count =3D bcc_ptr - &pSMB->Password[0]; - be32_add_cpu(&pSMB->hdr.smb_buf_length, count); + in_len +=3D count; pSMB->ByteCount =3D cpu_to_le16(count); =20 - rc =3D SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, - 0); + rc =3D SendReceive(xid, ses, smb_buffer, in_len, smb_buffer_response, + &length, 0); =20 /* above now done in SendReceive */ if (rc =3D=3D 0) { diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c index 340c44dc7b5b..a026dfd68d37 100644 --- a/fs/smb/client/misc.c +++ b/fs/smb/client/misc.c @@ -264,19 +264,18 @@ free_rsp_buf(int resp_buftype, void *rsp) =20 /* NB: MID can not be set if treeCon not passed in, in that case it is responsibility of caller to set the mid */ -void -header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , +unsigned int +header_assemble(struct smb_hdr *buffer, char smb_command, const struct cifs_tcon *treeCon, int word_count /* length of fixed section (word count) in two byte units */) { + unsigned int in_len; char *temp =3D (char *) buffer; =20 memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */ =20 - buffer->smb_buf_length =3D cpu_to_be32( - (2 * word_count) + sizeof(struct smb_hdr) - - 4 /* RFC 1001 length field does not count */ + - 2 /* for bcc field itself */) ; + in_len =3D (2 * word_count) + sizeof(struct smb_hdr) + + 2 /* for bcc field itself */; =20 buffer->Protocol[0] =3D 0xFF; buffer->Protocol[1] =3D 'S'; @@ -311,7 +310,7 @@ header_assemble(struct smb_hdr *buffer, char smb_comman= d /* command */ , =20 /* endian conversion of flags is now done just before sending */ buffer->WordCount =3D (char) word_count; - return; + return in_len; } =20 static int @@ -346,10 +345,11 @@ check_smb_hdr(struct smb_hdr *smb) } =20 int -checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *serve= r) +checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read, + struct TCP_Server_Info *server) { struct smb_hdr *smb =3D (struct smb_hdr *)buf; - __u32 rfclen =3D be32_to_cpu(smb->smb_buf_length); + __u32 rfclen =3D pdu_len; __u32 clc_len; /* calculated length */ cifs_dbg(FYI, "checkSMB Length: 0x%x, smb_buf_length: 0x%x\n", total_read, rfclen); @@ -394,24 +394,24 @@ checkSMB(char *buf, unsigned int total_read, struct T= CP_Server_Info *server) return -EIO; clc_len =3D smbCalcSize(smb); =20 - if (4 + rfclen !=3D total_read) { - cifs_dbg(VFS, "Length read does not match RFC1001 length %d\n", - rfclen); + if (rfclen !=3D total_read) { + cifs_dbg(VFS, "Length read does not match RFC1001 length %d/%d\n", + rfclen, total_read); return -EIO; } =20 - if (4 + rfclen !=3D clc_len) { + if (rfclen !=3D clc_len) { __u16 mid =3D get_mid(smb); /* check if bcc wrapped around for large read responses */ if ((rfclen > 64 * 1024) && (rfclen > clc_len)) { /* check if lengths match mod 64K */ - if (((4 + rfclen) & 0xFFFF) =3D=3D (clc_len & 0xFFFF)) + if (((rfclen) & 0xFFFF) =3D=3D (clc_len & 0xFFFF)) return 0; /* bcc wrapped */ } cifs_dbg(FYI, "Calculated size %u vs length %u mismatch for mid=3D%u\n", - clc_len, 4 + rfclen, mid); + clc_len, rfclen, mid); =20 - if (4 + rfclen < clc_len) { + if (rfclen < clc_len) { cifs_dbg(VFS, "RFC1001 size %u smaller than SMB for mid=3D%u\n", rfclen, mid); return -EIO; @@ -451,7 +451,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_I= nfo *srv) (struct smb_com_transaction_change_notify_rsp *)buf; struct file_notify_information *pnotify; __u32 data_offset =3D 0; - size_t len =3D srv->total_read - sizeof(pSMBr->hdr.smb_buf_length); + size_t len =3D srv->total_read - srv->pdu_size; =20 if (get_bcc(buf) > sizeof(struct file_notify_information)) { data_offset =3D le32_to_cpu(pSMBr->DataOffset); diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index ef3b498b0a02..752dee5a020c 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -1313,6 +1313,7 @@ struct sess_data { struct nls_table *nls_cp; void (*func)(struct sess_data *); int result; + unsigned int in_len; =20 /* we will send the SMB in three pieces: * a fixed length beginning part, an optional @@ -1336,11 +1337,12 @@ sess_alloc_buffer(struct sess_data *sess_data, int = wct) rc =3D small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses, (void **)&smb_buf); =20 - if (rc) + if (rc < 0) return rc; =20 + sess_data->in_len =3D rc; sess_data->iov[0].iov_base =3D (char *)smb_buf; - sess_data->iov[0].iov_len =3D be32_to_cpu(smb_buf->smb_buf_length) + 4; + sess_data->iov[0].iov_len =3D sess_data->in_len; /* * This variable will be used to clear the buffer * allocated above in case of any error in the calling function. @@ -1418,7 +1420,7 @@ sess_sendreceive(struct sess_data *sess_data) struct kvec rsp_iov =3D { NULL, 0 }; =20 count =3D sess_data->iov[1].iov_len + sess_data->iov[2].iov_len; - be32_add_cpu(&smb_buf->smb_buf_length, count); + sess_data->in_len +=3D count; put_bcc(count, smb_buf); =20 rc =3D SendReceive2(sess_data->xid, sess_data->ses, diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index a15ebd3f0d50..bb5b0438a300 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -34,15 +34,15 @@ send_nt_cancel(struct TCP_Server_Info *server, struct s= mb_rqst *rqst, { int rc =3D 0; struct smb_hdr *in_buf =3D (struct smb_hdr *)rqst->rq_iov[0].iov_base; + unsigned int in_len =3D rqst->rq_iov[0].iov_len; =20 - /* -4 for RFC1001 length and +2 for BCC field */ - in_buf->smb_buf_length =3D cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2); + /* +2 for BCC field */ in_buf->Command =3D SMB_COM_NT_CANCEL; in_buf->WordCount =3D 0; put_bcc(0, in_buf); =20 cifs_server_lock(server); - rc =3D cifs_sign_smb(in_buf, server, &mid->sequence_number); + rc =3D cifs_sign_smb(in_buf, in_len, server, &mid->sequence_number); if (rc) { cifs_server_unlock(server); return rc; @@ -54,7 +54,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb= _rqst *rqst, * after signing here. */ --server->sequence_number; - rc =3D smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); + rc =3D smb_send(server, in_buf, in_len); if (rc < 0) server->sequence_number--; =20 @@ -288,7 +288,7 @@ check2ndT2(char *buf) } =20 static int -coalesce_t2(char *second_buf, struct smb_hdr *target_hdr) +coalesce_t2(char *second_buf, struct smb_hdr *target_hdr, unsigned int *pd= u_len) { struct smb_t2_rsp *pSMBs =3D (struct smb_t2_rsp *)second_buf; struct smb_t2_rsp *pSMBt =3D (struct smb_t2_rsp *)target_hdr; @@ -354,15 +354,15 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_= hdr) } put_bcc(byte_count, target_hdr); =20 - byte_count =3D be32_to_cpu(target_hdr->smb_buf_length); + byte_count =3D *pdu_len; byte_count +=3D total_in_src; /* don't allow buffer to overflow */ - if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { + if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { cifs_dbg(FYI, "coalesced BCC exceeds buffer size (%u)\n", byte_count); return -ENOBUFS; } - target_hdr->smb_buf_length =3D cpu_to_be32(byte_count); + *pdu_len =3D byte_count; =20 /* copy second buffer into end of first buffer */ memcpy(data_area_of_tgt, data_area_of_src, total_in_src); @@ -397,7 +397,7 @@ cifs_check_trans2(struct mid_q_entry *mid, struct TCP_S= erver_Info *server, mid->multiRsp =3D true; if (mid->resp_buf) { /* merge response - fix up 1st*/ - malformed =3D coalesce_t2(buf, mid->resp_buf); + malformed =3D coalesce_t2(buf, mid->resp_buf, &mid->response_pdu_len); if (malformed > 0) return true; /* All parts received or packet is malformed. */ @@ -460,7 +460,7 @@ smb1_negotiate_wsize(struct cifs_tcon *tcon, struct smb= 3_fs_context *ctx) if (!(server->capabilities & CAP_LARGE_WRITE_X) || (!(server->capabilities & CAP_UNIX) && server->sign)) wsize =3D min_t(unsigned int, wsize, - server->maxBuf - sizeof(WRITE_REQ) + 4); + server->maxBuf - sizeof(WRITE_REQ)); =20 /* hard limit of CIFS_MAX_WSIZE */ wsize =3D min_t(unsigned int, wsize, CIFS_MAX_WSIZE); @@ -1486,7 +1486,6 @@ struct smb_version_values smb1_values =3D { .exclusive_lock_type =3D 0, .shared_lock_type =3D LOCKING_ANDX_SHARED_LOCK, .unlock_lock_type =3D 0, - .header_preamble_size =3D 4, .header_size =3D sizeof(struct smb_hdr), .max_header_size =3D MAX_CIFS_HDR_SIZE, .read_rsp_size =3D sizeof(READ_RSP), diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c index 96bfe4c63ccf..f3cb62d91450 100644 --- a/fs/smb/client/smb2misc.c +++ b/fs/smb/client/smb2misc.c @@ -134,7 +134,8 @@ static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u= 32 len, } =20 int -smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *se= rver) +smb2_check_message(char *buf, unsigned int pdu_len, unsigned int len, + struct TCP_Server_Info *server) { struct TCP_Server_Info *pserver; struct smb2_hdr *shdr =3D (struct smb2_hdr *)buf; diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 7ace6d4d305b..3b8d3852009e 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -432,7 +432,7 @@ smb2_find_dequeue_mid(struct TCP_Server_Info *server, c= har *buf) } =20 static void -smb2_dump_detail(void *buf, struct TCP_Server_Info *server) +smb2_dump_detail(void *buf, size_t buf_len, struct TCP_Server_Info *server) { #ifdef CONFIG_CIFS_DEBUG2 struct smb2_hdr *shdr =3D (struct smb2_hdr *)buf; @@ -440,7 +440,7 @@ smb2_dump_detail(void *buf, struct TCP_Server_Info *ser= ver) cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n", shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId, shdr->Id.SyncId.ProcessId); - if (!server->ops->check_message(buf, server->total_read, server)) { + if (!server->ops->check_message(buf, buf_len, server->total_read, server)= ) { cifs_server_dbg(VFS, "smb buf %p len %u\n", buf, server->ops->calc_smb_size(buf)); } @@ -5767,7 +5767,6 @@ struct smb_version_values smb20_values =3D { .shared_lock_type =3D SMB2_LOCKFLAG_SHARED, .unlock_lock_type =3D SMB2_LOCKFLAG_UNLOCK, .header_size =3D sizeof(struct smb2_hdr), - .header_preamble_size =3D 0, .max_header_size =3D MAX_SMB2_HDR_SIZE, .read_rsp_size =3D sizeof(struct smb2_read_rsp), .lock_cmd =3D SMB2_LOCK, @@ -5789,7 +5788,6 @@ struct smb_version_values smb21_values =3D { .shared_lock_type =3D SMB2_LOCKFLAG_SHARED, .unlock_lock_type =3D SMB2_LOCKFLAG_UNLOCK, .header_size =3D sizeof(struct smb2_hdr), - .header_preamble_size =3D 0, .max_header_size =3D MAX_SMB2_HDR_SIZE, .read_rsp_size =3D sizeof(struct smb2_read_rsp), .lock_cmd =3D SMB2_LOCK, @@ -5810,7 +5808,6 @@ struct smb_version_values smb3any_values =3D { .shared_lock_type =3D SMB2_LOCKFLAG_SHARED, .unlock_lock_type =3D SMB2_LOCKFLAG_UNLOCK, .header_size =3D sizeof(struct smb2_hdr), - .header_preamble_size =3D 0, .max_header_size =3D MAX_SMB2_HDR_SIZE, .read_rsp_size =3D sizeof(struct smb2_read_rsp), .lock_cmd =3D SMB2_LOCK, @@ -5831,7 +5828,6 @@ struct smb_version_values smbdefault_values =3D { .shared_lock_type =3D SMB2_LOCKFLAG_SHARED, .unlock_lock_type =3D SMB2_LOCKFLAG_UNLOCK, .header_size =3D sizeof(struct smb2_hdr), - .header_preamble_size =3D 0, .max_header_size =3D MAX_SMB2_HDR_SIZE, .read_rsp_size =3D sizeof(struct smb2_read_rsp), .lock_cmd =3D SMB2_LOCK, @@ -5852,7 +5848,6 @@ struct smb_version_values smb30_values =3D { .shared_lock_type =3D SMB2_LOCKFLAG_SHARED, .unlock_lock_type =3D SMB2_LOCKFLAG_UNLOCK, .header_size =3D sizeof(struct smb2_hdr), - .header_preamble_size =3D 0, .max_header_size =3D MAX_SMB2_HDR_SIZE, .read_rsp_size =3D sizeof(struct smb2_read_rsp), .lock_cmd =3D SMB2_LOCK, @@ -5873,7 +5868,6 @@ struct smb_version_values smb302_values =3D { .shared_lock_type =3D SMB2_LOCKFLAG_SHARED, .unlock_lock_type =3D SMB2_LOCKFLAG_UNLOCK, .header_size =3D sizeof(struct smb2_hdr), - .header_preamble_size =3D 0, .max_header_size =3D MAX_SMB2_HDR_SIZE, .read_rsp_size =3D sizeof(struct smb2_read_rsp), .lock_cmd =3D SMB2_LOCK, @@ -5894,7 +5888,6 @@ struct smb_version_values smb311_values =3D { .shared_lock_type =3D SMB2_LOCKFLAG_SHARED, .unlock_lock_type =3D SMB2_LOCKFLAG_UNLOCK, .header_size =3D sizeof(struct smb2_hdr), - .header_preamble_size =3D 0, .max_header_size =3D MAX_SMB2_HDR_SIZE, .read_rsp_size =3D sizeof(struct smb2_read_rsp), .lock_cmd =3D SMB2_LOCK, diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h index 5241daaae543..441df217c796 100644 --- a/fs/smb/client/smb2proto.h +++ b/fs/smb/client/smb2proto.h @@ -21,7 +21,7 @@ struct smb_rqst; ***************************************************************** */ extern int map_smb2_to_linux_error(char *buf, bool log_err); -extern int smb2_check_message(char *buf, unsigned int length, +extern int smb2_check_message(char *buf, unsigned int pdu_len, unsigned in= t length, struct TCP_Server_Info *server); extern unsigned int smb2_calc_size(void *buf); extern char *smb2_get_data_area_len(int *off, int *len, diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index 915cedde5d66..0401d3eb9370 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -289,8 +289,8 @@ int __smb_send_rqst(struct TCP_Server_Info *server, int= num_rqst, sigfillset(&mask); sigprocmask(SIG_BLOCK, &mask, &oldmask); =20 - /* Generate a rfc1002 marker for SMB2+ */ - if (!is_smb1(server)) { + /* Generate a rfc1002 marker */ + { struct kvec hiov =3D { .iov_base =3D &rfc1002_marker, .iov_len =3D 4 @@ -640,13 +640,13 @@ cifs_wait_mtu_credits(struct TCP_Server_Info *server,= size_t size, return 0; } =20 -int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *= midQ) +int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *= mid) { int error; =20 error =3D wait_event_state(server->response_q, - midQ->mid_state !=3D MID_REQUEST_SUBMITTED && - midQ->mid_state !=3D MID_RESPONSE_RECEIVED, + mid->mid_state !=3D MID_REQUEST_SUBMITTED && + mid->mid_state !=3D MID_RESPONSE_RECEIVED, (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE)); if (error < 0) return -ERESTARTSYS; @@ -866,7 +866,7 @@ compound_send_recv(const unsigned int xid, struct cifs_= ses *ses, int *resp_buf_type, struct kvec *resp_iov) { int i, j, optype, rc =3D 0; - struct mid_q_entry *midQ[MAX_COMPOUND]; + struct mid_q_entry *mid[MAX_COMPOUND]; bool cancelled_mid[MAX_COMPOUND] =3D {false}; struct cifs_credits credits[MAX_COMPOUND] =3D { { .value =3D 0, .instance =3D 0 } @@ -932,35 +932,35 @@ compound_send_recv(const unsigned int xid, struct cif= s_ses *ses, } =20 for (i =3D 0; i < num_rqst; i++) { - midQ[i] =3D server->ops->setup_request(ses, server, &rqst[i]); - if (IS_ERR(midQ[i])) { + mid[i] =3D server->ops->setup_request(ses, server, &rqst[i]); + if (IS_ERR(mid[i])) { revert_current_mid(server, i); for (j =3D 0; j < i; j++) - delete_mid(midQ[j]); + delete_mid(mid[j]); cifs_server_unlock(server); =20 /* Update # of requests on wire to server */ for (j =3D 0; j < num_rqst; j++) add_credits(server, &credits[j], optype); - return PTR_ERR(midQ[i]); + return PTR_ERR(mid[i]); } =20 - midQ[i]->mid_state =3D MID_REQUEST_SUBMITTED; - midQ[i]->optype =3D optype; + mid[i]->mid_state =3D MID_REQUEST_SUBMITTED; + mid[i]->optype =3D optype; /* * Invoke callback for every part of the compound chain * to calculate credits properly. Wake up this thread only when * the last element is received. */ if (i < num_rqst - 1) - midQ[i]->callback =3D cifs_compound_callback; + mid[i]->callback =3D cifs_compound_callback; else - midQ[i]->callback =3D cifs_compound_last_callback; + mid[i]->callback =3D cifs_compound_last_callback; } rc =3D smb_send_rqst(server, num_rqst, rqst, flags); =20 for (i =3D 0; i < num_rqst; i++) - cifs_save_when_sent(midQ[i]); + cifs_save_when_sent(mid[i]); =20 if (rc < 0) { revert_current_mid(server, num_rqst); @@ -1003,23 +1003,23 @@ compound_send_recv(const unsigned int xid, struct c= ifs_ses *ses, spin_unlock(&ses->ses_lock); =20 for (i =3D 0; i < num_rqst; i++) { - rc =3D wait_for_response(server, midQ[i]); + rc =3D wait_for_response(server, mid[i]); if (rc !=3D 0) break; } if (rc !=3D 0) { for (; i < num_rqst; i++) { cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n", - midQ[i]->mid, le16_to_cpu(midQ[i]->command)); - send_cancel(server, &rqst[i], midQ[i]); - spin_lock(&midQ[i]->mid_lock); - midQ[i]->wait_cancelled =3D true; - if (midQ[i]->callback) { - midQ[i]->callback =3D cifs_cancelled_callback; + mid[i]->mid, le16_to_cpu(mid[i]->command)); + send_cancel(server, &rqst[i], mid[i]); + spin_lock(&mid[i]->mid_lock); + mid[i]->wait_cancelled =3D true; + if (mid[i]->callback) { + mid[i]->callback =3D cifs_cancelled_callback; cancelled_mid[i] =3D true; credits[i].value =3D 0; } - spin_unlock(&midQ[i]->mid_lock); + spin_unlock(&mid[i]->mid_lock); } } =20 @@ -1027,36 +1027,35 @@ compound_send_recv(const unsigned int xid, struct c= ifs_ses *ses, if (rc < 0) goto out; =20 - rc =3D cifs_sync_mid_result(midQ[i], server); + rc =3D cifs_sync_mid_result(mid[i], server); if (rc !=3D 0) { /* mark this mid as cancelled to not free it below */ cancelled_mid[i] =3D true; goto out; } =20 - if (!midQ[i]->resp_buf || - midQ[i]->mid_state !=3D MID_RESPONSE_READY) { + if (!mid[i]->resp_buf || + mid[i]->mid_state !=3D MID_RESPONSE_READY) { rc =3D -EIO; cifs_dbg(FYI, "Bad MID state?\n"); goto out; } =20 - buf =3D (char *)midQ[i]->resp_buf; + buf =3D (char *)mid[i]->resp_buf; resp_iov[i].iov_base =3D buf; - resp_iov[i].iov_len =3D midQ[i]->resp_buf_size + - HEADER_PREAMBLE_SIZE(server); + resp_iov[i].iov_len =3D mid[i]->resp_buf_size; =20 - if (midQ[i]->large_buf) + if (mid[i]->large_buf) resp_buf_type[i] =3D CIFS_LARGE_BUFFER; else resp_buf_type[i] =3D CIFS_SMALL_BUFFER; =20 - rc =3D server->ops->check_receive(midQ[i], server, + rc =3D server->ops->check_receive(mid[i], server, flags & CIFS_LOG_ERROR); =20 /* mark it so buf will not be freed by delete_mid */ if ((flags & CIFS_NO_RSP_BUF) =3D=3D 0) - midQ[i]->resp_buf =3D NULL; + mid[i]->resp_buf =3D NULL; =20 } =20 @@ -1086,7 +1085,7 @@ compound_send_recv(const unsigned int xid, struct cif= s_ses *ses, */ for (i =3D 0; i < num_rqst; i++) { if (!cancelled_mid[i]) - delete_mid(midQ[i]); + delete_mid(mid[i]); } =20 return rc; @@ -1111,8 +1110,7 @@ int cifs_discard_remaining_data(struct TCP_Server_Info *server) { unsigned int rfclen =3D server->pdu_size; - size_t remaining =3D rfclen + HEADER_PREAMBLE_SIZE(server) - - server->total_read; + size_t remaining =3D rfclen - server->total_read; =20 while (remaining > 0) { ssize_t length; @@ -1157,7 +1155,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, st= ruct mid_q_entry *mid) unsigned int data_offset, data_len; struct cifs_io_subrequest *rdata =3D mid->callback_data; char *buf =3D server->smallbuf; - unsigned int buflen =3D server->pdu_size + HEADER_PREAMBLE_SIZE(server); + unsigned int buflen =3D server->pdu_size; bool use_rdma_mr =3D false; =20 cifs_dbg(FYI, "%s: mid=3D%llu offset=3D%llu bytes=3D%zu\n", @@ -1191,14 +1189,9 @@ cifs_readv_receive(struct TCP_Server_Info *server, s= truct mid_q_entry *mid) =20 /* set up first two iov for signature check and to get credits */ rdata->iov[0].iov_base =3D buf; - rdata->iov[0].iov_len =3D HEADER_PREAMBLE_SIZE(server); - rdata->iov[1].iov_base =3D buf + HEADER_PREAMBLE_SIZE(server); - rdata->iov[1].iov_len =3D - server->total_read - HEADER_PREAMBLE_SIZE(server); + rdata->iov[0].iov_len =3D server->total_read; cifs_dbg(FYI, "0: iov_base=3D%p iov_len=3D%zu\n", rdata->iov[0].iov_base, rdata->iov[0].iov_len); - cifs_dbg(FYI, "1: iov_base=3D%p iov_len=3D%zu\n", - rdata->iov[1].iov_base, rdata->iov[1].iov_len); =20 /* Was the SMB read successful? */ rdata->result =3D server->ops->map_error(buf, false); @@ -1218,8 +1211,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, st= ruct mid_q_entry *mid) return cifs_readv_discard(server, mid); } =20 - data_offset =3D server->ops->read_data_offset(buf) + - HEADER_PREAMBLE_SIZE(server); + data_offset =3D server->ops->read_data_offset(buf); if (data_offset < server->total_read) { /* * win2k8 sometimes sends an offset of 0 when the read diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h index f38c5739a9d2..945a8e0cf36c 100644 --- a/fs/smb/common/smb2pdu.h +++ b/fs/smb/common/smb2pdu.h @@ -2016,9 +2016,6 @@ struct smb2_lease_ack { * MS-SMB 2.2.3.1 */ struct smb_hdr { - __be32 smb_buf_length; /* BB length is only two (rarely three) bytes, - with one or two byte "type" preceding it that will be - zero - we could mask the type byte off */ __u8 Protocol[4]; __u8 Command; union { diff --git a/fs/smb/common/smbglob.h b/fs/smb/common/smbglob.h index 7853b5771128..9562845a5617 100644 --- a/fs/smb/common/smbglob.h +++ b/fs/smb/common/smbglob.h @@ -26,7 +26,6 @@ struct smb_version_values { __u32 exclusive_lock_type; __u32 shared_lock_type; __u32 unlock_lock_type; - size_t header_preamble_size; size_t header_size; size_t max_header_size; size_t read_rsp_size; From nobody Tue Dec 2 00:25:46 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 01E7F29BDBA for ; Mon, 1 Dec 2025 22:57:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629876; cv=none; b=giA65mLrZrV6TsARRJFfln/WQY4ZpaFh0Qy6m1Z9GFuJsiKy0GLQojvnFoePGE82NxuCDhhQsgkCNjVjUGT0Z1Cg3kSIOl/twskjYHqgWxp2mOeOabIzGQ+mwEpPd3cyuWWt6SEYc/rIPj3aeQ2JC+aYTXQev0oweXgXRPSz+jo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629876; c=relaxed/simple; bh=v0w0wbBuRmE/hqCTHUNxRWFx5sXO9L3DeoDFuabhKQk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=E/jM544kN++f3PhctlJZzuHrAcwykc+7ftwJbhL5CQIRbzGbR8+jFwK0lllhKxizjv8IJkDaP34s6mfj3jqlMPl1hXRafRRYA31Vf2gbMYTCSsTi8pkMj918QaPVvfhmPy3Dy+cEgJ8o/R3fIQ4IdasdzcDUKzx8ewNY0eyMtDM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=HSLBmML4; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="HSLBmML4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764629873; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7ZvOM2ptPjoWsye4CO/Rb2gimmR4GB33tvnhv1f5q2M=; b=HSLBmML4KyhFHZpN4kswlGm1OY1NVX/u9FLw+vcYxsBPVbWGfhXCRhB9r2Dd0A9pGcSzMH p+gQndsh37ANUCzEAAdNDMvcRHLJnyvlq9B7ZfVGnrwk6lo1wLXg7hIkaHp5FElGgL30/F Je0n9VsRO0KUm7rKf4GgoaVlPbo4gAc= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-617-vq83y0RJNbqM3IFXqf4CkA-1; Mon, 01 Dec 2025 17:57:50 -0500 X-MC-Unique: vq83y0RJNbqM3IFXqf4CkA-1 X-Mimecast-MFC-AGG-ID: vq83y0RJNbqM3IFXqf4CkA_1764629868 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 354D3180057A; Mon, 1 Dec 2025 22:57:48 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.14]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5529419560A7; Mon, 1 Dec 2025 22:57:45 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Stefan Metzmacher , Tom Talpey , linux-cifs@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 2/9] cifs: Make smb1's SendReceive() wrap cifs_send_recv() Date: Mon, 1 Dec 2025 22:57:23 +0000 Message-ID: <20251201225732.1520128-3-dhowells@redhat.com> In-Reply-To: <20251201225732.1520128-1-dhowells@redhat.com> References: <20251201225732.1520128-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Make the smb1 transport's SendReceive() simply wrap cifs_send_recv() as does SendReceive2(). This will then allow that to pick up the transport changes there. Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: Shyam Prasad N cc: Tom Talpey cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org --- fs/smb/client/cifstransport.c | 82 +++++------------------------------ 1 file changed, 10 insertions(+), 72 deletions(-) diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c index d12578b37179..1a28d361b1f7 100644 --- a/fs/smb/client/cifstransport.c +++ b/fs/smb/client/cifstransport.c @@ -236,12 +236,12 @@ SendReceive(const unsigned int xid, struct cifs_ses *= ses, struct smb_hdr *in_buf, unsigned int in_len, struct smb_hdr *out_buf, int *pbytes_returned, const int flags) { - int rc =3D 0; - struct mid_q_entry *mid; + struct TCP_Server_Info *server; + struct kvec resp_iov =3D {}; struct kvec iov =3D { .iov_base =3D in_buf, .iov_len =3D in_len }; struct smb_rqst rqst =3D { .rq_iov =3D &iov, .rq_nvec =3D 1 }; - struct cifs_credits credits =3D { .value =3D 1, .instance =3D 0 }; - struct TCP_Server_Info *server; + int resp_buf_type; + int rc =3D 0; =20 if (WARN_ON_ONCE(in_len > 0xffffff)) return -EIO; @@ -272,77 +272,15 @@ SendReceive(const unsigned int xid, struct cifs_ses *= ses, return -EIO; } =20 - rc =3D wait_for_free_request(server, flags, &credits.instance); - if (rc) - return rc; - - /* make sure that we sign in the same order that we send on this socket - and avoid races inside tcp sendmsg code that could cause corruption - of smb data */ - - cifs_server_lock(server); - - rc =3D allocate_mid(ses, in_buf, &mid); - if (rc) { - cifs_server_unlock(server); - /* Update # of requests on wire to server */ - add_credits(server, &credits, 0); - return rc; - } - - rc =3D cifs_sign_smb(in_buf, in_len, server, &mid->sequence_number); - if (rc) { - cifs_server_unlock(server); - goto out; - } - - mid->mid_state =3D MID_REQUEST_SUBMITTED; - - rc =3D smb_send(server, in_buf, in_len); - cifs_save_when_sent(mid); - - if (rc < 0) - server->sequence_number -=3D 2; - - cifs_server_unlock(server); - + rc =3D cifs_send_recv(xid, ses, ses->server, + &rqst, &resp_buf_type, flags, &resp_iov); if (rc < 0) - goto out; - - rc =3D wait_for_response(server, mid); - if (rc !=3D 0) { - send_cancel(server, &rqst, mid); - spin_lock(&mid->mid_lock); - if (mid->callback) { - /* no longer considered to be "in-flight" */ - mid->callback =3D release_mid; - spin_unlock(&mid->mid_lock); - add_credits(server, &credits, 0); - return rc; - } - spin_unlock(&mid->mid_lock); - } - - rc =3D cifs_sync_mid_result(mid, server); - if (rc !=3D 0) { - add_credits(server, &credits, 0); return rc; - } - - if (!mid->resp_buf || !out_buf || - mid->mid_state !=3D MID_RESPONSE_READY) { - rc =3D -EIO; - cifs_server_dbg(VFS, "Bad MID state?\n"); - goto out; - } - - *pbytes_returned =3D mid->response_pdu_len; - memcpy(out_buf, mid->resp_buf, *pbytes_returned); - rc =3D cifs_check_receive(mid, server, 0); -out: - delete_mid(mid); - add_credits(server, &credits, 0); =20 + *pbytes_returned =3D resp_iov.iov_len; + if (resp_iov.iov_len) + memcpy(out_buf, resp_iov.iov_base, resp_iov.iov_len); + free_rsp_buf(resp_buf_type, resp_iov.iov_base); return rc; } From nobody Tue Dec 2 00:25:46 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C3B882BD030 for ; Mon, 1 Dec 2025 22:57:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629879; cv=none; b=KkhrISRG8e2N1QsIRnZtep/UhsHBGyBaQRDQNVvyvy1b2DirVF6md1eLv/lONuVFC3wXUxN2RRjdsWmJvxXbFJLaZ15xjudWW58J9q1jXMrGFZTvPRSQt/WUwYSOzxi4eEQ5mQHWecnmEtQo3Wfg+yxGYmEDzQuQoO0LPmlDRJc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629879; c=relaxed/simple; bh=al+Um88a5DxNHYjxnfsVKIqoYgMrvlEOdgpJt4gsJrM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kklYNoJy2gQdHCE6tmdsONHmibYVfRELRL3/X2FAA0kqsCyq1M0h+hZsrErFmhlgHbyiiZokPU1EQoY+d/umi00Np1zsly6vDPX7Hge8AdqxJKG7X4PDuqr65OiTtQ9NuGnPrYGEybEaJfBcK9uA0eNjaxqjKR+8qiItKUnDkXQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ARiRadfS; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ARiRadfS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764629876; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=H5z3taMElbBotirZeASIdy+kqLgBwsqrocgqhkVpjh0=; b=ARiRadfSiBtVoYa4IsXbor0lujTArRvX1SqrwceE6+TWx/AAIm8QwCB8Uk64O+ee8FpSUQ c9T2PtY9UIKrBapcnJUZzcdk1w60fhdN4hGCYWq0PkN2LWIF0za67+OYio2sb5w1RRxeRo YK/1JTX2ix4LbLf0IKxxhU2DC+fyhYI= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-578-wvl55oa4N1yS4YrjEC58MQ-1; Mon, 01 Dec 2025 17:57:53 -0500 X-MC-Unique: wvl55oa4N1yS4YrjEC58MQ-1 X-Mimecast-MFC-AGG-ID: wvl55oa4N1yS4YrjEC58MQ_1764629872 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1B6FA195606F; Mon, 1 Dec 2025 22:57:52 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.14]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 97D171800451; Mon, 1 Dec 2025 22:57:49 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Stefan Metzmacher , Tom Talpey , linux-cifs@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 3/9] cifs: Clean up some places where an extra kvec[] was required for rfc1002 Date: Mon, 1 Dec 2025 22:57:24 +0000 Message-ID: <20251201225732.1520128-4-dhowells@redhat.com> In-Reply-To: <20251201225732.1520128-1-dhowells@redhat.com> References: <20251201225732.1520128-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Content-Type: text/plain; charset="utf-8" Clean up some places where previously an extra element in the kvec array was being used to hold an rfc1002 header for SMB1 (a previous patch removed this and generated it on the fly as for SMB2/3). Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: Shyam Prasad N cc: Tom Talpey cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org --- fs/smb/client/cifsencrypt.c | 52 ++++++++--------------------------- fs/smb/client/cifsproto.h | 7 ----- fs/smb/client/cifstransport.c | 20 ++------------ fs/smb/client/smb1ops.c | 12 +++++--- fs/smb/client/transport.c | 30 +++++++++++--------- 5 files changed, 39 insertions(+), 82 deletions(-) diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c index 1e0ac87c6686..a9a57904c6b1 100644 --- a/fs/smb/client/cifsencrypt.c +++ b/fs/smb/client/cifsencrypt.c @@ -86,26 +86,21 @@ static int cifs_sig_iter(const struct iov_iter *iter, s= ize_t maxsize, int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *s= erver, char *signature, struct cifs_calc_sig_ctx *ctx) { - int i; + struct iov_iter iter; ssize_t rc; - struct kvec *iov =3D rqst->rq_iov; - int n_vec =3D rqst->rq_nvec; + size_t size =3D 0; =20 - for (i =3D 0; i < n_vec; i++) { - if (iov[i].iov_len =3D=3D 0) - continue; - if (iov[i].iov_base =3D=3D NULL) { - cifs_dbg(VFS, "null iovec entry\n"); - return -EIO; - } + for (int i =3D 0; i < rqst->rq_nvec; i++) + size +=3D rqst->rq_iov[i].iov_len; =20 - rc =3D cifs_sig_update(ctx, iov[i].iov_base, iov[i].iov_len); - if (rc) { - cifs_dbg(VFS, "%s: Could not update with payload\n", - __func__); - return rc; - } - } + iov_iter_kvec(&iter, ITER_SOURCE, rqst->rq_iov, rqst->rq_nvec, size); + + if (iov_iter_count(&iter) <=3D 4) + return -EIO; + + rc =3D cifs_sig_iter(&iter, iov_iter_count(&iter), ctx); + if (rc < 0) + return rc; =20 rc =3D cifs_sig_iter(&rqst->rq_iter, iov_iter_count(&rqst->rq_iter), ctx); if (rc < 0) @@ -186,29 +181,6 @@ int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_S= erver_Info *server, return rc; } =20 -int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *se= rver, - __u32 *pexpected_response_sequence) -{ - struct smb_rqst rqst =3D { .rq_iov =3D iov, - .rq_nvec =3D n_vec }; - - return cifs_sign_rqst(&rqst, server, pexpected_response_sequence); -} - -/* must be called with server->srv_mutex held */ -int cifs_sign_smb(struct smb_hdr *cifs_pdu, unsigned int pdu_len, - struct TCP_Server_Info *server, - __u32 *pexpected_response_sequence_number) -{ - struct kvec iov[1] =3D { - [0].iov_base =3D (char *)cifs_pdu, - [0].iov_len =3D pdu_len, - }; - - return cifs_sign_smbv(iov, ARRAY_SIZE(iov), server, - pexpected_response_sequence_number); -} - int cifs_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, __u32 expected_sequence_number) diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index 7fb40684a584..13e0367e0e10 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -30,8 +30,6 @@ extern void cifs_buf_release(void *); extern struct smb_hdr *cifs_small_buf_get(void); extern void cifs_small_buf_release(void *); extern void free_rsp_buf(int, void *); -extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *, - unsigned int /* length */); extern int smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *msg, size_t *sent); @@ -562,11 +560,6 @@ extern void tconInfoFree(struct cifs_tcon *tcon, enum = smb3_tcon_ref_trace trace) =20 extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *s= erver, __u32 *pexpected_response_sequence_number); -int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *se= rver, - __u32 *pexpected_response_sequence); -int cifs_sign_smb(struct smb_hdr *cifs_pdu, unsigned int pdu_len, - struct TCP_Server_Info *server, - __u32 *pexpected_response_sequence_number); int cifs_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, __u32 expected_sequence_number); diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c index 1a28d361b1f7..22615890f35c 100644 --- a/fs/smb/client/cifstransport.c +++ b/fs/smb/client/cifstransport.c @@ -70,22 +70,6 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_S= erver_Info *server) return temp; } =20 -int -smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, - unsigned int smb_buf_length) -{ - struct kvec iov[1] =3D { - [0].iov_base =3D smb_buffer, - [0].iov_len =3D smb_buf_length, - }; - struct smb_rqst rqst =3D { - .rq_iov =3D iov, - .rq_nvec =3D ARRAY_SIZE(iov), - }; - - return __smb_send_rqst(server, 1, &rqst); -} - static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf, struct mid_q_entry **ppmidQ) { @@ -369,7 +353,7 @@ int SendReceiveBlockingLock(const unsigned int xid, str= uct cifs_tcon *tcon, return rc; } =20 - rc =3D cifs_sign_smb(in_buf, in_len, server, &mid->sequence_number); + rc =3D cifs_sign_rqst(&rqst, server, &mid->sequence_number); if (rc) { delete_mid(mid); cifs_server_unlock(server); @@ -377,7 +361,7 @@ int SendReceiveBlockingLock(const unsigned int xid, str= uct cifs_tcon *tcon, } =20 mid->mid_state =3D MID_REQUEST_SUBMITTED; - rc =3D smb_send(server, in_buf, in_len); + rc =3D __smb_send_rqst(server, 1, &rqst); cifs_save_when_sent(mid); =20 if (rc < 0) diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index bb5b0438a300..f4f74a447c97 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -32,17 +32,21 @@ static int send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst, struct mid_q_entry *mid) { - int rc =3D 0; struct smb_hdr *in_buf =3D (struct smb_hdr *)rqst->rq_iov[0].iov_base; - unsigned int in_len =3D rqst->rq_iov[0].iov_len; + struct kvec iov[1]; + struct smb_rqst crqst =3D { .rq_iov =3D iov, .rq_nvec =3D 1 }; + int rc =3D 0; =20 /* +2 for BCC field */ in_buf->Command =3D SMB_COM_NT_CANCEL; in_buf->WordCount =3D 0; put_bcc(0, in_buf); =20 + iov[0].iov_base =3D in_buf; + iov[0].iov_len =3D sizeof(struct smb_hdr) + 2; + cifs_server_lock(server); - rc =3D cifs_sign_smb(in_buf, in_len, server, &mid->sequence_number); + rc =3D cifs_sign_rqst(&crqst, server, &mid->sequence_number); if (rc) { cifs_server_unlock(server); return rc; @@ -54,7 +58,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb= _rqst *rqst, * after signing here. */ --server->sequence_number; - rc =3D smb_send(server, in_buf, in_len); + rc =3D __smb_send_rqst(server, 1, &crqst); if (rc < 0) server->sequence_number--; =20 diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index 0401d3eb9370..07716a61564a 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -994,6 +994,9 @@ compound_send_recv(const unsigned int xid, struct cifs_= ses *ses, if ((ses->ses_status =3D=3D SES_NEW) || (optype & CIFS_NEG_OP) || (optype= & CIFS_SESS_OP)) { spin_unlock(&ses->ses_lock); =20 + if (WARN_ON_ONCE(num_rqst !=3D 1 || !resp_iov)) + return -EINVAL; + cifs_server_lock(server); smb311_update_preauth_hash(ses, server, rqst[0].rq_iov, rqst[0].rq_nvec); cifs_server_unlock(server); @@ -1041,22 +1044,23 @@ compound_send_recv(const unsigned int xid, struct c= ifs_ses *ses, goto out; } =20 - buf =3D (char *)mid[i]->resp_buf; - resp_iov[i].iov_base =3D buf; - resp_iov[i].iov_len =3D mid[i]->resp_buf_size; - - if (mid[i]->large_buf) - resp_buf_type[i] =3D CIFS_LARGE_BUFFER; - else - resp_buf_type[i] =3D CIFS_SMALL_BUFFER; - rc =3D server->ops->check_receive(mid[i], server, - flags & CIFS_LOG_ERROR); + flags & CIFS_LOG_ERROR); + + if (resp_iov) { + buf =3D (char *)mid[i]->resp_buf; + resp_iov[i].iov_base =3D buf; + resp_iov[i].iov_len =3D mid[i]->resp_buf_size; =20 - /* mark it so buf will not be freed by delete_mid */ - if ((flags & CIFS_NO_RSP_BUF) =3D=3D 0) - mid[i]->resp_buf =3D NULL; + if (mid[i]->large_buf) + resp_buf_type[i] =3D CIFS_LARGE_BUFFER; + else + resp_buf_type[i] =3D CIFS_SMALL_BUFFER; =20 + /* mark it so buf will not be freed by delete_mid */ + if ((flags & CIFS_NO_RSP_BUF) =3D=3D 0) + mid[i]->resp_buf =3D NULL; + } } =20 /* From nobody Tue Dec 2 00:25:46 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C35022BE03C for ; Mon, 1 Dec 2025 22:57:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629883; cv=none; b=G/6eofcixmfmNYF1DQtJ5HzcS8f/UIQyeEUe51Qwy19flgr+Kg0/dYC/vmTQwtuhqctnzaGKfgJDaMtszbpUZmw6rNEXGG3ZLT4MQNKQKfW+0zVVsrUnBik9orTfioLDKN6NGNJseQGGS0t32ZYoQpPPye8F0a2C4M51o6JqySY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629883; c=relaxed/simple; bh=9shAie4sAr/f0+tftu7KlEkBaGCw1PtPge1VApeTn+0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RO5BdZBYy6QocoByRDxVtYzAw7mgUFB0BJN2rFnMEobXZGYAsL2ai7lphv0TIRwXCVxmrwgErTaVMluhBTrp7hZ3OiwT1rRPL3ywz4JVSfq2x/OLkUygV5tWUjVyS/RaxuTwWao4OmBDAPCEak5zmhuzmVy7VNtenBWYew5esUw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Fz0CUs2N; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Fz0CUs2N" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764629879; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Rl7ZBpYYdxoohEAIQbl6ngCtBsso8Yp4hKTKq4KsxRs=; b=Fz0CUs2NLTvf2LZhCpjWH2ano0LBBWcySnGKXgXNet2T6dghdaUNoM0uysV0pGS2/sbsux w4amZHLFvOitNMvAk4ZAVadIjPH6H+gF1v3UK/t0r6MysAVzWCLM/od62/re11WsARVC09 nlzPisF8leKj+r18rJYL1ZrHGL0umuU= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-481-BO7hjacKPwa5Xq_ujMZlOA-1; Mon, 01 Dec 2025 17:57:57 -0500 X-MC-Unique: BO7hjacKPwa5Xq_ujMZlOA-1 X-Mimecast-MFC-AGG-ID: BO7hjacKPwa5Xq_ujMZlOA_1764629876 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2C7CB1800673; Mon, 1 Dec 2025 22:57:56 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.14]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A58BA195608E; Mon, 1 Dec 2025 22:57:53 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Stefan Metzmacher , Tom Talpey , linux-cifs@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 4/9] cifs: Replace SendReceiveBlockingLock() with SendReceive() plus flags Date: Mon, 1 Dec 2025 22:57:25 +0000 Message-ID: <20251201225732.1520128-5-dhowells@redhat.com> In-Reply-To: <20251201225732.1520128-1-dhowells@redhat.com> References: <20251201225732.1520128-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Content-Type: text/plain; charset="utf-8" Replace the smb1 transport's SendReceiveBlockingLock() with SendReceive() plus a couple of flags. This will then allow that to pick up the transport changes there. The first flag, CIFS_INTERRUPTIBLE_WAIT, is added to indicate that the wait should be interruptible and the second, CIFS_WINDOWS_LOCK, indicates that we need to send a Lock command with unlock type rather than a Cancel. send_lock_cancel() is then called from cifs_lock_cancel() which is called from the main transport loop in compound_send_recv(). [!] I *think* the error code handling is probably right. Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: Shyam Prasad N cc: Tom Talpey cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org --- fs/smb/client/cifsglob.h | 8 +- fs/smb/client/cifsproto.h | 10 +- fs/smb/client/cifssmb.c | 18 +-- fs/smb/client/cifstransport.c | 199 +--------------------------------- fs/smb/client/smb1ops.c | 47 +++++++- fs/smb/client/transport.c | 13 ++- 6 files changed, 79 insertions(+), 216 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 1255e43a4d82..1bfaf9b71f07 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -311,8 +311,9 @@ struct cifs_open_parms; struct cifs_credits; =20 struct smb_version_operations { - int (*send_cancel)(struct TCP_Server_Info *, struct smb_rqst *, - struct mid_q_entry *); + int (*send_cancel)(struct cifs_ses *ses, struct TCP_Server_Info *server, + struct smb_rqst *rqst, struct mid_q_entry *mid, + unsigned int xid); bool (*compare_fids)(struct cifsFileInfo *, struct cifsFileInfo *); /* setup request: allocate mid, sign message */ struct mid_q_entry *(*setup_request)(struct cifs_ses *, @@ -1689,6 +1690,7 @@ struct mid_q_entry { __u16 credits_received; /* number of credits from the response */ __u32 pid; /* process id */ __u32 sequence_number; /* for CIFS signing */ + unsigned int sr_flags; /* Flags passed to send_recv() */ unsigned long when_alloc; /* when mid was created */ #ifdef CONFIG_CIFS_STATS2 unsigned long when_sent; /* time when smb send finished */ @@ -1900,6 +1902,8 @@ enum cifs_writable_file_flags { #define CIFS_TRANSFORM_REQ 0x0800 /* transform request before sendi= ng */ #define CIFS_NO_SRV_RSP 0x1000 /* there is no server response */ #define CIFS_COMPRESS_REQ 0x4000 /* compress request before sendin= g */ +#define CIFS_INTERRUPTIBLE_WAIT 0x8000 /* Interruptible wait (e.g. lock = request) */ +#define CIFS_WINDOWS_LOCK 0x10000 /* We're trying to get a Windows= lock */ =20 /* Security Flags: indicate type of session setup needed */ #define CIFSSEC_MAY_SIGN 0x00001 diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index 13e0367e0e10..c36beed87596 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -130,11 +130,12 @@ extern int cifs_wait_mtu_credits(struct TCP_Server_In= fo *server, struct cifs_credits *credits); =20 static inline int -send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst, - struct mid_q_entry *mid) +send_cancel(struct cifs_ses *ses, struct TCP_Server_Info *server, + struct smb_rqst *rqst, struct mid_q_entry *mid, + unsigned int xid) { return server->ops->send_cancel ? - server->ops->send_cancel(server, rqst, mid) : 0; + server->ops->send_cancel(ses, server, rqst, mid, xid) : 0; } =20 int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *= midQ); @@ -142,9 +143,6 @@ extern int SendReceive2(const unsigned int /* xid */ , = struct cifs_ses *, struct kvec *, int /* nvec to send */, int * /* type of buf returned */, const int flags, struct kvec * /* resp vec */); -int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, - struct smb_hdr *in_buf, unsigned int in_len, - struct smb_hdr *out_buf, int *pbytes_returned); =20 void smb2_query_server_interfaces(struct work_struct *work); void diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c index 645831708e1b..f260789a5831 100644 --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -2059,7 +2059,7 @@ CIFSSMBLock(const unsigned int xid, struct cifs_tcon = *tcon, /* LOCK_RSP *pSMBr =3D NULL; */ /* No response data other than rc to parse= */ unsigned int in_len; int bytes_returned; - int flags =3D 0; + int flags =3D CIFS_WINDOWS_LOCK | CIFS_INTERRUPTIBLE_WAIT; __u16 count; =20 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n", @@ -2104,8 +2104,9 @@ CIFSSMBLock(const unsigned int xid, struct cifs_tcon = *tcon, pSMB->ByteCount =3D cpu_to_le16(count); =20 if (waitFlag) - rc =3D SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, in_le= n, - (struct smb_hdr *) pSMB, &bytes_returned); + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, + (struct smb_hdr *) pSMB, &bytes_returned, + flags); else rc =3D SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, in_len, flags); cifs_small_buf_release(pSMB); @@ -2130,7 +2131,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_= tcon *tcon, struct cifs_posix_lock *parm_data; unsigned int in_len; int rc =3D 0; - int timeout =3D 0; + int sr_flags =3D CIFS_INTERRUPTIBLE_WAIT; int bytes_returned =3D 0; int resp_buf_type =3D 0; __u16 params, param_offset, offset, byte_count, count; @@ -2173,7 +2174,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_= tcon *tcon, =20 parm_data->lock_type =3D cpu_to_le16(lock_type); if (waitFlag) { - timeout =3D CIFS_BLOCKING_OP; /* blocking operation, no timeout */ + sr_flags |=3D CIFS_BLOCKING_OP; /* blocking operation, no timeout */ parm_data->lock_flags =3D cpu_to_le16(1); pSMB->Timeout =3D cpu_to_le32(-1); } else @@ -2190,13 +2191,14 @@ CIFSSMBPosixLock(const unsigned int xid, struct cif= s_tcon *tcon, in_len +=3D byte_count; pSMB->ByteCount =3D cpu_to_le16(byte_count); if (waitFlag) { - rc =3D SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, in_le= n, - (struct smb_hdr *) pSMBr, &bytes_returned); + rc =3D SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len, + (struct smb_hdr *) pSMBr, &bytes_returned, + sr_flags); } else { iov[0].iov_base =3D (char *)pSMB; iov[0].iov_len =3D in_len; rc =3D SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, - &resp_buf_type, timeout, &rsp_iov); + &resp_buf_type, sr_flags, &rsp_iov); pSMBr =3D (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base; } cifs_small_buf_release(pSMB); diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c index 22615890f35c..08e5a5f0103e 100644 --- a/fs/smb/client/cifstransport.c +++ b/fs/smb/client/cifstransport.c @@ -239,13 +239,6 @@ SendReceive(const unsigned int xid, struct cifs_ses *s= es, return -EIO; } =20 - spin_lock(&server->srv_lock); - if (server->tcpStatus =3D=3D CifsExiting) { - spin_unlock(&server->srv_lock); - return -ENOENT; - } - spin_unlock(&server->srv_lock); - /* Ensure that we do not send more than 50 overlapping requests to the same server. We may make this configurable later or use ses->maxReq */ @@ -261,193 +254,11 @@ SendReceive(const unsigned int xid, struct cifs_ses = *ses, if (rc < 0) return rc; =20 - *pbytes_returned =3D resp_iov.iov_len; - if (resp_iov.iov_len) - memcpy(out_buf, resp_iov.iov_base, resp_iov.iov_len); - free_rsp_buf(resp_buf_type, resp_iov.iov_base); - return rc; -} - -/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows - blocking lock to return. */ - -static int -send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon, - struct smb_hdr *in_buf, unsigned int in_len, - struct smb_hdr *out_buf) -{ - int bytes_returned; - struct cifs_ses *ses =3D tcon->ses; - LOCK_REQ *pSMB =3D (LOCK_REQ *)in_buf; - - /* We just modify the current in_buf to change - the type of lock from LOCKING_ANDX_SHARED_LOCK - or LOCKING_ANDX_EXCLUSIVE_LOCK to - LOCKING_ANDX_CANCEL_LOCK. */ - - pSMB->LockType =3D LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES; - pSMB->Timeout =3D 0; - pSMB->hdr.Mid =3D get_next_mid(ses->server); - - return SendReceive(xid, ses, in_buf, in_len, out_buf, - &bytes_returned, 0); -} - -int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, - struct smb_hdr *in_buf, unsigned int in_len, - struct smb_hdr *out_buf, int *pbytes_returned) -{ - int rc =3D 0; - int rstart =3D 0; - struct mid_q_entry *mid; - struct cifs_ses *ses; - struct kvec iov =3D { .iov_base =3D in_buf, .iov_len =3D in_len }; - struct smb_rqst rqst =3D { .rq_iov =3D &iov, .rq_nvec =3D 1 }; - unsigned int instance; - struct TCP_Server_Info *server; - - if (WARN_ON_ONCE(in_len > 0xffffff)) - return -EIO; - if (tcon =3D=3D NULL || tcon->ses =3D=3D NULL) { - cifs_dbg(VFS, "Null smb session\n"); - return -EIO; - } - ses =3D tcon->ses; - server =3D ses->server; - - if (server =3D=3D NULL) { - cifs_dbg(VFS, "Null tcp session\n"); - return -EIO; - } - - spin_lock(&server->srv_lock); - if (server->tcpStatus =3D=3D CifsExiting) { - spin_unlock(&server->srv_lock); - return -ENOENT; - } - spin_unlock(&server->srv_lock); - - /* Ensure that we do not send more than 50 overlapping requests - to the same server. We may make this configurable later or - use ses->maxReq */ - - if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { - cifs_tcon_dbg(VFS, "Invalid length, greater than maximum frame, %d\n", - in_len); - return -EIO; - } - - rc =3D wait_for_free_request(server, CIFS_BLOCKING_OP, &instance); - if (rc) - return rc; - - /* make sure that we sign in the same order that we send on this socket - and avoid races inside tcp sendmsg code that could cause corruption - of smb data */ - - cifs_server_lock(server); - - rc =3D allocate_mid(ses, in_buf, &mid); - if (rc) { - cifs_server_unlock(server); - return rc; - } - - rc =3D cifs_sign_rqst(&rqst, server, &mid->sequence_number); - if (rc) { - delete_mid(mid); - cifs_server_unlock(server); - return rc; - } - - mid->mid_state =3D MID_REQUEST_SUBMITTED; - rc =3D __smb_send_rqst(server, 1, &rqst); - cifs_save_when_sent(mid); - - if (rc < 0) - server->sequence_number -=3D 2; - - cifs_server_unlock(server); - - if (rc < 0) { - delete_mid(mid); - return rc; - } - - /* Wait for a reply - allow signals to interrupt. */ - rc =3D wait_event_interruptible(server->response_q, - (!(mid->mid_state =3D=3D MID_REQUEST_SUBMITTED || - mid->mid_state =3D=3D MID_RESPONSE_RECEIVED)) || - ((server->tcpStatus !=3D CifsGood) && - (server->tcpStatus !=3D CifsNew))); - - /* Were we interrupted by a signal ? */ - spin_lock(&server->srv_lock); - if ((rc =3D=3D -ERESTARTSYS) && - (mid->mid_state =3D=3D MID_REQUEST_SUBMITTED || - mid->mid_state =3D=3D MID_RESPONSE_RECEIVED) && - ((server->tcpStatus =3D=3D CifsGood) || - (server->tcpStatus =3D=3D CifsNew))) { - spin_unlock(&server->srv_lock); - - if (in_buf->Command =3D=3D SMB_COM_TRANSACTION2) { - /* POSIX lock. We send a NT_CANCEL SMB to cause the - blocking lock to return. */ - rc =3D send_cancel(server, &rqst, mid); - if (rc) { - delete_mid(mid); - return rc; - } - } else { - /* Windows lock. We send a LOCKINGX_CANCEL_LOCK - to cause the blocking lock to return. */ - - rc =3D send_lock_cancel(xid, tcon, in_buf, in_len, out_buf); - - /* If we get -ENOLCK back the lock may have - already been removed. Don't exit in this case. */ - if (rc && rc !=3D -ENOLCK) { - delete_mid(mid); - return rc; - } - } - - rc =3D wait_for_response(server, mid); - if (rc) { - send_cancel(server, &rqst, mid); - spin_lock(&mid->mid_lock); - if (mid->callback) { - /* no longer considered to be "in-flight" */ - mid->callback =3D release_mid; - spin_unlock(&mid->mid_lock); - return rc; - } - spin_unlock(&mid->mid_lock); - } - - /* We got the response - restart system call. */ - rstart =3D 1; - spin_lock(&server->srv_lock); - } - spin_unlock(&server->srv_lock); - - rc =3D cifs_sync_mid_result(mid, server); - if (rc !=3D 0) - return rc; - - /* rcvd frame is ok */ - if (out_buf =3D=3D NULL || mid->mid_state !=3D MID_RESPONSE_READY) { - rc =3D -EIO; - cifs_tcon_dbg(VFS, "Bad MID state?\n"); - goto out; + if (out_buf) { + *pbytes_returned =3D resp_iov.iov_len; + if (resp_iov.iov_len) + memcpy(out_buf, resp_iov.iov_base, resp_iov.iov_len); } - - *pbytes_returned =3D mid->response_pdu_len; - memcpy(out_buf, mid->resp_buf, *pbytes_returned); - rc =3D cifs_check_receive(mid, server, 0); -out: - delete_mid(mid); - if (rstart && rc =3D=3D -EACCES) - return -ERESTARTSYS; + free_rsp_buf(resp_buf_type, resp_iov.iov_base); return rc; } diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index f4f74a447c97..45af69d95b27 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -29,8 +29,9 @@ * SMB_COM_NT_CANCEL request and then sends it. */ static int -send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst, - struct mid_q_entry *mid) +send_nt_cancel(struct cifs_ses *ses, struct TCP_Server_Info *server, + struct smb_rqst *rqst, struct mid_q_entry *mid, + unsigned int xid) { struct smb_hdr *in_buf =3D (struct smb_hdr *)rqst->rq_iov[0].iov_base; struct kvec iov[1]; @@ -70,6 +71,46 @@ send_nt_cancel(struct TCP_Server_Info *server, struct sm= b_rqst *rqst, return rc; } =20 +/* + * Send a LOCKINGX_CANCEL_LOCK to cause the Windows blocking lock to + * return. + */ +static int +send_lock_cancel(struct cifs_ses *ses, struct TCP_Server_Info *server, + struct smb_rqst *rqst, struct mid_q_entry *mid, + unsigned int xid) +{ + struct smb_hdr *in_buf =3D (struct smb_hdr *)rqst->rq_iov[0].iov_base; + unsigned int in_len =3D rqst->rq_iov[0].iov_len; + LOCK_REQ *pSMB =3D (LOCK_REQ *)in_buf; + int rc; + + /* We just modify the current in_buf to change + * the type of lock from LOCKING_ANDX_SHARED_LOCK + * or LOCKING_ANDX_EXCLUSIVE_LOCK to + * LOCKING_ANDX_CANCEL_LOCK. + */ + pSMB->LockType =3D LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES; + pSMB->Timeout =3D 0; + pSMB->hdr.Mid =3D get_next_mid(ses->server); + + rc =3D SendReceive(xid, ses, in_buf, in_len, NULL, NULL, 0); + if (rc =3D=3D -ENOLCK) + rc =3D 0; /* If we get back -ENOLCK, it probably means we managed + * to cancel the lock command before it took effect. + */ + return rc; +} + +static int cifs_send_cancel(struct cifs_ses *ses, struct TCP_Server_Info *= server, + struct smb_rqst *rqst, struct mid_q_entry *mid, + unsigned int xid) +{ + if (mid->sr_flags & CIFS_WINDOWS_LOCK) + return send_lock_cancel(ses, server, rqst, mid, xid); + return send_nt_cancel(ses, server, rqst, mid, xid); +} + static bool cifs_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2) { @@ -1396,7 +1437,7 @@ cifs_is_network_name_deleted(char *buf, struct TCP_Se= rver_Info *server) } =20 struct smb_version_operations smb1_operations =3D { - .send_cancel =3D send_nt_cancel, + .send_cancel =3D cifs_send_cancel, .compare_fids =3D cifs_compare_fids, .setup_request =3D cifs_setup_request, .setup_async_request =3D cifs_setup_async_request, diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index 07716a61564a..ea5f9e4171a9 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -642,12 +642,16 @@ cifs_wait_mtu_credits(struct TCP_Server_Info *server,= size_t size, =20 int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *= mid) { + unsigned int sleep_state =3D TASK_KILLABLE; int error; =20 + if (mid->sr_flags & CIFS_INTERRUPTIBLE_WAIT) + sleep_state =3D TASK_INTERRUPTIBLE; + error =3D wait_event_state(server->response_q, mid->mid_state !=3D MID_REQUEST_SUBMITTED && mid->mid_state !=3D MID_RESPONSE_RECEIVED, - (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE)); + (sleep_state | TASK_FREEZABLE_UNSAFE)); if (error < 0) return -ERESTARTSYS; =20 @@ -701,6 +705,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct = smb_rqst *rqst, return PTR_ERR(mid); } =20 + mid->sr_flags =3D flags; mid->receive =3D receive; mid->callback =3D callback; mid->callback_data =3D cbdata; @@ -945,6 +950,7 @@ compound_send_recv(const unsigned int xid, struct cifs_= ses *ses, return PTR_ERR(mid[i]); } =20 + mid[i]->sr_flags =3D flags; mid[i]->mid_state =3D MID_REQUEST_SUBMITTED; mid[i]->optype =3D optype; /* @@ -1014,10 +1020,11 @@ compound_send_recv(const unsigned int xid, struct c= ifs_ses *ses, for (; i < num_rqst; i++) { cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n", mid[i]->mid, le16_to_cpu(mid[i]->command)); - send_cancel(server, &rqst[i], mid[i]); + send_cancel(ses, server, &rqst[i], mid[i], xid); spin_lock(&mid[i]->mid_lock); mid[i]->wait_cancelled =3D true; - if (mid[i]->callback) { + if (mid[i]->mid_state =3D=3D MID_REQUEST_SUBMITTED || + mid[i]->mid_state =3D=3D MID_RESPONSE_RECEIVED) { mid[i]->callback =3D cifs_cancelled_callback; cancelled_mid[i] =3D true; credits[i].value =3D 0; From nobody Tue Dec 2 00:25:46 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DEFFB2C028B for ; Mon, 1 Dec 2025 22:58:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629885; cv=none; b=PPMiYGCmhT1S5t7EIp8eUHXolcBn3LFQccCVQpB2XsZqS+T+R1H7Y78brC2aXnU8JQwxQvvSTtZNEs0mik1BJ+TtBfakcsyHoUCo5IavUwfxrIr9PoCiPhyduoTS/Qt2menBT/+uR9k1Ngp9XrLE4Z8Ap7ot851Dz5hosSg1yLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629885; c=relaxed/simple; bh=tvUt2hjjrDVeeNltwHLey+XPanB6WwnjLvVsOMpkB+Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ISJvCgYihJfXwcpd3R3fGE3sSvSocTdw/X2HencOsQ1g8Es8ZNHIco6zHGf/cwjruRPMGFwx1gLdWh3zfM20JfnTSrK000MQO2Ko+NKMYIMWsmDTdismn/9V0E8wdnIkw/sREUVQ7WKV1KC2OejY7bFGrHtzxtZjol7NzqkVeaA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=gYBchT90; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="gYBchT90" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764629882; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=A/A/h7yv3X7tua8wAh2BlUckBWYTc4Q1PylD0wwVZ6c=; b=gYBchT90tktyjg48NR+MbjdRREgEv6alDRi0+TT31swZal9Ge6uQbLBnXlKvPlE2RTR4NL bArmqzQm3gi4dAj9ySL9XoaG6Yr1zcqWQfm3vYjKH84fr5DuxVsSwtArouLJy8c3Z4wNBv VftSOQ63gVGF4GGwCDZ9H3PprMNA4xc= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-612-E5DZHxxPORu_1APqm4ROoQ-1; Mon, 01 Dec 2025 17:58:01 -0500 X-MC-Unique: E5DZHxxPORu_1APqm4ROoQ-1 X-Mimecast-MFC-AGG-ID: E5DZHxxPORu_1APqm4ROoQ_1764629880 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3E2D01800447; Mon, 1 Dec 2025 22:58:00 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.14]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9166019560B2; Mon, 1 Dec 2025 22:57:57 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Stefan Metzmacher , Tom Talpey , linux-cifs@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 5/9] cifs: Fix specification of function pointers Date: Mon, 1 Dec 2025 22:57:26 +0000 Message-ID: <20251201225732.1520128-6-dhowells@redhat.com> In-Reply-To: <20251201225732.1520128-1-dhowells@redhat.com> References: <20251201225732.1520128-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Change the mid_receive_t, mid_callback_t and mid_handle_t function pointers to have the pointer marker in the typedef. Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: linux-cifs@vger.kernel.org --- fs/smb/client/cifsglob.h | 12 ++++++------ fs/smb/client/cifsproto.h | 8 ++++---- fs/smb/client/transport.c | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 1bfaf9b71f07..18ac91d0982d 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -1660,7 +1660,7 @@ static inline void cifs_stats_bytes_read(struct cifs_= tcon *tcon, * Returns zero on a successful receive, or an error. The receive state in * the TCP_Server_Info will also be updated. */ -typedef int (mid_receive_t)(struct TCP_Server_Info *server, +typedef int (*mid_receive_t)(struct TCP_Server_Info *server, struct mid_q_entry *mid); =20 /* @@ -1671,13 +1671,13 @@ typedef int (mid_receive_t)(struct TCP_Server_Info = *server, * - it will be called by cifsd, with no locks held * - the mid will be removed from any lists */ -typedef void (mid_callback_t)(struct mid_q_entry *mid); +typedef void (*mid_callback_t)(struct mid_q_entry *mid); =20 /* * This is the protopyte for mid handle function. This is called once the = mid * has been recognized after decryption of the message. */ -typedef int (mid_handle_t)(struct TCP_Server_Info *server, +typedef int (*mid_handle_t)(struct TCP_Server_Info *server, struct mid_q_entry *mid); =20 /* one of these for every pending CIFS request to the server */ @@ -1696,9 +1696,9 @@ struct mid_q_entry { unsigned long when_sent; /* time when smb send finished */ unsigned long when_received; /* when demux complete (taken off wire) */ #endif - mid_receive_t *receive; /* call receive callback */ - mid_callback_t *callback; /* call completion callback */ - mid_handle_t *handle; /* call handle mid callback */ + mid_receive_t receive; /* call receive callback */ + mid_callback_t callback; /* call completion callback */ + mid_handle_t handle; /* call handle mid callback */ void *callback_data; /* general purpose pointer for callback */ struct task_struct *creator; void *resp_buf; /* pointer to received SMB header */ diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index c36beed87596..9a307c9c8c56 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -95,10 +95,10 @@ extern int cifs_ipaddr_cmp(struct sockaddr *srcaddr, st= ruct sockaddr *rhs); extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *r= hs); extern int cifs_discard_remaining_data(struct TCP_Server_Info *server); extern int cifs_call_async(struct TCP_Server_Info *server, - struct smb_rqst *rqst, - mid_receive_t *receive, mid_callback_t *callback, - mid_handle_t *handle, void *cbdata, const int flags, - const struct cifs_credits *exist_credits); + struct smb_rqst *rqst, + mid_receive_t receive, mid_callback_t callback, + mid_handle_t handle, void *cbdata, const int flags, + const struct cifs_credits *exist_credits); extern struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses); extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, struct TCP_Server_Info *server, diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index ea5f9e4171a9..6077eaf73df6 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -664,8 +664,8 @@ int wait_for_response(struct TCP_Server_Info *server, s= truct mid_q_entry *mid) */ int cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, - mid_receive_t *receive, mid_callback_t *callback, - mid_handle_t *handle, void *cbdata, const int flags, + mid_receive_t receive, mid_callback_t callback, + mid_handle_t handle, void *cbdata, const int flags, const struct cifs_credits *exist_credits) { int rc; From nobody Tue Dec 2 00:25:46 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A59462D0615 for ; Mon, 1 Dec 2025 22:58:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629894; cv=none; b=kEJrm2BIJeXZnmkq4DH4z8kMK1Tkh80amP4pLIM72Ik6ZOJzNxpZaoL1KZR1TAVA/lTh7yrqK1If/eOnIacOaDXpbjTeyuFYUvzSbD02aSnVhi7GcWEujGZCLoKKLcoGr9/q6jSORz0BS0BK2VnD7I4DX6wbO7W8s40mQ2+W5iY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629894; c=relaxed/simple; bh=ww7Y+4ci+YtAD5oSLu6aJ7Z98wwrhb62fJiwXPIfRvU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=koobLDq8lbVh21pgqsLn4mqk4tyUbRV6B+y1Ue7cXjieLuRDPk1l7gRboVLdA+hcLK62sDhQi7LwNdQkMGTd0CqQhGPMRSAM8GmmatVV2le2AOfE4e7Y7yK+C+KzYR5ySl8mnlwAOXyy6dWPvm4maythICKT5GplBOdb3TxyRd0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=NJC1r8H8; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="NJC1r8H8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764629890; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IK8XnacOBIfX/7TLT+Bj4AH8WmJ9K2ndRKm33ZDlOxs=; b=NJC1r8H8KKLd/kRfIxvrJ0m0B17zjBAie8uu0vQKqVrFyEurdu+JzG+4XSW519G4u21ZMZ Eu+UEukpbRoAMkWetOZvCPGn65RGIG0G4YBE6tyxIhv2sVr8gj8WNNGDBsqY9IQ0oO3+By +24j8SGvpakO7gzVLBJuAb9Y9Ql2GIw= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-541-3sSD0racOaOTCJEj7zn2IQ-1; Mon, 01 Dec 2025 17:58:06 -0500 X-MC-Unique: 3sSD0racOaOTCJEj7zn2IQ-1 X-Mimecast-MFC-AGG-ID: 3sSD0racOaOTCJEj7zn2IQ_1764629884 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 99DA01956053; Mon, 1 Dec 2025 22:58:04 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.14]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id C463D195608E; Mon, 1 Dec 2025 22:58:01 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Stefan Metzmacher , Tom Talpey , linux-cifs@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 6/9] cifs: Remove the server pointer from smb_message Date: Mon, 1 Dec 2025 22:57:27 +0000 Message-ID: <20251201225732.1520128-7-dhowells@redhat.com> In-Reply-To: <20251201225732.1520128-1-dhowells@redhat.com> References: <20251201225732.1520128-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Content-Type: text/plain; charset="utf-8" Remove the server pointer from smb_message and instead pass it down to all the things that access it. Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: Shyam Prasad N cc: Tom Talpey (RDMA, smbdirect) cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org --- fs/smb/client/cifsfs.c | 7 +++-- fs/smb/client/cifsglob.h | 14 +++++----- fs/smb/client/cifsproto.h | 21 ++++++++++----- fs/smb/client/cifssmb.c | 15 +++++------ fs/smb/client/cifstransport.c | 15 +++++------ fs/smb/client/connect.c | 34 ++++++++++++------------ fs/smb/client/netmisc.c | 5 ++-- fs/smb/client/smb1ops.c | 4 +-- fs/smb/client/smb2ops.c | 22 ++++++++-------- fs/smb/client/smb2pdu.c | 26 ++++++++----------- fs/smb/client/smb2transport.c | 9 +++---- fs/smb/client/transport.c | 49 ++++++++++++++++------------------- 12 files changed, 108 insertions(+), 113 deletions(-) diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 185ac41bd7e9..44d3dec9743b 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -442,7 +442,7 @@ static struct kmem_cache *cifs_io_request_cachep; static struct kmem_cache *cifs_io_subrequest_cachep; mempool_t *cifs_sm_req_poolp; mempool_t *cifs_req_poolp; -mempool_t *cifs_mid_poolp; +mempool_t cifs_mid_pool; mempool_t cifs_io_request_pool; mempool_t cifs_io_subrequest_pool; =20 @@ -1844,8 +1844,7 @@ static int init_mids(void) return -ENOMEM; =20 /* 3 is a reasonable minimum number of simultaneous operations */ - cifs_mid_poolp =3D mempool_create_slab_pool(3, cifs_mid_cachep); - if (cifs_mid_poolp =3D=3D NULL) { + if (mempool_init_slab_pool(&cifs_mid_pool, 3, cifs_mid_cachep) < 0) { kmem_cache_destroy(cifs_mid_cachep); return -ENOMEM; } @@ -1855,7 +1854,7 @@ static int init_mids(void) =20 static void destroy_mids(void) { - mempool_destroy(cifs_mid_poolp); + mempool_exit(&cifs_mid_pool); kmem_cache_destroy(cifs_mid_cachep); } =20 diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 18ac91d0982d..1f93c309dfe8 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -1671,7 +1671,7 @@ typedef int (*mid_receive_t)(struct TCP_Server_Info *= server, * - it will be called by cifsd, with no locks held * - the mid will be removed from any lists */ -typedef void (*mid_callback_t)(struct mid_q_entry *mid); +typedef void (*mid_callback_t)(struct TCP_Server_Info *srv, struct mid_q_e= ntry *mid); =20 /* * This is the protopyte for mid handle function. This is called once the = mid @@ -1683,8 +1683,7 @@ typedef int (*mid_handle_t)(struct TCP_Server_Info *s= erver, /* one of these for every pending CIFS request to the server */ struct mid_q_entry { struct list_head qhead; /* mids waiting on reply from this server */ - struct kref refcount; - struct TCP_Server_Info *server; /* server corresponding to this mid */ + refcount_t refcount; __u64 mid; /* multiplex id */ __u16 credits; /* number of credits consumed by this mid */ __u16 credits_received; /* number of credits from the response */ @@ -2109,7 +2108,7 @@ extern __u32 cifs_lock_secret; =20 extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; -extern mempool_t *cifs_mid_poolp; +extern mempool_t cifs_mid_pool; extern mempool_t cifs_io_request_pool; extern mempool_t cifs_io_subrequest_pool; =20 @@ -2356,9 +2355,10 @@ static inline bool cifs_netbios_name(const char *nam= e, size_t namelen) * Execute mid callback atomically - ensures callback runs exactly once * and prevents sleeping in atomic context. */ -static inline void mid_execute_callback(struct mid_q_entry *mid) +static inline void mid_execute_callback(struct TCP_Server_Info *server, + struct mid_q_entry *mid) { - void (*callback)(struct mid_q_entry *mid); + mid_callback_t callback; =20 spin_lock(&mid->mid_lock); callback =3D mid->callback; @@ -2366,7 +2366,7 @@ static inline void mid_execute_callback(struct mid_q_= entry *mid) spin_unlock(&mid->mid_lock); =20 if (callback) - callback(mid); + callback(server, mid); } =20 #define CIFS_REPARSE_SUPPORT(tcon) \ diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index 9a307c9c8c56..d72d66dcb953 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -82,9 +82,9 @@ extern char *cifs_build_path_to_root(struct smb3_fs_conte= xt *ctx, int add_treename); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); char *cifs_build_devname(char *nodename, const char *prepath); -extern void delete_mid(struct mid_q_entry *mid); -void __release_mid(struct kref *refcount); -extern void cifs_wake_up_task(struct mid_q_entry *mid); +void delete_mid(struct TCP_Server_Info *server, struct mid_q_entry *mid); +void __release_mid(struct TCP_Server_Info *server, struct mid_q_entry *mid= ); +void cifs_wake_up_task(struct TCP_Server_Info *server, struct mid_q_entry = *mid); extern int cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid); extern char *smb3_fs_context_fullpath(const struct smb3_fs_context *ctx, @@ -180,7 +180,8 @@ extern int decode_negTokenInit(unsigned char *security_= blob, int length, extern int cifs_convert_address(struct sockaddr *dst, const char *src, int= len); extern void cifs_set_port(struct sockaddr *addr, const unsigned short int = port); extern int map_smb_to_linux_error(char *buf, bool logErr); -extern int map_and_check_smb_error(struct mid_q_entry *mid, bool logErr); +extern int map_and_check_smb_error(struct TCP_Server_Info *server, + struct mid_q_entry *mid, bool logErr); unsigned int header_assemble(struct smb_hdr *buffer, char smb_command, const struct cifs_tcon *treeCon, int word_count /* length of fixed section word count in two byte units */); @@ -263,7 +264,7 @@ extern unsigned int setup_special_mode_ACE(struct smb_a= ce *pace, __u64 nmode); extern unsigned int setup_special_user_owner_ACE(struct smb_ace *pace); =20 -extern void dequeue_mid(struct mid_q_entry *mid, bool malformed); +void dequeue_mid(struct TCP_Server_Info *server, struct mid_q_entry *mid, = bool malformed); extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, unsigned int to_read); extern ssize_t cifs_discard_from_socket(struct TCP_Server_Info *server, @@ -767,9 +768,15 @@ static inline bool dfs_src_pathname_equal(const char *= s1, const char *s2) return true; } =20 -static inline void release_mid(struct mid_q_entry *mid) +static inline void smb_get_mid(struct mid_q_entry *mid) { - kref_put(&mid->refcount, __release_mid); + refcount_inc(&mid->refcount); +} + +static inline void release_mid(struct TCP_Server_Info *server, struct mid_= q_entry *mid) +{ + if (refcount_dec_and_test(&mid->refcount)) + __release_mid(server, mid); } =20 static inline void cifs_free_open_info(struct cifs_open_info_data *data) diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c index f260789a5831..071ec22b5e34 100644 --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -584,12 +584,11 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon = *tcon) * FIXME: maybe we should consider checking that the reply matches request? */ static void -cifs_echo_callback(struct mid_q_entry *mid) +cifs_echo_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid) { - struct TCP_Server_Info *server =3D mid->callback_data; struct cifs_credits credits =3D { .value =3D 1, .instance =3D 0 }; =20 - release_mid(mid); + release_mid(server, mid); add_credits(server, &credits, CIFS_ECHO_OP); } =20 @@ -1317,12 +1316,11 @@ CIFS_open(const unsigned int xid, struct cifs_open_= parms *oparms, int *oplock, } =20 static void -cifs_readv_callback(struct mid_q_entry *mid) +cifs_readv_callback(struct TCP_Server_Info *server, struct mid_q_entry *mi= d) { struct cifs_io_subrequest *rdata =3D mid->callback_data; struct netfs_inode *ictx =3D netfs_inode(rdata->rreq->inode); struct cifs_tcon *tcon =3D tlink_tcon(rdata->req->cfile->tlink); - struct TCP_Server_Info *server =3D tcon->ses->server; struct smb_rqst rqst =3D { .rq_iov =3D rdata->iov, .rq_nvec =3D 1, .rq_iter =3D rdata->subreq.io_iter }; @@ -1420,7 +1418,7 @@ cifs_readv_callback(struct mid_q_entry *mid) rdata->subreq.transferred +=3D rdata->got_bytes; trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress); netfs_read_subreq_terminated(&rdata->subreq); - release_mid(mid); + release_mid(server, mid); add_credits(server, &credits, 0); trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0, server->credits, server->in_flight, @@ -1736,10 +1734,9 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_= parms *io_parms, * workqueue completion task. */ static void -cifs_writev_callback(struct mid_q_entry *mid) +cifs_writev_callback(struct TCP_Server_Info *server, struct mid_q_entry *m= id) { struct cifs_io_subrequest *wdata =3D mid->callback_data; - struct TCP_Server_Info *server =3D wdata->server; struct cifs_tcon *tcon =3D tlink_tcon(wdata->req->cfile->tlink); WRITE_RSP *smb =3D (WRITE_RSP *)mid->resp_buf; struct cifs_credits credits =3D { @@ -1803,7 +1800,7 @@ cifs_writev_callback(struct mid_q_entry *mid) 0, cifs_trace_rw_credits_write_response_clear); wdata->credits.value =3D 0; cifs_write_subrequest_terminated(wdata, result); - release_mid(mid); + release_mid(server, mid); trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0, server->credits, server->in_flight, credits.value, cifs_trace_rw_credits_write_response_add); diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c index 08e5a5f0103e..87a246efe695 100644 --- a/fs/smb/client/cifstransport.c +++ b/fs/smb/client/cifstransport.c @@ -43,9 +43,9 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Se= rver_Info *server) return NULL; } =20 - temp =3D mempool_alloc(cifs_mid_poolp, GFP_NOFS); + temp =3D mempool_alloc(&cifs_mid_pool, GFP_NOFS); memset(temp, 0, sizeof(struct mid_q_entry)); - kref_init(&temp->refcount); + refcount_set(&temp->refcount, 1); spin_lock_init(&temp->mid_lock); temp->mid =3D get_mid(smb_buffer); temp->pid =3D current->pid; @@ -54,7 +54,6 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Se= rver_Info *server) /* easier to use jiffies */ /* when mid allocated can be before when sent */ temp->when_alloc =3D jiffies; - temp->server =3D server; =20 /* * The default is for the mid to be synchronous, so the @@ -119,7 +118,7 @@ cifs_setup_async_request(struct TCP_Server_Info *server= , struct smb_rqst *rqst) =20 rc =3D cifs_sign_rqst(rqst, server, &mid->sequence_number); if (rc) { - release_mid(mid); + release_mid(server, mid); return ERR_PTR(rc); } =20 @@ -179,11 +178,11 @@ cifs_check_receive(struct mid_q_entry *mid, struct TC= P_Server_Info *server, } =20 /* BB special case reconnect tid and uid here? */ - return map_and_check_smb_error(mid, log_error); + return map_and_check_smb_error(server, mid, log_error); } =20 struct mid_q_entry * -cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored, +cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server, struct smb_rqst *rqst) { int rc; @@ -193,9 +192,9 @@ cifs_setup_request(struct cifs_ses *ses, struct TCP_Ser= ver_Info *ignored, rc =3D allocate_mid(ses, hdr, &mid); if (rc) return ERR_PTR(rc); - rc =3D cifs_sign_rqst(rqst, ses->server, &mid->sequence_number); + rc =3D cifs_sign_rqst(rqst, server, &mid->sequence_number); if (rc) { - delete_mid(mid); + delete_mid(server, mid); return ERR_PTR(rc); } return mid; diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index d10fe1b11377..59f1affc4790 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -325,7 +325,7 @@ cifs_abort_connection(struct TCP_Server_Info *server) cifs_dbg(FYI, "%s: moving mids to private list\n", __func__); spin_lock(&server->mid_queue_lock); list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) { - kref_get(&mid->refcount); + smb_get_mid(mid); if (mid->mid_state =3D=3D MID_REQUEST_SUBMITTED) mid->mid_state =3D MID_RETRY_NEEDED; list_move(&mid->qhead, &retry_list); @@ -337,8 +337,8 @@ cifs_abort_connection(struct TCP_Server_Info *server) cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__); list_for_each_entry_safe(mid, nmid, &retry_list, qhead) { list_del_init(&mid->qhead); - mid_execute_callback(mid); - release_mid(mid); + mid_execute_callback(server, mid); + release_mid(server, mid); } } =20 @@ -882,7 +882,7 @@ is_smb_response(struct TCP_Server_Info *server, unsigne= d char type) */ spin_lock(&server->mid_queue_lock); list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) { - kref_get(&mid->refcount); + smb_get_mid(mid); list_move(&mid->qhead, &dispose_list); mid->deleted_from_q =3D true; } @@ -915,8 +915,8 @@ is_smb_response(struct TCP_Server_Info *server, unsigne= d char type) list_del_init(&mid->qhead); mid->mid_rc =3D mid_rc; mid->mid_state =3D MID_RC; - mid_execute_callback(mid); - release_mid(mid); + mid_execute_callback(server, mid); + release_mid(server, mid); } =20 /* @@ -948,12 +948,12 @@ is_smb_response(struct TCP_Server_Info *server, unsig= ned char type) } =20 void -dequeue_mid(struct mid_q_entry *mid, bool malformed) +dequeue_mid(struct TCP_Server_Info *server, struct mid_q_entry *mid, bool = malformed) { #ifdef CONFIG_CIFS_STATS2 mid->when_received =3D jiffies; #endif - spin_lock(&mid->server->mid_queue_lock); + spin_lock(&server->mid_queue_lock); if (!malformed) mid->mid_state =3D MID_RESPONSE_RECEIVED; else @@ -963,12 +963,12 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed) * function has finished processing it is a bug. */ if (mid->deleted_from_q =3D=3D true) { - spin_unlock(&mid->server->mid_queue_lock); + spin_unlock(&server->mid_queue_lock); pr_warn_once("trying to dequeue a deleted mid\n"); } else { list_del_init(&mid->qhead); mid->deleted_from_q =3D true; - spin_unlock(&mid->server->mid_queue_lock); + spin_unlock(&server->mid_queue_lock); } } =20 @@ -1004,7 +1004,7 @@ handle_mid(struct mid_q_entry *mid, struct TCP_Server= _Info *server, else server->smallbuf =3D NULL; } - dequeue_mid(mid, malformed); + dequeue_mid(server, mid, malformed); } =20 int @@ -1101,7 +1101,7 @@ clean_demultiplex_info(struct TCP_Server_Info *server) list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { mid_entry =3D list_entry(tmp, struct mid_q_entry, qhead); cifs_dbg(FYI, "Clearing mid %llu\n", mid_entry->mid); - kref_get(&mid_entry->refcount); + smb_get_mid(mid_entry); mid_entry->mid_state =3D MID_SHUTDOWN; list_move(&mid_entry->qhead, &dispose_list); mid_entry->deleted_from_q =3D true; @@ -1113,8 +1113,8 @@ clean_demultiplex_info(struct TCP_Server_Info *server) mid_entry =3D list_entry(tmp, struct mid_q_entry, qhead); cifs_dbg(FYI, "Callback mid %llu\n", mid_entry->mid); list_del_init(&mid_entry->qhead); - mid_execute_callback(mid_entry); - release_mid(mid_entry); + mid_execute_callback(server, mid_entry); + release_mid(server, mid_entry); } /* 1/8th of sec is more than enough time for them to exit */ msleep(125); @@ -1355,7 +1355,7 @@ cifs_demultiplex_thread(void *p) if (length < 0) { for (i =3D 0; i < num_mids; i++) if (mids[i]) - release_mid(mids[i]); + release_mid(server, mids[i]); continue; } =20 @@ -1388,9 +1388,9 @@ cifs_demultiplex_thread(void *p) } =20 if (!mids[i]->multiRsp || mids[i]->multiEnd) - mid_execute_callback(mids[i]); + mid_execute_callback(server, mids[i]); =20 - release_mid(mids[i]); + release_mid(server, mids[i]); } else if (server->ops->is_oplock_break && server->ops->is_oplock_break(bufs[i], server)) { diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c index 9ec20601cee2..ba8a92b430c1 100644 --- a/fs/smb/client/netmisc.c +++ b/fs/smb/client/netmisc.c @@ -889,7 +889,8 @@ map_smb_to_linux_error(char *buf, bool logErr) } =20 int -map_and_check_smb_error(struct mid_q_entry *mid, bool logErr) +map_and_check_smb_error(struct TCP_Server_Info *server, + struct mid_q_entry *mid, bool logErr) { int rc; struct smb_hdr *smb =3D (struct smb_hdr *)mid->resp_buf; @@ -904,7 +905,7 @@ map_and_check_smb_error(struct mid_q_entry *mid, bool l= ogErr) if (class =3D=3D ERRSRV && code =3D=3D ERRbaduid) { cifs_dbg(FYI, "Server returned 0x%x, reconnecting session...\n", code); - cifs_signal_cifsd_for_reconnect(mid->server, false); + cifs_signal_cifsd_for_reconnect(server, false); } } =20 diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index 45af69d95b27..53c77db552da 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -145,7 +145,7 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buf= fer) if (compare_mid(mid->mid, buf) && mid->mid_state =3D=3D MID_REQUEST_SUBMITTED && le16_to_cpu(mid->command) =3D=3D buf->Command) { - kref_get(&mid->refcount); + smb_get_mid(mid); spin_unlock(&server->mid_queue_lock); return mid; } @@ -447,7 +447,7 @@ cifs_check_trans2(struct mid_q_entry *mid, struct TCP_S= erver_Info *server, return true; /* All parts received or packet is malformed. */ mid->multiEnd =3D true; - dequeue_mid(mid, malformed); + dequeue_mid(server, mid, malformed); return true; } if (!server->large_buf) { diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 3b8d3852009e..760edb98ed64 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -406,7 +406,7 @@ __smb2_find_mid(struct TCP_Server_Info *server, char *b= uf, bool dequeue) if ((mid->mid =3D=3D wire_mid) && (mid->mid_state =3D=3D MID_REQUEST_SUBMITTED) && (mid->command =3D=3D shdr->Command)) { - kref_get(&mid->refcount); + smb_get_mid(mid); if (dequeue) { list_del_init(&mid->qhead); mid->deleted_from_q =3D true; @@ -4716,7 +4716,7 @@ handle_read_data(struct TCP_Server_Info *server, stru= ct mid_q_entry *mid, if (is_offloaded) mid->mid_state =3D MID_RESPONSE_RECEIVED; else - dequeue_mid(mid, false); + dequeue_mid(server, mid, false); return 0; } =20 @@ -4743,7 +4743,7 @@ handle_read_data(struct TCP_Server_Info *server, stru= ct mid_q_entry *mid, if (is_offloaded) mid->mid_state =3D MID_RESPONSE_MALFORMED; else - dequeue_mid(mid, rdata->result); + dequeue_mid(server, mid, rdata->result); return 0; } =20 @@ -4762,7 +4762,7 @@ handle_read_data(struct TCP_Server_Info *server, stru= ct mid_q_entry *mid, if (is_offloaded) mid->mid_state =3D MID_RESPONSE_MALFORMED; else - dequeue_mid(mid, rdata->result); + dequeue_mid(server, mid, rdata->result); return 0; } =20 @@ -4772,7 +4772,7 @@ handle_read_data(struct TCP_Server_Info *server, stru= ct mid_q_entry *mid, if (is_offloaded) mid->mid_state =3D MID_RESPONSE_MALFORMED; else - dequeue_mid(mid, rdata->result); + dequeue_mid(server, mid, rdata->result); return 0; } =20 @@ -4783,7 +4783,7 @@ handle_read_data(struct TCP_Server_Info *server, stru= ct mid_q_entry *mid, if (is_offloaded) mid->mid_state =3D MID_RESPONSE_MALFORMED; else - dequeue_mid(mid, rdata->result); + dequeue_mid(server, mid, rdata->result); return 0; } rdata->got_bytes =3D buffer_len; @@ -4802,14 +4802,14 @@ handle_read_data(struct TCP_Server_Info *server, st= ruct mid_q_entry *mid, if (is_offloaded) mid->mid_state =3D MID_RESPONSE_MALFORMED; else - dequeue_mid(mid, rdata->result); + dequeue_mid(server, mid, rdata->result); return 0; } =20 if (is_offloaded) mid->mid_state =3D MID_RESPONSE_RECEIVED; else - dequeue_mid(mid, false); + dequeue_mid(server, mid, false); return 0; } =20 @@ -4856,7 +4856,7 @@ static void smb2_decrypt_offload(struct work_struct *= work) dw->server->ops->is_network_name_deleted(dw->buf, dw->server); =20 - mid_execute_callback(mid); + mid_execute_callback(dw->server, mid); } else { spin_lock(&dw->server->srv_lock); if (dw->server->tcpStatus =3D=3D CifsNeedReconnect) { @@ -4864,7 +4864,7 @@ static void smb2_decrypt_offload(struct work_struct *= work) mid->mid_state =3D MID_RETRY_NEEDED; spin_unlock(&dw->server->mid_queue_lock); spin_unlock(&dw->server->srv_lock); - mid_execute_callback(mid); + mid_execute_callback(dw->server, mid); } else { spin_lock(&dw->server->mid_queue_lock); mid->mid_state =3D MID_REQUEST_SUBMITTED; @@ -4875,7 +4875,7 @@ static void smb2_decrypt_offload(struct work_struct *= work) spin_unlock(&dw->server->srv_lock); } } - release_mid(mid); + release_mid(dw->server, mid); } =20 free_pages: diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index ef2c6ac500f7..910703d8efb5 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -4091,9 +4091,8 @@ SMB2_change_notify(const unsigned int xid, struct cif= s_tcon *tcon, * FIXME: maybe we should consider checking that the reply matches request? */ static void -smb2_echo_callback(struct mid_q_entry *mid) +smb2_echo_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid) { - struct TCP_Server_Info *server =3D mid->callback_data; struct smb2_echo_rsp *rsp =3D (struct smb2_echo_rsp *)mid->resp_buf; struct cifs_credits credits =3D { .value =3D 0, .instance =3D 0 }; =20 @@ -4103,7 +4102,7 @@ smb2_echo_callback(struct mid_q_entry *mid) credits.instance =3D server->reconnect_instance; } =20 - release_mid(mid); + release_mid(server, mid); add_credits(server, &credits, CIFS_ECHO_OP); } =20 @@ -4518,14 +4517,12 @@ smb2_new_read_req(void **buf, unsigned int *total_l= en, } =20 static void -smb2_readv_callback(struct mid_q_entry *mid) +smb2_readv_callback(struct TCP_Server_Info *server, struct mid_q_entry *mi= d) { struct cifs_io_subrequest *rdata =3D mid->callback_data; struct netfs_inode *ictx =3D netfs_inode(rdata->rreq->inode); struct cifs_tcon *tcon =3D tlink_tcon(rdata->req->cfile->tlink); - struct TCP_Server_Info *server =3D rdata->server; - struct smb2_hdr *shdr =3D - (struct smb2_hdr *)rdata->iov[0].iov_base; + struct smb2_hdr *shdr =3D (struct smb2_hdr *)rdata->iov[0].iov_base; struct cifs_credits credits =3D { .value =3D 0, .instance =3D 0, @@ -4540,9 +4537,9 @@ smb2_readv_callback(struct mid_q_entry *mid) rqst.rq_iter =3D rdata->subreq.io_iter; } =20 - WARN_ONCE(rdata->server !=3D mid->server, + WARN_ONCE(rdata->server !=3D server, "rdata server %p !=3D mid server %p", - rdata->server, mid->server); + rdata->server, server); =20 cifs_dbg(FYI, "%s: mid=3D%llu state=3D%d result=3D%d bytes=3D%zu/%zu\n", __func__, mid->mid, mid->mid_state, rdata->result, @@ -4643,7 +4640,7 @@ smb2_readv_callback(struct mid_q_entry *mid) rdata->subreq.transferred +=3D rdata->got_bytes; trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress); netfs_read_subreq_terminated(&rdata->subreq); - release_mid(mid); + release_mid(server, mid); trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0, server->credits, server->in_flight, credits.value, cifs_trace_rw_credits_read_response_add); @@ -4820,11 +4817,10 @@ SMB2_read(const unsigned int xid, struct cifs_io_pa= rms *io_parms, * workqueue completion task. */ static void -smb2_writev_callback(struct mid_q_entry *mid) +smb2_writev_callback(struct TCP_Server_Info *server, struct mid_q_entry *m= id) { struct cifs_io_subrequest *wdata =3D mid->callback_data; struct cifs_tcon *tcon =3D tlink_tcon(wdata->req->cfile->tlink); - struct TCP_Server_Info *server =3D wdata->server; struct smb2_write_rsp *rsp =3D (struct smb2_write_rsp *)mid->resp_buf; struct cifs_credits credits =3D { .value =3D 0, @@ -4837,9 +4833,9 @@ smb2_writev_callback(struct mid_q_entry *mid) ssize_t result =3D 0; size_t written; =20 - WARN_ONCE(wdata->server !=3D mid->server, + WARN_ONCE(wdata->server !=3D server, "wdata server %p !=3D mid server %p", - wdata->server, mid->server); + wdata->server, server); =20 switch (mid->mid_state) { case MID_RESPONSE_RECEIVED: @@ -4929,7 +4925,7 @@ smb2_writev_callback(struct mid_q_entry *mid) 0, cifs_trace_rw_credits_write_response_clear); wdata->credits.value =3D 0; cifs_write_subrequest_terminated(wdata, result ?: written); - release_mid(mid); + release_mid(server, mid); trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0, server->credits, server->in_flight, credits.value, cifs_trace_rw_credits_write_response_add); diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c index 6a9b80385b86..d06f872c9ab2 100644 --- a/fs/smb/client/smb2transport.c +++ b/fs/smb/client/smb2transport.c @@ -653,16 +653,15 @@ smb2_mid_entry_alloc(const struct smb2_hdr *shdr, return NULL; } =20 - temp =3D mempool_alloc(cifs_mid_poolp, GFP_NOFS); + temp =3D mempool_alloc(&cifs_mid_pool, GFP_NOFS); memset(temp, 0, sizeof(struct mid_q_entry)); - kref_init(&temp->refcount); + refcount_set(&temp->refcount, 1); spin_lock_init(&temp->mid_lock); temp->mid =3D le64_to_cpu(shdr->MessageId); temp->credits =3D credits > 0 ? credits : 1; temp->pid =3D current->pid; temp->command =3D shdr->Command; /* Always LE */ temp->when_alloc =3D jiffies; - temp->server =3D server; =20 /* * The default is for the mid to be synchronous, so the @@ -779,7 +778,7 @@ smb2_setup_request(struct cifs_ses *ses, struct TCP_Ser= ver_Info *server, rc =3D smb2_sign_rqst(rqst, server); if (rc) { revert_current_mid_from_hdr(server, shdr); - delete_mid(mid); + delete_mid(server, mid); return ERR_PTR(rc); } =20 @@ -813,7 +812,7 @@ smb2_setup_async_request(struct TCP_Server_Info *server= , struct smb_rqst *rqst) rc =3D smb2_sign_rqst(rqst, server); if (rc) { revert_current_mid_from_hdr(server, shdr); - release_mid(mid); + release_mid(server, mid); return ERR_PTR(rc); } =20 diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index 6077eaf73df6..c26d1837d527 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -32,24 +32,21 @@ #include "compress.h" =20 void -cifs_wake_up_task(struct mid_q_entry *mid) +cifs_wake_up_task(struct TCP_Server_Info *server, struct mid_q_entry *mid) { if (mid->mid_state =3D=3D MID_RESPONSE_RECEIVED) mid->mid_state =3D MID_RESPONSE_READY; wake_up_process(mid->callback_data); } =20 -void __release_mid(struct kref *refcount) +void __release_mid(struct TCP_Server_Info *server, struct mid_q_entry *mid= Entry) { - struct mid_q_entry *midEntry =3D - container_of(refcount, struct mid_q_entry, refcount); #ifdef CONFIG_CIFS_STATS2 - __le16 command =3D midEntry->server->vals->lock_cmd; + __le16 command =3D server->vals->lock_cmd; __u16 smb_cmd =3D le16_to_cpu(midEntry->command); unsigned long now; unsigned long roundtrip_time; #endif - struct TCP_Server_Info *server =3D midEntry->server; =20 if (midEntry->resp_buf && (midEntry->wait_cancelled) && (midEntry->mid_state =3D=3D MID_RESPONSE_RECEIVED || @@ -116,20 +113,21 @@ void __release_mid(struct kref *refcount) #endif put_task_struct(midEntry->creator); =20 - mempool_free(midEntry, cifs_mid_poolp); + mempool_free(midEntry, &cifs_mid_pool); } =20 void -delete_mid(struct mid_q_entry *mid) +delete_mid(struct TCP_Server_Info *server, struct mid_q_entry *mid) { - spin_lock(&mid->server->mid_queue_lock); - if (mid->deleted_from_q =3D=3D false) { + spin_lock(&server->mid_queue_lock); + + if (!mid->deleted_from_q) { list_del_init(&mid->qhead); mid->deleted_from_q =3D true; } - spin_unlock(&mid->server->mid_queue_lock); + spin_unlock(&server->mid_queue_lock); =20 - release_mid(mid); + release_mid(server, mid); } =20 /* @@ -727,7 +725,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct = smb_rqst *rqst, if (rc < 0) { revert_current_mid(server, mid->credits); server->sequence_number -=3D 2; - delete_mid(mid); + delete_mid(server, mid); } =20 cifs_server_unlock(server); @@ -777,14 +775,13 @@ int cifs_sync_mid_result(struct mid_q_entry *mid, str= uct TCP_Server_Info *server spin_unlock(&server->mid_queue_lock); =20 sync_mid_done: - release_mid(mid); + release_mid(server, mid); return rc; } =20 static void -cifs_compound_callback(struct mid_q_entry *mid) +cifs_compound_callback(struct TCP_Server_Info *server, struct mid_q_entry = *mid) { - struct TCP_Server_Info *server =3D mid->server; struct cifs_credits credits =3D { .value =3D server->ops->get_credits(mid), .instance =3D server->reconnect_instance, @@ -797,17 +794,17 @@ cifs_compound_callback(struct mid_q_entry *mid) } =20 static void -cifs_compound_last_callback(struct mid_q_entry *mid) +cifs_compound_last_callback(struct TCP_Server_Info *server, struct mid_q_e= ntry *mid) { - cifs_compound_callback(mid); - cifs_wake_up_task(mid); + cifs_compound_callback(server, mid); + cifs_wake_up_task(server, mid); } =20 static void -cifs_cancelled_callback(struct mid_q_entry *mid) +cifs_cancelled_callback(struct TCP_Server_Info *server, struct mid_q_entry= *mid) { - cifs_compound_callback(mid); - release_mid(mid); + cifs_compound_callback(server, mid); + release_mid(server, mid); } =20 /* @@ -941,7 +938,7 @@ compound_send_recv(const unsigned int xid, struct cifs_= ses *ses, if (IS_ERR(mid[i])) { revert_current_mid(server, i); for (j =3D 0; j < i; j++) - delete_mid(mid[j]); + delete_mid(server, mid[j]); cifs_server_unlock(server); =20 /* Update # of requests on wire to server */ @@ -1096,7 +1093,7 @@ compound_send_recv(const unsigned int xid, struct cif= s_ses *ses, */ for (i =3D 0; i < num_rqst; i++) { if (!cancelled_mid[i]) - delete_mid(mid[i]); + delete_mid(server, mid[i]); } =20 return rc; @@ -1145,7 +1142,7 @@ __cifs_readv_discard(struct TCP_Server_Info *server, = struct mid_q_entry *mid, int length; =20 length =3D cifs_discard_remaining_data(server); - dequeue_mid(mid, malformed); + dequeue_mid(server, mid, malformed); mid->resp_buf =3D server->smallbuf; server->smallbuf =3D NULL; return length; @@ -1282,7 +1279,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, st= ruct mid_q_entry *mid) if (server->total_read < buflen) return cifs_readv_discard(server, mid); =20 - dequeue_mid(mid, false); + dequeue_mid(server, mid, false); mid->resp_buf =3D server->smallbuf; server->smallbuf =3D NULL; return length; From nobody Tue Dec 2 00:25:46 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBF602D321B for ; Mon, 1 Dec 2025 22:58:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629896; cv=none; b=iKzvtbsyMy7hGWgKiukumJAlR0vlUTK6jX6RjpUHClZFlhdiOTHJoTk0xwEi6EdXV0CTEFXfL9wvZjOjLY0UVHhubtpsHqPyW6kbIqKltnIOh2//86lXqZ5JZeDiezKOX+rZ0++eBDfJPKCNBDMIpRweDKEUtflKlL40pWiW3u0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629896; c=relaxed/simple; bh=kVAzsdYACNxCMIlrstbDN4TiRE8cu9bDDpWkvccgviQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CTlZG7RbkDlGzX6B53omhyj4KhCLE/e9D/K0MtdrDcGLBXYoJ5s5NV2ptsM2xfHC8AGenWmNnMsBJ3a+361zYm9x9SxJ/UINsZcOrxNoyUxcpCMNelcf58r2DoONaOZPizbIdmINzkI1sGtb3WVkY8cCtmr02rDr5056FhHcI5M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Pe7iCBHu; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Pe7iCBHu" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764629893; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nkk/qeDFISFqpoIzreaKbH6PF7a/zBmUeahYIhhBiU0=; b=Pe7iCBHugHYUIy9Ei8puw4UF5smgSVOcjbKkXhqQ6tyhRkFOReYRIbv77FU+fD+xlbwNqA NmhpHe61NcnG1scca1kMbizMMi2MCn+kUzWpPVPXRGXpBsTYV2ZQmtHl9owG0tT49lbVYO 5gUlBj2qjBLDpTbhwLlMnGV+7tI+hmc= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-468-wXejG35tPvKSbc0osxpLlw-1; Mon, 01 Dec 2025 17:58:10 -0500 X-MC-Unique: wXejG35tPvKSbc0osxpLlw-1 X-Mimecast-MFC-AGG-ID: wXejG35tPvKSbc0osxpLlw_1764629888 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B75F1195609D; Mon, 1 Dec 2025 22:58:08 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.14]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 23C0219560B2; Mon, 1 Dec 2025 22:58:05 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Stefan Metzmacher , Tom Talpey , linux-cifs@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 7/9] cifs: Don't need state locking in smb2_get_mid_entry() Date: Mon, 1 Dec 2025 22:57:28 +0000 Message-ID: <20251201225732.1520128-8-dhowells@redhat.com> In-Reply-To: <20251201225732.1520128-1-dhowells@redhat.com> References: <20251201225732.1520128-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" There's no need to get ->srv_lock or ->ses_lock in smb2_get_mid_entry() as all that happens of relevance (to the lock) inside the locked sections is the reading of one status value in each. Replace the locking with READ_ONCE() and use a switch instead of a chain of if-statements. Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: Shyam Prasad N cc: Tom Talpey cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org --- fs/smb/client/smb2transport.c | 48 +++++++++++++++-------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c index d06f872c9ab2..99fa48bcd459 100644 --- a/fs/smb/client/smb2transport.c +++ b/fs/smb/client/smb2transport.c @@ -684,43 +684,35 @@ static int smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server, struct smb2_hdr *shdr, struct mid_q_entry **mid) { - spin_lock(&server->srv_lock); - if (server->tcpStatus =3D=3D CifsExiting) { - spin_unlock(&server->srv_lock); + switch (READ_ONCE(server->tcpStatus)) { + case CifsExiting: return -ENOENT; - } - - if (server->tcpStatus =3D=3D CifsNeedReconnect) { - spin_unlock(&server->srv_lock); + case CifsNeedReconnect: cifs_dbg(FYI, "tcp session dead - return to caller to retry\n"); return -EAGAIN; - } - - if (server->tcpStatus =3D=3D CifsNeedNegotiate && - shdr->Command !=3D SMB2_NEGOTIATE) { - spin_unlock(&server->srv_lock); - return -EAGAIN; - } - spin_unlock(&server->srv_lock); - - spin_lock(&ses->ses_lock); - if (ses->ses_status =3D=3D SES_NEW) { - if ((shdr->Command !=3D SMB2_SESSION_SETUP) && - (shdr->Command !=3D SMB2_NEGOTIATE)) { - spin_unlock(&ses->ses_lock); + case CifsNeedNegotiate: + if (shdr->Command !=3D SMB2_NEGOTIATE) return -EAGAIN; - } - /* else ok - we are setting up session */ + break; + default: + break; } =20 - if (ses->ses_status =3D=3D SES_EXITING) { - if (shdr->Command !=3D SMB2_LOGOFF) { - spin_unlock(&ses->ses_lock); + switch (READ_ONCE(ses->ses_status)) { + case SES_NEW: + if (shdr->Command !=3D SMB2_SESSION_SETUP && + shdr->Command !=3D SMB2_NEGOTIATE) + return -EAGAIN; + /* else ok - we are setting up session */ + break; + case SES_EXITING: + if (shdr->Command !=3D SMB2_LOGOFF) return -EAGAIN; - } /* else ok - we are shutting down the session */ + break; + default: + break; } - spin_unlock(&ses->ses_lock); =20 *mid =3D smb2_mid_entry_alloc(shdr, server); if (*mid =3D=3D NULL) From nobody Tue Dec 2 00:25:46 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 795A32D0610 for ; Mon, 1 Dec 2025 22:58:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629909; cv=none; b=EBUpSYiZJ9VAyYTPZjSIuyPsJEBb9PSBBBOBlKnzJOE5BWr46Y3KxOwjP6XbjmlsXCYohhC4MR3aPjzdkoZitWoY1SvMc6EeXK7xjgiKCpE1bQlgR9+TveNU6sKMdGDEarTQdlCxXFSciC5oim/UgYWuJintVGWNw7HTjFyoEQ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629909; c=relaxed/simple; bh=84piYekjhEMDXYWelRN9y2MqcKiQRMowjlRQf0wO+kA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hgGQ8i0LRoFjhT5Jn4hKedBRHGn/WPvk5G2kXnJCMt8N3PsCYIAyND08dTzDakk/DyHiJgNpyVxcuq8uhjdAcdRmTpVjCy1dGWgwz3O7Wn18Jbl7N5wI7wTxHE+IWQ1CHcsS0Uka8Uoz72z+UvJYcyDPh7MltL/JAjUrfYpMfq8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=S1WJyjZ0; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="S1WJyjZ0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764629901; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hw7uqzwXtA2W+Xm2S1P309bTSQNLQBddmaGOcRT4dro=; b=S1WJyjZ0zarO7PVv/FdmpZO2g+Ww1gy4f1kh4dtSncIPW1sR3+VTqIDAZvtp8LGsBK0NU1 SHm+LJQET07W3cLecbLZfAXLgPzVTZvv5gnvtB6u1D4ae33H9jGfKyl8SfCF5UG8kZahmJ bQac0eoEgDkTQl81t7LcYKDF6BSdDzk= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-53-xWmIzw31PDuor_Eo8VXRnw-1; Mon, 01 Dec 2025 17:58:14 -0500 X-MC-Unique: xWmIzw31PDuor_Eo8VXRnw-1 X-Mimecast-MFC-AGG-ID: xWmIzw31PDuor_Eo8VXRnw_1764629893 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0FF6419560B0; Mon, 1 Dec 2025 22:58:13 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.14]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 259A8195608E; Mon, 1 Dec 2025 22:58:09 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Stefan Metzmacher , Tom Talpey , linux-cifs@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 8/9] cifs: Add a tracepoint to log EIO errors Date: Mon, 1 Dec 2025 22:57:29 +0000 Message-ID: <20251201225732.1520128-9-dhowells@redhat.com> In-Reply-To: <20251201225732.1520128-1-dhowells@redhat.com> References: <20251201225732.1520128-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Content-Type: text/plain; charset="utf-8" Add a tracepoint to log EIO errors and give it the capacity to convey up to two integers of information. This is then wrapped with three functions: int smb_EIO(enum smb_eio_trace trace) int smb_EIO1(enum smb_eio_trace trace, unsigned long info) int smb_EIO2(enum smb_eio_trace trace, unsigned long info, unsigned long info2) depending on how many bits of info are desired to be logged with any particular trace. The functions all return -EIO and can be used in place of -EIO. The trace argument is an enum value that gets translated to a string when the trace is printed. This makes is easier to log EIO instances when the client is under high load than turning on a printk wrapper such as cifs_dbg(). Granted, EIO could have its own separate EIO printing since EIO shouldn't happen. Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: linux-cifs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org --- fs/smb/client/cached_dir.c | 2 +- fs/smb/client/cifsacl.c | 10 +- fs/smb/client/cifsencrypt.c | 13 ++- fs/smb/client/cifsglob.h | 88 ----------------- fs/smb/client/cifsproto.h | 106 ++++++++++++++++++++ fs/smb/client/cifssmb.c | 149 +++++++++++++++++----------- fs/smb/client/cifstransport.c | 8 +- fs/smb/client/compress.c | 2 +- fs/smb/client/connect.c | 11 ++- fs/smb/client/dir.c | 6 +- fs/smb/client/file.c | 6 +- fs/smb/client/inode.c | 14 +-- fs/smb/client/link.c | 10 +- fs/smb/client/misc.c | 18 ++-- fs/smb/client/netmisc.c | 4 + fs/smb/client/readdir.c | 2 +- fs/smb/client/reparse.c | 53 ++++++---- fs/smb/client/sess.c | 8 +- fs/smb/client/smb2file.c | 6 +- fs/smb/client/smb2inode.c | 12 ++- fs/smb/client/smb2maperror.c | 3 + fs/smb/client/smb2ops.c | 41 +++++--- fs/smb/client/smb2pdu.c | 177 +++++++++++++++++++++------------- fs/smb/client/smb2transport.c | 2 +- fs/smb/client/trace.h | 149 ++++++++++++++++++++++++++++ fs/smb/client/transport.c | 21 ++-- fs/smb/client/xattr.c | 2 +- 27 files changed, 610 insertions(+), 313 deletions(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index e3ea6fe7edb4..1db7ab6c2529 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -176,7 +176,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon = *tcon, server =3D cifs_pick_channel(ses); =20 if (!server->ops->new_lease_key) - return -EIO; + return smb_EIO(smb_eio_trace_no_lease_key); =20 utf16_path =3D cifs_convert_path_to_utf16(path, cifs_sb); if (!utf16_path) diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c index ce2ebc213a1d..7e6e473bd4a0 100644 --- a/fs/smb/client/cifsacl.c +++ b/fs/smb/client/cifsacl.c @@ -300,7 +300,7 @@ id_to_sid(unsigned int cid, uint sidtype, struct smb_si= d *ssid) __func__, sidtype =3D=3D SIDOWNER ? 'u' : 'g', cid); goto out_revert_creds; } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) { - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_malformed_sid_key, sidkey->datalen); cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=3D%hu)\n", __func__, sidkey->datalen); goto invalidate_key; @@ -317,7 +317,8 @@ id_to_sid(unsigned int cid, uint sidtype, struct smb_si= d *ssid) =20 ksid_size =3D CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32)); if (ksid_size > sidkey->datalen) { - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_malformed_ksid_key, + ksid_size, sidkey->datalen); cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=3D%hu, ksid= _size=3D%u)\n", __func__, sidkey->datalen, ksid_size); goto invalidate_key; @@ -352,7 +353,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid = *psid, if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) { cifs_dbg(FYI, "%s: %u subauthorities is too many!\n", __func__, psid->num_subauth); - return -EIO; + return smb_EIO2(smb_eio_trace_sid_too_many_auth, + psid->num_subauth, SID_MAX_SUB_AUTHORITIES); } =20 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) || @@ -1227,7 +1229,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_s= b, __u32 dacloffset; =20 if (pntsd =3D=3D NULL) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 owner_sid_ptr =3D (struct smb_sid *)((char *)pntsd + le32_to_cpu(pntsd->osidoffset)); diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c index a9a57904c6b1..ca2a84e8673e 100644 --- a/fs/smb/client/cifsencrypt.c +++ b/fs/smb/client/cifsencrypt.c @@ -75,11 +75,13 @@ static int cifs_sig_iter(const struct iov_iter *iter, s= ize_t maxsize, struct cifs_calc_sig_ctx *ctx) { struct iov_iter tmp_iter =3D *iter; - int err =3D -EIO; + size_t did; + int err; =20 - if (iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err, - cifs_sig_step) !=3D maxsize) - return err; + did =3D iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err, + cifs_sig_step); + if (did !=3D maxsize) + return smb_EIO2(smb_eio_trace_sig_iter, did, maxsize); return 0; } =20 @@ -96,7 +98,8 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct T= CP_Server_Info *server, iov_iter_kvec(&iter, ITER_SOURCE, rqst->rq_iov, rqst->rq_nvec, size); =20 if (iov_iter_count(&iter) <=3D 4) - return -EIO; + return smb_EIO2(smb_eio_trace_sig_data_too_small, + iov_iter_count(&iter), 4); =20 rc =3D cifs_sig_iter(&iter, iov_iter_count(&iter), ctx); if (rc < 0) diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 1f93c309dfe8..a8cfe9b87a20 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -2206,94 +2206,6 @@ static inline void move_cifs_info_to_smb2(struct smb= 2_file_all_info *dst, const dst->FileNameLength =3D src->FileNameLength; } =20 -static inline int cifs_get_num_sgs(const struct smb_rqst *rqst, - int num_rqst, - const u8 *sig) -{ - unsigned int len, skip; - unsigned int nents =3D 0; - unsigned long addr; - size_t data_size; - int i, j; - - /* - * The first rqst has a transform header where the first 20 bytes are - * not part of the encrypted blob. - */ - skip =3D 20; - - /* Assumes the first rqst has a transform header as the first iov. - * I.e. - * rqst[0].rq_iov[0] is transform header - * rqst[0].rq_iov[1+] data to be encrypted/decrypted - * rqst[1+].rq_iov[0+] data to be encrypted/decrypted - */ - for (i =3D 0; i < num_rqst; i++) { - data_size =3D iov_iter_count(&rqst[i].rq_iter); - - /* We really don't want a mixture of pinned and unpinned pages - * in the sglist. It's hard to keep track of which is what. - * Instead, we convert to a BVEC-type iterator higher up. - */ - if (data_size && - WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter))) - return -EIO; - - /* We also don't want to have any extra refs or pins to clean - * up in the sglist. - */ - if (data_size && - WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter))) - return -EIO; - - for (j =3D 0; j < rqst[i].rq_nvec; j++) { - struct kvec *iov =3D &rqst[i].rq_iov[j]; - - addr =3D (unsigned long)iov->iov_base + skip; - if (is_vmalloc_or_module_addr((void *)addr)) { - len =3D iov->iov_len - skip; - nents +=3D DIV_ROUND_UP(offset_in_page(addr) + len, - PAGE_SIZE); - } else { - nents++; - } - skip =3D 0; - } - if (data_size) - nents +=3D iov_iter_npages(&rqst[i].rq_iter, INT_MAX); - } - nents +=3D DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_S= IZE); - return nents; -} - -/* We can not use the normal sg_set_buf() as we will sometimes pass a - * stack object as buf. - */ -static inline void cifs_sg_set_buf(struct sg_table *sgtable, - const void *buf, - unsigned int buflen) -{ - unsigned long addr =3D (unsigned long)buf; - unsigned int off =3D offset_in_page(addr); - - addr &=3D PAGE_MASK; - if (is_vmalloc_or_module_addr((void *)addr)) { - do { - unsigned int len =3D min_t(unsigned int, buflen, PAGE_SIZE - off); - - sg_set_page(&sgtable->sgl[sgtable->nents++], - vmalloc_to_page((void *)addr), len, off); - - off =3D 0; - addr +=3D PAGE_SIZE; - buflen -=3D len; - } while (buflen); - } else { - sg_set_page(&sgtable->sgl[sgtable->nents++], - virt_to_page((void *)addr), buflen, off); - } -} - #define CIFS_OPARMS(_cifs_sb, _tcon, _path, _da, _cd, _co, _mode) \ ((struct cifs_open_parms) { \ .tcon =3D _tcon, \ diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index d72d66dcb953..5d54de12f0f4 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -786,4 +786,110 @@ static inline void cifs_free_open_info(struct cifs_op= en_info_data *data) memset(data, 0, sizeof(*data)); } =20 +static inline int smb_EIO(enum smb_eio_trace trace) +{ + trace_smb3_eio(trace, 0, 0); + return -EIO; +} + +static inline int smb_EIO1(enum smb_eio_trace trace, unsigned long info) +{ + trace_smb3_eio(trace, info, 0); + return -EIO; +} + +static inline int smb_EIO2(enum smb_eio_trace trace, unsigned long info, u= nsigned long info2) +{ + trace_smb3_eio(trace, info, info2); + return -EIO; +} + +static inline int cifs_get_num_sgs(const struct smb_rqst *rqst, + int num_rqst, + const u8 *sig) +{ + unsigned int len, skip; + unsigned int nents =3D 0; + unsigned long addr; + size_t data_size; + int i, j; + + /* + * The first rqst has a transform header where the first 20 bytes are + * not part of the encrypted blob. + */ + skip =3D 20; + + /* Assumes the first rqst has a transform header as the first iov. + * I.e. + * rqst[0].rq_iov[0] is transform header + * rqst[0].rq_iov[1+] data to be encrypted/decrypted + * rqst[1+].rq_iov[0+] data to be encrypted/decrypted + */ + for (i =3D 0; i < num_rqst; i++) { + data_size =3D iov_iter_count(&rqst[i].rq_iter); + + /* We really don't want a mixture of pinned and unpinned pages + * in the sglist. It's hard to keep track of which is what. + * Instead, we convert to a BVEC-type iterator higher up. + */ + if (data_size && + WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter))) + return smb_EIO(smb_eio_trace_user_iter); + + /* We also don't want to have any extra refs or pins to clean + * up in the sglist. + */ + if (data_size && + WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter))) + return smb_EIO(smb_eio_trace_extract_will_pin); + + for (j =3D 0; j < rqst[i].rq_nvec; j++) { + struct kvec *iov =3D &rqst[i].rq_iov[j]; + + addr =3D (unsigned long)iov->iov_base + skip; + if (is_vmalloc_or_module_addr((void *)addr)) { + len =3D iov->iov_len - skip; + nents +=3D DIV_ROUND_UP(offset_in_page(addr) + len, + PAGE_SIZE); + } else { + nents++; + } + skip =3D 0; + } + if (data_size) + nents +=3D iov_iter_npages(&rqst[i].rq_iter, INT_MAX); + } + nents +=3D DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_S= IZE); + return nents; +} + +/* We can not use the normal sg_set_buf() as we will sometimes pass a + * stack object as buf. + */ +static inline void cifs_sg_set_buf(struct sg_table *sgtable, + const void *buf, + unsigned int buflen) +{ + unsigned long addr =3D (unsigned long)buf; + unsigned int off =3D offset_in_page(addr); + + addr &=3D PAGE_MASK; + if (is_vmalloc_or_module_addr((void *)addr)) { + do { + unsigned int len =3D min_t(unsigned int, buflen, PAGE_SIZE - off); + + sg_set_page(&sgtable->sgl[sgtable->nents++], + vmalloc_to_page((void *)addr), len, off); + + off =3D 0; + addr +=3D PAGE_SIZE; + buflen -=3D len; + } while (buflen); + } else { + sg_set_page(&sgtable->sgl[sgtable->nents++], + virt_to_page((void *)addr), buflen, off); + } +} + #endif /* _CIFSPROTO_H */ diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c index 071ec22b5e34..defaf001e13f 100644 --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -373,7 +373,8 @@ decode_ext_sec_blob(struct cifs_ses *ses, SMB_NEGOTIATE= _RSP *pSMBr) =20 count =3D get_bcc(&pSMBr->hdr); if (count < SMB1_CLIENT_GUID_SIZE) - return -EIO; + return smb_EIO2(smb_eio_trace_neg_sec_blob_too_small, + count, SMB1_CLIENT_GUID_SIZE); =20 spin_lock(&cifs_tcp_ses_lock); if (server->srv_count > 1) { @@ -432,7 +433,7 @@ CIFSSMBNegotiate(const unsigned int xid, =20 if (!server) { WARN(1, "%s: server is NULL!\n", __func__); - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); } =20 rc =3D smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ , @@ -516,7 +517,8 @@ CIFSSMBNegotiate(const unsigned int xid, server->negflavor =3D CIFS_NEGFLAVOR_EXTENDED; rc =3D decode_ext_sec_blob(ses, pSMBr); } else if (server->sec_mode & SECMODE_PW_ENCRYPT) { - rc =3D -EIO; /* no crypt key only if plain text pwd */ + /* no crypt key only if plain text pwd */ + rc =3D smb_EIO(smb_eio_trace_neg_no_crypt_key); } else { server->negflavor =3D CIFS_NEGFLAVOR_UNENCAP; server->capabilities &=3D ~CAP_EXTENDED_SECURITY; @@ -542,7 +544,7 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *t= con) =20 /* BB: do we need to check this? These should never be NULL. */ if ((tcon->ses =3D=3D NULL) || (tcon->ses->server =3D=3D NULL)) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 /* * No need to return error on this operation if tid invalidated and @@ -553,7 +555,7 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *t= con) spin_lock(&tcon->ses->chan_lock); if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) { spin_unlock(&tcon->ses->chan_lock); - return -EIO; + return smb_EIO(smb_eio_trace_tdis_in_reconnect); } spin_unlock(&tcon->ses->chan_lock); =20 @@ -650,7 +652,7 @@ CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *= ses) * should probably be a BUG() */ if (!ses || !ses->server) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 mutex_lock(&ses->session_mutex); spin_lock(&ses->chan_lock); @@ -980,7 +982,8 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tco= n *tcon, rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); =20 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) { - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_create_rsp_too_small, + get_bcc(&pSMBr->hdr), sizeof(OPEN_PSX_RSP)); goto psx_create_err; } =20 @@ -1371,11 +1374,12 @@ cifs_readv_callback(struct TCP_Server_Info *server,= struct mid_q_entry *mid) break; case MID_RESPONSE_MALFORMED: trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed); - rdata->result =3D -EIO; + rdata->result =3D smb_EIO(smb_eio_trace_read_rsp_malformed); break; - default: + default:=20 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown); - rdata->result =3D -EIO; + rdata->result =3D smb_EIO1(smb_eio_trace_read_mid_state_unknown, + mid->mid_state); break; } =20 @@ -1446,7 +1450,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata) wct =3D 10; /* old style read */ if ((rdata->subreq.start >> 32) > 0) { /* can not handle this big offset for old */ - return -EIO; + return smb_EIO(smb_eio_trace_read_too_far); } } =20 @@ -1521,7 +1525,7 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_pa= rms *io_parms, wct =3D 10; /* old style read */ if ((offset >> 32) > 0) { /* can not handle this big offset for old */ - return -EIO; + return smb_EIO(smb_eio_trace_read_too_far); } } =20 @@ -1576,7 +1580,8 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_pa= rms *io_parms, || (data_length > count)) { cifs_dbg(FYI, "bad length %d for count %d\n", data_length, count); - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_read_overlarge, + data_length, count); *nbytes =3D 0; } else { pReadData =3D (char *) (&pSMBr->hdr.Protocol) + @@ -1635,7 +1640,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_p= arms *io_parms, wct =3D 12; if ((offset >> 32) > 0) { /* can not handle big offset for old srv */ - return -EIO; + return smb_EIO(smb_eio_trace_write_too_far); } } =20 @@ -1786,11 +1791,12 @@ cifs_writev_callback(struct TCP_Server_Info *server= , struct mid_q_entry *mid) break; case MID_RESPONSE_MALFORMED: trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed); - result =3D -EIO; + result =3D smb_EIO(smb_eio_trace_write_rsp_malformed); break; default: trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown); - result =3D -EIO; + result =3D smb_EIO1(smb_eio_trace_write_mid_state_unknown, + mid->mid_state); break; } =20 @@ -1825,7 +1831,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata) wct =3D 12; if (wdata->subreq.start >> 32 > 0) { /* can not handle big offset for old srv */ - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_write_too_far); goto out; } } @@ -1917,7 +1923,7 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_= parms *io_parms, wct =3D 12; if ((offset >> 32) > 0) { /* can not handle big offset for old srv */ - return -EIO; + return smb_EIO(smb_eio_trace_write_too_far); } } rc =3D small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); @@ -1973,7 +1979,7 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_= parms *io_parms, cifs_dbg(FYI, "Send error Write2 =3D %d\n", rc); } else if (resp_buf_type =3D=3D 0) { /* presumably this can not happen, but best to be safe */ - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_write_bad_buf_type, resp_buf_type); } else { WRITE_RSP *pSMBr =3D (WRITE_RSP *)rsp_iov.iov_base; *nbytes =3D le16_to_cpu(pSMBr->CountHigh); @@ -2209,13 +2215,15 @@ CIFSSMBPosixLock(const unsigned int xid, struct cif= s_tcon *tcon, rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); =20 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) { - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_lock_bcc_too_small, + get_bcc(&pSMBr->hdr), sizeof(*parm_data)); goto plk_err_exit; } data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); data_count =3D le16_to_cpu(pSMBr->t2.DataCount); if (data_count < sizeof(struct cifs_posix_lock)) { - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_lock_data_too_small, + data_count, sizeof(struct cifs_posix_lock)); goto plk_err_exit; } parm_data =3D (struct cifs_posix_lock *) @@ -2774,7 +2782,8 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struc= t cifs_tcon *tcon, rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); /* BB also check enough total bytes returned */ if (rc || get_bcc(&pSMBr->hdr) < 2) - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_qsym_bcc_too_small, + get_bcc(&pSMBr->hdr), 2); else { bool is_unicode; u16 count =3D le16_to_cpu(pSMBr->t2.DataCount); @@ -2876,13 +2885,15 @@ int cifs_query_reparse_point(const unsigned int xid, data_count =3D le32_to_cpu(io_rsp->DataCount); if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 || !data_count || data_count > 2048) { - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_qreparse_sizes_wrong, + get_bcc(&io_rsp->hdr), data_count); goto error; } =20 /* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */ if (io_rsp->SetupCount !=3D 1) { - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_qreparse_setup_count, + io_rsp->SetupCount, 1); goto error; } =20 @@ -2892,14 +2903,17 @@ int cifs_query_reparse_point(const unsigned int xid, * Check that we have full FSCTL_GET_REPARSE_POINT buffer. */ if (data_count !=3D le16_to_cpu(io_rsp->ReturnedDataLen)) { - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_qreparse_ret_datalen, + data_count, le16_to_cpu(io_rsp->ReturnedDataLen)); goto error; } =20 end =3D 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount; start =3D (__u8 *)&io_rsp->hdr.Protocol + data_offset; if (start >=3D end) { - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_qreparse_data_area, + (unsigned long)start - (unsigned long)io_rsp, + (unsigned long)end - (unsigned long)io_rsp); goto error; } =20 @@ -2908,7 +2922,8 @@ int cifs_query_reparse_point(const unsigned int xid, len =3D sizeof(*buf); if (data_count < len || data_count < le16_to_cpu(buf->ReparseDataLength) + len) { - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_qreparse_rep_datalen, + data_count, le16_to_cpu(buf->ReparseDataLength) + len); goto error; } =20 @@ -3352,7 +3367,8 @@ int cifs_do_get_acl(const unsigned int xid, struct ci= fs_tcon *tcon, rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); /* BB also check enough total bytes returned */ if (rc || get_bcc(&pSMBr->hdr) < 2) - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_getacl_bcc_too_small, + get_bcc(&pSMBr->hdr), 2); else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); __u16 count =3D le16_to_cpu(pSMBr->t2.DataCount); @@ -3525,7 +3541,8 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tc= on *tcon, if (rc || get_bcc(&pSMBr->hdr) < 2) /* If rc should we check for EOPNOSUPP and disable the srvino flag? or in caller? */ - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_getextattr_bcc_too_small, + get_bcc(&pSMBr->hdr), 2); else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); __u16 count =3D le16_to_cpu(pSMBr->t2.DataCount); @@ -3533,7 +3550,8 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tc= on *tcon, =20 if (count !=3D 16) { cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n"); - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_getextattr_inv_size, + count, 16); goto GetExtAttrOut; } pfinfo =3D (struct file_chattr_info *) @@ -3700,7 +3718,8 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs= _tcon *tcon, __u16 fid, pSMBr, parm, *acl_inf); =20 if (le32_to_cpu(pSMBr->ParameterCount) !=3D 4) { - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_getcifsacl_param_count, + le32_to_cpu(pSMBr->ParameterCount), 4); *pbuflen =3D 0; goto qsec_out; } @@ -3858,8 +3877,10 @@ SMBQueryInformation(const unsigned int xid, struct c= ifs_tcon *tcon, data->EndOfFile =3D data->AllocationSize; data->Attributes =3D cpu_to_le32(le16_to_cpu(pSMBr->attr)); - } else - rc =3D -EIO; /* bad buffer passed in */ + } else { + /* bad buffer passed in */ + rc =3D smb_EIO(smb_eio_trace_null_pointers); + } =20 cifs_buf_release(pSMB); =20 @@ -3921,9 +3942,11 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs= _tcon *tcon, rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); =20 if (rc) /* BB add auto retry on EOPNOTSUPP? */ - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_qfileinfo_invalid, + get_bcc(&pSMBr->hdr), 40); else if (get_bcc(&pSMBr->hdr) < 40) - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_qfileinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), 40); else if (pFindData) { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); memcpy((char *) pFindData, @@ -4008,12 +4031,15 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cif= s_tcon *tcon, rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); =20 if (rc) /* BB add auto retry on EOPNOTSUPP? */ - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_qpathinfo_invalid, + get_bcc(&pSMBr->hdr), 40); else if (!legacy && get_bcc(&pSMBr->hdr) < 40) - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), 40); else if (legacy && get_bcc(&pSMBr->hdr) < 24) - rc =3D -EIO; /* 24 or 26 expected but we do not read - last field */ + /* 24 or 26 expected but we do not read last field */ + rc =3D smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), 24); else if (data) { int size; __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); @@ -4093,7 +4119,8 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct c= ifs_tcon *tcon, =20 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions= can be disabled on mount by specifying the nosfu mount option.\n"); - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_unixqfileinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO)); } else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); memcpy((char *) pFindData, @@ -4177,7 +4204,8 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct c= ifs_tcon *tcon, =20 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions= can be disabled on mount by specifying the nosfu mount option.\n"); - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_unixqpathinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO)); } else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); memcpy((char *) pFindData, @@ -4580,7 +4608,8 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct = cifs_tcon *tcon, if (rc || get_bcc(&pSMBr->hdr) < 2) /* If rc should we check for EOPNOSUPP and disable the srvino flag? or in caller? */ - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_getsrvinonum_bcc_too_small, + get_bcc(&pSMBr->hdr), 2); else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); __u16 count =3D le16_to_cpu(pSMBr->t2.DataCount); @@ -4588,7 +4617,8 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct = cifs_tcon *tcon, /* BB Do we need a cast or hash here ? */ if (count < 8) { cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n"); - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_getsrvinonum_size, + count, 8); goto GetInodeNumOut; } pfinfo =3D (struct file_internal_info *) @@ -4697,7 +4727,8 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_s= es *ses, =20 /* BB Also check if enough total bytes returned? */ if (rc || get_bcc(&pSMBr->hdr) < 17) { - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_getdfsrefer_bcc_too_small, + get_bcc(&pSMBr->hdr), 17); goto GetDFSRefExit; } =20 @@ -4773,7 +4804,8 @@ SMBOldQFSInfo(const unsigned int xid, struct cifs_tco= n *tcon, rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); =20 if (rc || get_bcc(&pSMBr->hdr) < 18) - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_oldqfsinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), 18); else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n", @@ -4862,7 +4894,8 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tc= on *tcon, rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); =20 if (rc || get_bcc(&pSMBr->hdr) < 24) - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_qfsinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), 24); else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); =20 @@ -4952,7 +4985,8 @@ CIFSSMBQFSAttributeInfo(const unsigned int xid, struc= t cifs_tcon *tcon) =20 if (rc || get_bcc(&pSMBr->hdr) < 13) { /* BB also check if enough bytes returned */ - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_qfsattrinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), 13); } else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); response_data =3D @@ -5025,7 +5059,9 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct c= ifs_tcon *tcon) =20 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_SYSTEM_DEVICE_INFO)) - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_qfsdevinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), + sizeof(FILE_SYSTEM_DEVICE_INFO)); else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); response_data =3D @@ -5096,7 +5132,8 @@ CIFSSMBQFSUnixInfo(const unsigned int xid, struct cif= s_tcon *tcon) rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); =20 if (rc || get_bcc(&pSMBr->hdr) < 13) { - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_qfsunixinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), 13); } else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); response_data =3D @@ -5244,7 +5281,8 @@ CIFSSMBQFSPosixInfo(const unsigned int xid, struct ci= fs_tcon *tcon, rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); =20 if (rc || get_bcc(&pSMBr->hdr) < 13) { - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_qfsposixinfo_bcc_too_small, + get_bcc(&pSMBr->hdr), 13); } else { __u16 data_offset =3D le16_to_cpu(pSMBr->t2.DataOffset); response_data =3D @@ -6044,7 +6082,8 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tc= on *tcon, =20 rc =3D validate_t2((struct smb_t2_rsp *)pSMBr); if (rc || get_bcc(&pSMBr->hdr) < 4) { - rc =3D -EIO; /* bad smb */ + rc =3D smb_EIO2(smb_eio_trace_qalleas_bcc_too_small, + get_bcc(&pSMBr->hdr), 4); goto QAllEAsOut; } =20 @@ -6074,7 +6113,9 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tc= on *tcon, end_of_smb =3D (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr); if ((char *)ea_response_data + list_len > end_of_smb) { cifs_dbg(FYI, "EA list appears to go beyond SMB\n"); - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_qalleas_overlong, + (unsigned long)ea_response_data + list_len - (unsigned long)pSMBr, + (unsigned long)end_of_smb - (unsigned long)pSMBr); goto QAllEAsOut; } =20 @@ -6091,7 +6132,7 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tc= on *tcon, /* make sure we can read name_len and value_len */ if (list_len < 0) { cifs_dbg(FYI, "EA entry goes beyond length of list\n"); - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len); goto QAllEAsOut; } =20 @@ -6100,7 +6141,7 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tc= on *tcon, list_len -=3D name_len + 1 + value_len; if (list_len < 0) { cifs_dbg(FYI, "EA entry goes beyond length of list\n"); - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len); goto QAllEAsOut; } =20 diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c index 87a246efe695..28d1cee90625 100644 --- a/fs/smb/client/cifstransport.c +++ b/fs/smb/client/cifstransport.c @@ -227,15 +227,15 @@ SendReceive(const unsigned int xid, struct cifs_ses *= ses, int rc =3D 0; =20 if (WARN_ON_ONCE(in_len > 0xffffff)) - return -EIO; + return smb_EIO1(smb_eio_trace_tx_too_long, in_len); if (ses =3D=3D NULL) { cifs_dbg(VFS, "Null smb session\n"); - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); } server =3D ses->server; if (server =3D=3D NULL) { cifs_dbg(VFS, "Null tcp session\n"); - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); } =20 /* Ensure that we do not send more than 50 overlapping requests @@ -245,7 +245,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *se= s, if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { cifs_server_dbg(VFS, "Invalid length, greater than maximum frame, %d\n", in_len); - return -EIO; + return smb_EIO1(smb_eio_trace_tx_too_long, in_len); } =20 rc =3D cifs_send_recv(xid, ses, ses->server, diff --git a/fs/smb/client/compress.c b/fs/smb/client/compress.c index db709f5cd2e1..f03dd9804427 100644 --- a/fs/smb/client/compress.c +++ b/fs/smb/client/compress.c @@ -310,7 +310,7 @@ int smb_compress(struct TCP_Server_Info *server, struct= smb_rqst *rq, compress_s iter =3D rq->rq_iter; =20 if (!copy_from_iter_full(src, slen, &iter)) { - ret =3D -EIO; + ret =3D smb_EIO(smb_eio_trace_compress_copy); goto err_free; } =20 diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index 59f1affc4790..70e56d980ba8 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -3240,7 +3240,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server) if (be16_to_cpu(resp.length) !=3D 0) { cifs_dbg(VFS, "RFC 1002 positive session response but with invalid non-= zero length %u\n", be16_to_cpu(resp.length)); - return -EIO; + return smb_EIO(smb_eio_trace_rx_pos_sess_resp); } cifs_dbg(FYI, "RFC 1002 positive session response"); break; @@ -3279,17 +3279,18 @@ ip_rfc1001_connect(struct TCP_Server_Info *server) break; case RFC1002_INSUFFICIENT_RESOURCE: /* remote server resource error */ + smb_EIO(smb_eio_trace_rx_insuff_res); rc =3D -EREMOTEIO; break; case RFC1002_UNSPECIFIED_ERROR: default: /* other/unknown error */ - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_rx_unspec_error); break; } } else { cifs_dbg(VFS, "RFC 1002 negative session response\n"); - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_rx_neg_sess_resp); } return rc; case RFC1002_RETARGET_SESSION_RESPONSE: @@ -3311,7 +3312,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server) return -EMULTIHOP; default: cifs_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", resp.type); - return -EIO; + return smb_EIO1(smb_eio_trace_rx_unknown_resp, resp.type); } =20 server->with_rfc1001 =3D true; @@ -4001,7 +4002,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses, __u16 bytes_left, count; =20 if (ses =3D=3D NULL) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 smb_buffer =3D cifs_buf_get(); if (smb_buffer =3D=3D NULL) diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index da5597dbf5b9..4ad69dc77e09 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -471,7 +471,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *di= rentry, struct cifs_open_info_data buf =3D {}; =20 if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); =20 /* * Posix open is only called (at lookup time) for file create now. For @@ -589,7 +589,7 @@ int cifs_create(struct mnt_idmap *idmap, struct inode *= inode, inode, direntry, direntry); =20 if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) { - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_forced_shutdown); goto out_free_xid; } =20 @@ -631,7 +631,7 @@ int cifs_mknod(struct mnt_idmap *idmap, struct inode *i= node, =20 cifs_sb =3D CIFS_SB(inode->i_sb); if (unlikely(cifs_forced_shutdown(cifs_sb))) - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); =20 tlink =3D cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 474dadeb1593..0c01d5736e45 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -117,7 +117,7 @@ static void cifs_issue_write(struct netfs_io_subrequest= *subreq) int rc; =20 if (cifs_forced_shutdown(sbi)) { - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_forced_shutdown); goto fail; } =20 @@ -285,7 +285,7 @@ static int cifs_init_request(struct netfs_io_request *r= req, struct file *file) req->pid =3D req->cfile->pid; } else if (rreq->origin !=3D NETFS_WRITEBACK) { WARN_ON_ONCE(1); - return -EIO; + return smb_EIO1(smb_eio_trace_not_netfs_writeback, rreq->origin); } =20 return 0; @@ -1035,7 +1035,7 @@ int cifs_open(struct inode *inode, struct file *file) cifs_sb =3D CIFS_SB(inode->i_sb); if (unlikely(cifs_forced_shutdown(cifs_sb))) { free_xid(xid); - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); } =20 tlink =3D cifs_sb_tlink(cifs_sb); diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index c2ac39d89df2..d30f2fe296e9 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -1951,7 +1951,7 @@ static int __cifs_unlink(struct inode *dir, struct de= ntry *dentry, bool sillyren cifs_dbg(FYI, "cifs_unlink, dir=3D0x%p, dentry=3D0x%p\n", dir, dentry); =20 if (unlikely(cifs_forced_shutdown(cifs_sb))) - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); =20 /* Unhash dentry in advance to prevent any concurrent opens */ spin_lock(&dentry->d_lock); @@ -2267,7 +2267,7 @@ struct dentry *cifs_mkdir(struct mnt_idmap *idmap, st= ruct inode *inode, =20 cifs_sb =3D CIFS_SB(inode->i_sb); if (unlikely(cifs_forced_shutdown(cifs_sb))) - return ERR_PTR(-EIO); + return ERR_PTR(smb_EIO(smb_eio_trace_forced_shutdown)); tlink =3D cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return ERR_CAST(tlink); @@ -2353,7 +2353,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *di= rentry) =20 cifs_sb =3D CIFS_SB(inode->i_sb); if (unlikely(cifs_forced_shutdown(cifs_sb))) { - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_forced_shutdown); goto rmdir_exit; } =20 @@ -2515,7 +2515,7 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *s= ource_dir, =20 cifs_sb =3D CIFS_SB(source_dir->i_sb); if (unlikely(cifs_forced_shutdown(cifs_sb))) - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); =20 /* * Prevent any concurrent opens on the target by unhashing the dentry. @@ -2900,7 +2900,7 @@ int cifs_getattr(struct mnt_idmap *idmap, const struc= t path *path, int rc; =20 if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); =20 /* * We need to be sure that all dirty pages are written and the server @@ -2975,7 +2975,7 @@ int cifs_fiemap(struct inode *inode, struct fiemap_ex= tent_info *fei, u64 start, int rc; =20 if (unlikely(cifs_forced_shutdown(cifs_sb))) - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); =20 /* * We need to be sure that all dirty pages are written as they @@ -3467,7 +3467,7 @@ cifs_setattr(struct mnt_idmap *idmap, struct dentry *= direntry, #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ =20 if (unlikely(cifs_forced_shutdown(cifs_sb))) - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); /* * Avoid setting [cm]time with O_TRUNC to prevent the server from * disabling automatic timestamp updates as specified in diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c index 70f3c0c67eeb..fdfdc9a3abdd 100644 --- a/fs/smb/client/link.c +++ b/fs/smb/client/link.c @@ -160,7 +160,8 @@ create_mf_symlink(const unsigned int xid, struct cifs_t= con *tcon, goto out; =20 if (bytes_written !=3D CIFS_MF_SYMLINK_FILE_SIZE) - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_symlink_file_size, + bytes_written, CIFS_MF_SYMLINK_FILE_SIZE); out: kfree(buf); return rc; @@ -424,7 +425,8 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tc= on *tcon, =20 /* Make sure we wrote all of the symlink data */ if ((rc =3D=3D 0) && (*pbytes_written !=3D CIFS_MF_SYMLINK_FILE_SIZE)) - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_short_symlink_write, + *pbytes_written, CIFS_MF_SYMLINK_FILE_SIZE); =20 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); =20 @@ -451,7 +453,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *in= ode, struct cifsInodeInfo *cifsInode; =20 if (unlikely(cifs_forced_shutdown(cifs_sb))) - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); =20 tlink =3D cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) @@ -553,7 +555,7 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *ino= de, struct inode *newinode =3D NULL; =20 if (unlikely(cifs_forced_shutdown(cifs_sb))) - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); =20 page =3D alloc_dentry_path(); if (!page) diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c index a026dfd68d37..eb7368367c14 100644 --- a/fs/smb/client/misc.c +++ b/fs/smb/client/misc.c @@ -379,25 +379,29 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned in= t total_read, return 0; } cifs_dbg(VFS, "rcvd invalid byte count (bcc)\n"); + return smb_EIO1(smb_eio_trace_rx_inv_bcc, tmp[sizeof(struct smb_hdr)]); } else { cifs_dbg(VFS, "Length less than smb header size\n"); + return smb_EIO2(smb_eio_trace_rx_too_short, + total_read, smb->WordCount); } - return -EIO; } else if (total_read < sizeof(*smb) + 2 * smb->WordCount) { cifs_dbg(VFS, "%s: can't read BCC due to invalid WordCount(%u)\n", __func__, smb->WordCount); - return -EIO; + return smb_EIO2(smb_eio_trace_rx_check_rsp, + total_read, 2 + sizeof(struct smb_hdr)); } =20 /* otherwise, there is enough to get to the BCC */ if (check_smb_hdr(smb)) - return -EIO; + return smb_EIO1(smb_eio_trace_rx_rfc1002_magic, *(u32 *)smb->Protocol); clc_len =3D smbCalcSize(smb); =20 if (rfclen !=3D total_read) { cifs_dbg(VFS, "Length read does not match RFC1001 length %d/%d\n", rfclen, total_read); - return -EIO; + return smb_EIO2(smb_eio_trace_rx_check_rsp, + total_read, rfclen); } =20 if (rfclen !=3D clc_len) { @@ -414,7 +418,8 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int = total_read, if (rfclen < clc_len) { cifs_dbg(VFS, "RFC1001 size %u smaller than SMB for mid=3D%u\n", rfclen, mid); - return -EIO; + return smb_EIO2(smb_eio_trace_rx_calc_len_too_big, + rfclen, clc_len); } else if (rfclen > clc_len + 512) { /* * Some servers (Windows XP in particular) send more @@ -427,7 +432,8 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int = total_read, */ cifs_dbg(VFS, "RFC1001 size %u more than 512 bytes larger than SMB for = mid=3D%u\n", rfclen, mid); - return -EIO; + return smb_EIO2(smb_eio_trace_rx_overlong, + rfclen, clc_len + 512); } } return 0; diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c index ba8a92b430c1..e5a465a018c0 100644 --- a/fs/smb/client/netmisc.c +++ b/fs/smb/client/netmisc.c @@ -885,6 +885,10 @@ map_smb_to_linux_error(char *buf, bool logErr) /* generic corrective action e.g. reconnect SMB session on * ERRbaduid could be added */ =20 + if (rc =3D=3D -EIO) + smb_EIO2(smb_eio_trace_smb1_received_error, + le32_to_cpu(smb->Status.CifsError), + le16_to_cpu(smb->Flags2)); return rc; } =20 diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c index 7ff728503ed1..6844f1dc3921 100644 --- a/fs/smb/client/readdir.c +++ b/fs/smb/client/readdir.c @@ -775,7 +775,7 @@ find_cifs_entry(const unsigned int xid, struct cifs_tco= n *tcon, loff_t pos, =20 if (cfile->srch_inf.ntwrk_buf_start =3D=3D NULL) { cifs_dbg(VFS, "ntwrk_buf_start is NULL during readdir\n"); - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); } =20 end_of_smb =3D cfile->srch_inf.ntwrk_buf_start + diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index 10c84c095fe7..ce9b923498b5 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -732,7 +732,8 @@ static int parse_reparse_nfs(struct reparse_nfs_data_bu= ffer *buf, len =3D le16_to_cpu(buf->ReparseDataLength); if (len < sizeof(buf->InodeType)) { cifs_dbg(VFS, "srv returned malformed nfs buffer\n"); - return -EIO; + return smb_EIO2(smb_eio_trace_reparse_nfs_too_short, + len, sizeof(buf->InodeType)); } =20 len -=3D sizeof(buf->InodeType); @@ -741,7 +742,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_bu= ffer *buf, case NFS_SPECFILE_LNK: if (len =3D=3D 0 || (len % 2)) { cifs_dbg(VFS, "srv returned malformed nfs symlink buffer\n"); - return -EIO; + return smb_EIO1(smb_eio_trace_reparse_nfs_symbuf, len); } /* * Check that buffer does not contain UTF-16 null codepoint @@ -749,7 +750,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_bu= ffer *buf, */ if (UniStrnlen((wchar_t *)buf->DataBuffer, len/2) !=3D len/2) { cifs_dbg(VFS, "srv returned null byte in nfs symlink target location\n"= ); - return -EIO; + return smb_EIO1(smb_eio_trace_reparse_nfs_nul, len); } data->symlink_target =3D cifs_strndup_from_utf16(buf->DataBuffer, len, true, @@ -764,7 +765,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_bu= ffer *buf, /* DataBuffer for block and char devices contains two 32-bit numbers */ if (len !=3D 8) { cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", t= ype); - return -EIO; + return smb_EIO1(smb_eio_trace_reparse_nfs_dev, len); } break; case NFS_SPECFILE_FIFO: @@ -772,7 +773,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_bu= ffer *buf, /* DataBuffer for fifos and sockets is empty */ if (len !=3D 0) { cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", t= ype); - return -EIO; + return smb_EIO1(smb_eio_trace_reparse_nfs_sockfifo, len); } break; default: @@ -796,13 +797,13 @@ int smb2_parse_native_symlink(char **target, const ch= ar *buf, unsigned int len, int abs_path_len; char *abs_path; int levels; - int rc; + int rc, ulen; int i; =20 /* Check that length it valid */ if (!len || (len % 2)) { cifs_dbg(VFS, "srv returned malformed symlink buffer\n"); - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_reparse_native_nul, len); goto out; } =20 @@ -810,9 +811,10 @@ int smb2_parse_native_symlink(char **target, const cha= r *buf, unsigned int len, * Check that buffer does not contain UTF-16 null codepoint * because Linux cannot process symlink with null byte. */ - if (UniStrnlen((wchar_t *)buf, len/2) !=3D len/2) { + ulen =3D UniStrnlen((wchar_t *)buf, len/2); + if (ulen !=3D len/2) { cifs_dbg(VFS, "srv returned null byte in native symlink target location\= n"); - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_reparse_native_nul, ulen, len); goto out; } =20 @@ -996,7 +998,8 @@ static int parse_reparse_native_symlink(struct reparse_= symlink_data_buffer *sym, len =3D le16_to_cpu(sym->SubstituteNameLength); if (offs + 20 > plen || offs + len + 20 > plen) { cifs_dbg(VFS, "srv returned malformed symlink buffer\n"); - return -EIO; + return smb_EIO2(smb_eio_trace_reparse_native_sym_len, + offs << 16 | len, plen); } =20 return smb2_parse_native_symlink(&data->symlink_target, @@ -1019,13 +1022,16 @@ static int parse_reparse_wsl_symlink(struct reparse= _wsl_symlink_data_buffer *buf =20 if (len <=3D data_offset) { cifs_dbg(VFS, "srv returned malformed wsl symlink buffer\n"); - return -EIO; + return smb_EIO2(smb_eio_trace_reparse_wsl_symbuf, + len, data_offset); } =20 /* MS-FSCC 2.1.2.7 defines layout of the Target field only for Version 2.= */ - if (le32_to_cpu(buf->Version) !=3D 2) { - cifs_dbg(VFS, "srv returned unsupported wsl symlink version %u\n", le32_= to_cpu(buf->Version)); - return -EIO; + u32 version =3D le32_to_cpu(buf->Version); + + if (version !=3D 2) { + cifs_dbg(VFS, "srv returned unsupported wsl symlink version %u\n", versi= on); + return smb_EIO1(smb_eio_trace_reparse_wsl_ver, version); } =20 /* Target for Version 2 is in UTF-8 but without trailing null-term byte */ @@ -1034,9 +1040,12 @@ static int parse_reparse_wsl_symlink(struct reparse_= wsl_symlink_data_buffer *buf * Check that buffer does not contain null byte * because Linux cannot process symlink with null byte. */ - if (strnlen(buf->Target, symname_utf8_len) !=3D symname_utf8_len) { + size_t ulen =3D strnlen(buf->Target, symname_utf8_len); + + if (ulen !=3D symname_utf8_len) { cifs_dbg(VFS, "srv returned null byte in wsl symlink target location\n"); - return -EIO; + return smb_EIO2(smb_eio_trace_reparse_wsl_ver, + ulen, symname_utf8_len); } symname_utf16 =3D kzalloc(symname_utf8_len * 2, GFP_KERNEL); if (!symname_utf16) @@ -1083,13 +1092,17 @@ int parse_reparse_point(struct reparse_data_buffer = *buf, case IO_REPARSE_TAG_AF_UNIX: case IO_REPARSE_TAG_LX_FIFO: case IO_REPARSE_TAG_LX_CHR: - case IO_REPARSE_TAG_LX_BLK: - if (le16_to_cpu(buf->ReparseDataLength) !=3D 0) { + case IO_REPARSE_TAG_LX_BLK: { + u16 dlen =3D le16_to_cpu(buf->ReparseDataLength); + + if (dlen !=3D 0) { + u32 rtag =3D le32_to_cpu(buf->ReparseTag); cifs_dbg(VFS, "srv returned malformed buffer for reparse point: 0x%08x\= n", - le32_to_cpu(buf->ReparseTag)); - return -EIO; + rtag); + return smb_EIO2(smb_eio_trace_reparse_data_len, dlen, rtag); } return 0; + } default: return -EOPNOTSUPP; } diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index 752dee5a020c..3e39faf63786 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -1503,7 +1503,7 @@ sess_auth_ntlmv2(struct sess_data *sess_data) smb_buf =3D (struct smb_hdr *)sess_data->iov[0].iov_base; =20 if (smb_buf->WordCount !=3D 3) { - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_sess_nl2_wcc, smb_buf->WordCount); cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount); goto out; } @@ -1629,7 +1629,7 @@ sess_auth_kerberos(struct sess_data *sess_data) smb_buf =3D (struct smb_hdr *)sess_data->iov[0].iov_base; =20 if (smb_buf->WordCount !=3D 4) { - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_sess_krb_wcc, smb_buf->WordCount); cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount); goto out_put_spnego_key; } @@ -1790,7 +1790,7 @@ sess_auth_rawntlmssp_negotiate(struct sess_data *sess= _data) cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n"); =20 if (smb_buf->WordCount !=3D 4) { - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_sess_rawnl_neg_wcc, smb_buf->WordCount); cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount); goto out_free_ntlmsspblob; } @@ -1880,7 +1880,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *s= ess_data) pSMB =3D (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base; smb_buf =3D (struct smb_hdr *)sess_data->iov[0].iov_base; if (smb_buf->WordCount !=3D 4) { - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_sess_rawnl_auth_wcc, smb_buf->WordCount); cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount); goto out_free_ntlmsspblob; } diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c index a7f629238830..68d37f11f3f3 100644 --- a/fs/smb/client/smb2file.c +++ b/fs/smb/client/smb2file.c @@ -76,11 +76,11 @@ int smb2_fix_symlink_target_type(char **target, bool di= rectory, struct cifs_sb_i return 0; =20 if (!*target) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 len =3D strlen(*target); if (!len) - return -EIO; + return smb_EIO1(smb_eio_trace_sym_target_len, len); =20 /* * If this is directory symlink and it does not have trailing slash then @@ -104,7 +104,7 @@ int smb2_fix_symlink_target_type(char **target, bool di= rectory, struct cifs_sb_i * both Windows and Linux systems. So return an error for such symlink. */ if (!directory && (*target)[len-1] =3D=3D '/') - return -EIO; + return smb_EIO(smb_eio_trace_sym_slash); =20 return 0; } diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index d0aad4821ed4..3e45e41f5713 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -31,16 +31,20 @@ static struct reparse_data_buffer *reparse_buf_ptr(stru= ct kvec *iov) struct reparse_data_buffer *buf; struct smb2_ioctl_rsp *io =3D iov->iov_base; u32 off, count, len; + u16 rdlen; =20 count =3D le32_to_cpu(io->OutputCount); off =3D le32_to_cpu(io->OutputOffset); if (check_add_overflow(off, count, &len) || len > iov->iov_len) - return ERR_PTR(-EIO); + return ERR_PTR(smb_EIO2(smb_eio_trace_reparse_overlong, + off, count)); =20 buf =3D (struct reparse_data_buffer *)((u8 *)io + off); len =3D sizeof(*buf); - if (count < len || count < le16_to_cpu(buf->ReparseDataLength) + len) - return ERR_PTR(-EIO); + rdlen =3D le16_to_cpu(buf->ReparseDataLength); + + if (count < len || count < rdlen + len) + return ERR_PTR(smb_EIO2(smb_eio_trace_reparse_rdlen, count, rdlen)); return buf; } =20 @@ -1635,7 +1639,7 @@ int smb2_rename_pending_delete(const char *full_path, } else { cifs_tcon_dbg(FYI, "%s: failed to rename '%s' to '%s': %d\n", __func__, full_path, to_name, rc); - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_pend_del_fail, rc); } out: cifs_put_tlink(tlink); diff --git a/fs/smb/client/smb2maperror.c b/fs/smb/client/smb2maperror.c index 12c2b868789f..b179d7369fba 100644 --- a/fs/smb/client/smb2maperror.c +++ b/fs/smb/client/smb2maperror.c @@ -9,6 +9,7 @@ */ #include #include "cifsglob.h" +#include "cifsproto.h" #include "cifs_debug.h" #include "smb2pdu.h" #include "smb2proto.h" @@ -2477,5 +2478,7 @@ map_smb2_to_linux_error(char *buf, bool log_err) le16_to_cpu(shdr->Command), le64_to_cpu(shdr->MessageId), le32_to_cpu(smb2err), rc); + if (rc =3D=3D -EIO) + smb_EIO1(smb_eio_trace_smb2_received_error, le32_to_cpu(smb2err)); return rc; } diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 760edb98ed64..3328d6a89038 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -1046,7 +1046,8 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size, =20 if (src_size < 8 + name_len + 1 + value_len) { cifs_dbg(FYI, "EA entry goes beyond length of list\n"); - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_ea_overrun, + src_size, 8 + name_len + 1 + value_len); goto out; } =20 @@ -1607,7 +1608,7 @@ smb2_ioctl_query_info(const unsigned int xid, } =20 if (!ses || !server) { - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_null_pointers); goto free_vars; } =20 @@ -1942,7 +1943,7 @@ smb2_copychunk_range(const unsigned int xid, if (unlikely(ret_data_len !=3D sizeof(*cc_rsp))) { cifs_tcon_dbg(VFS, "Copychunk invalid response: size %u/%zu\n", ret_data_len, sizeof(*cc_rsp)); - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_copychunk_inv_rsp, ret_data_len); goto out; } =20 @@ -1952,11 +1953,18 @@ smb2_copychunk_range(const unsigned int xid, =20 if (rc =3D=3D 0) { /* Check if server claimed to write more than we asked */ - if (unlikely(!bytes_written || bytes_written > copy_bytes || - !chunks_written || chunks_written > chunks)) { - cifs_tcon_dbg(VFS, "Copychunk invalid response: bytes written %u/%u, c= hunks written %u/%u\n", - bytes_written, copy_bytes, chunks_written, chunks); - rc =3D -EIO; + if (unlikely(!bytes_written || bytes_written > copy_bytes)) { + cifs_tcon_dbg(VFS, "Copychunk invalid response: bytes written %u/%u\n", + bytes_written, copy_bytes); + rc =3D smb_EIO2(smb_eio_trace_copychunk_overcopy_b, + bytes_written, copy_bytes); + goto out; + } + if (unlikely(!chunks_written || chunks_written > chunks)) { + cifs_tcon_dbg(VFS, "Copychunk invalid response: chunks written %u/%u\n= ", + chunks_written, chunks); + rc =3D smb_EIO2(smb_eio_trace_copychunk_overcopy_c, + chunks_written, chunks); goto out; } =20 @@ -3127,7 +3135,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cif= s_ses *ses, } =20 if (!rc && !dfs_rsp) - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_dfsref_no_rsp); if (rc) { if (!is_retryable_error(rc) && rc !=3D -ENOENT && rc !=3D -EOPNOTSUPP) cifs_tcon_dbg(FYI, "%s: ioctl error: rc=3D%d\n", __func__, rc); @@ -4555,7 +4563,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server= , int num_rqst, buffer, 0, 0, size); =20 if (!cifs_copy_iter_to_folioq(&old->rq_iter, size, buffer)) { - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_tx_copy_iter_to_buf, size); goto err_free; } } @@ -4656,7 +4664,8 @@ cifs_copy_folioq_to_iter(struct folio_queue *folioq, = size_t data_size, n =3D copy_folio_to_iter(folio, skip, len, iter); if (n !=3D len) { cifs_dbg(VFS, "%s: something went wrong\n", __func__); - return -EIO; + return smb_EIO2(smb_eio_trace_rx_copy_to_iter, + n, len); } data_size -=3D n; skip =3D 0; @@ -4739,7 +4748,7 @@ handle_read_data(struct TCP_Server_Info *server, stru= ct mid_q_entry *mid, /* data_offset is beyond the end of smallbuf */ cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n", __func__, data_offset); - rdata->result =3D -EIO; + rdata->result =3D smb_EIO1(smb_eio_trace_rx_overlong, data_offset); if (is_offloaded) mid->mid_state =3D MID_RESPONSE_MALFORMED; else @@ -4758,7 +4767,7 @@ handle_read_data(struct TCP_Server_Info *server, stru= ct mid_q_entry *mid, /* data offset is beyond the 1st page of response */ cifs_dbg(FYI, "%s: data offset (%u) beyond 1st page of response\n", __func__, data_offset); - rdata->result =3D -EIO; + rdata->result =3D smb_EIO1(smb_eio_trace_rx_overpage, data_offset); if (is_offloaded) mid->mid_state =3D MID_RESPONSE_MALFORMED; else @@ -4768,7 +4777,7 @@ handle_read_data(struct TCP_Server_Info *server, stru= ct mid_q_entry *mid, =20 if (data_len > buffer_len - pad_len) { /* data_len is corrupt -- discard frame */ - rdata->result =3D -EIO; + rdata->result =3D smb_EIO1(smb_eio_trace_rx_bad_datalen, data_len); if (is_offloaded) mid->mid_state =3D MID_RESPONSE_MALFORMED; else @@ -4793,12 +4802,12 @@ handle_read_data(struct TCP_Server_Info *server, st= ruct mid_q_entry *mid, WARN_ONCE(buffer, "read data can be either in buf or in buffer"); copied =3D copy_to_iter(buf + data_offset, data_len, &rdata->subreq.io_i= ter); if (copied =3D=3D 0) - return -EIO; + return smb_EIO2(smb_eio_trace_rx_copy_to_iter, copied, data_len); rdata->got_bytes =3D copied; } else { /* read response payload cannot be in both buf and pages */ WARN_ONCE(1, "buf can not contain only a part of read data"); - rdata->result =3D -EIO; + rdata->result =3D smb_EIO(smb_eio_trace_rx_both_buf); if (is_offloaded) mid->mid_state =3D MID_RESPONSE_MALFORMED; else diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 910703d8efb5..1aefe5079362 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -249,15 +249,15 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon = *tcon, =20 ses =3D tcon->ses; if (!ses) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); spin_lock(&ses->ses_lock); if (ses->ses_status =3D=3D SES_EXITING) { spin_unlock(&ses->ses_lock); - return -EIO; + return smb_EIO(smb_eio_trace_sess_exiting); } spin_unlock(&ses->ses_lock); if (!ses->server || !server) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 spin_lock(&server->srv_lock); if (server->tcpStatus =3D=3D CifsNeedReconnect) { @@ -1061,7 +1061,7 @@ SMB2_negotiate(const unsigned int xid, =20 if (!server) { WARN(1, "%s: server is NULL!\n", __func__); - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); } =20 rc =3D smb2_plain_req_init(SMB2_NEGOTIATE, NULL, server, @@ -1142,64 +1142,84 @@ SMB2_negotiate(const unsigned int xid, } else if (rc !=3D 0) goto neg_exit; =20 - rc =3D -EIO; + u16 dialect =3D le16_to_cpu(rsp->DialectRevision); if (strcmp(server->vals->version_string, SMB3ANY_VERSION_STRING) =3D=3D 0) { - if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB20_PROT_ID)) { + switch (dialect) { + case SMB20_PROT_ID: cifs_server_dbg(VFS, "SMB2 dialect returned but not requested\n"); + rc =3D smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 3); goto neg_exit; - } else if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB21_PROT_ID)) { + case SMB21_PROT_ID: cifs_server_dbg(VFS, "SMB2.1 dialect returned but not requested\n"); + rc =3D smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 3); goto neg_exit; - } else if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB311_PROT_ID)) { + case SMB311_PROT_ID: /* ops set to 3.0 by default for default so update */ server->ops =3D &smb311_operations; server->vals =3D &smb311_values; + break; + default: + break; } } else if (strcmp(server->vals->version_string, - SMBDEFAULT_VERSION_STRING) =3D=3D 0) { - if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB20_PROT_ID)) { + SMBDEFAULT_VERSION_STRING) =3D=3D 0) { + switch (dialect) { + case SMB20_PROT_ID: cifs_server_dbg(VFS, "SMB2 dialect returned but not requested\n"); + rc =3D smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 0); goto neg_exit; - } else if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB21_PROT_ID)) { + case SMB21_PROT_ID: /* ops set to 3.0 by default for default so update */ server->ops =3D &smb21_operations; server->vals =3D &smb21_values; - } else if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB311_PROT_ID)) { + break; + case SMB311_PROT_ID: server->ops =3D &smb311_operations; server->vals =3D &smb311_values; + break; + default: + break; } - } else if (le16_to_cpu(rsp->DialectRevision) !=3D - server->vals->protocol_id) { + } else if (dialect !=3D server->vals->protocol_id) { /* if requested single dialect ensure returned dialect matched */ cifs_server_dbg(VFS, "Invalid 0x%x dialect returned: not requested\n", - le16_to_cpu(rsp->DialectRevision)); + dialect); + rc =3D smb_EIO2(smb_eio_trace_neg_unreq_dialect, + dialect, server->vals->protocol_id); goto neg_exit; } =20 cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode); =20 - if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB20_PROT_ID)) + switch (dialect) { + case SMB20_PROT_ID: cifs_dbg(FYI, "negotiated smb2.0 dialect\n"); - else if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB21_PROT_ID)) + break; + case SMB21_PROT_ID: cifs_dbg(FYI, "negotiated smb2.1 dialect\n"); - else if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB30_PROT_ID)) + break; + case SMB30_PROT_ID: cifs_dbg(FYI, "negotiated smb3.0 dialect\n"); - else if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB302_PROT_ID)) + break; + case SMB302_PROT_ID: cifs_dbg(FYI, "negotiated smb3.02 dialect\n"); - else if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB311_PROT_ID)) + break; + case SMB311_PROT_ID: cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n"); - else { + break; + default: cifs_server_dbg(VFS, "Invalid dialect returned by server 0x%x\n", - le16_to_cpu(rsp->DialectRevision)); + dialect); + rc =3D smb_EIO1(smb_eio_trace_neg_inval_dialect, dialect); goto neg_exit; } =20 rc =3D 0; - server->dialect =3D le16_to_cpu(rsp->DialectRevision); + server->dialect =3D dialect; =20 /* * Keep a copy of the hash after negprot. This hash will be @@ -1255,10 +1275,10 @@ SMB2_negotiate(const unsigned int xid, if (rc =3D=3D 1) rc =3D 0; else if (rc =3D=3D 0) - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_neg_decode_token, rc); } =20 - if (rsp->DialectRevision =3D=3D cpu_to_le16(SMB311_PROT_ID)) { + if (server->dialect =3D=3D SMB311_PROT_ID) { if (rsp->NegotiateContextCount) rc =3D smb311_decode_neg_context(rsp, server, rsp_iov.iov_len); @@ -1371,32 +1391,47 @@ int smb3_validate_negotiate(const unsigned int xid,= struct cifs_tcon *tcon) } else if (rc !=3D 0) { cifs_tcon_dbg(VFS, "validate protocol negotiate failed: %d\n", rc); - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_neg_info_fail, rc); goto out_free_inbuf; } =20 - rc =3D -EIO; if (rsplen !=3D sizeof(*pneg_rsp)) { cifs_tcon_dbg(VFS, "Invalid protocol negotiate response size: %d\n", rsplen); =20 /* relax check since Mac returns max bufsize allowed on ioctl */ - if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp)) + if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp)) { + rc =3D smb_EIO1(smb_eio_trace_neg_bad_rsplen, rsplen); goto out_free_rsp; + } } =20 /* check validate negotiate info response matches what we got earlier */ - if (pneg_rsp->Dialect !=3D cpu_to_le16(server->dialect)) + u16 dialect =3D le16_to_cpu(pneg_rsp->Dialect); + + if (dialect !=3D server->dialect) { + rc =3D smb_EIO2(smb_eio_trace_neg_info_dialect, + dialect, server->dialect); goto vneg_out; + } =20 - if (pneg_rsp->SecurityMode !=3D cpu_to_le16(server->sec_mode)) + u16 sec_mode =3D le16_to_cpu(pneg_rsp->SecurityMode); + + if (sec_mode !=3D server->sec_mode) { + rc =3D smb_EIO2(smb_eio_trace_neg_info_sec_mode, + sec_mode, server->sec_mode); goto vneg_out; + } =20 /* do not validate server guid because not saved at negprot time yet */ + u32 caps =3D le32_to_cpu(pneg_rsp->Capabilities); =20 - if ((le32_to_cpu(pneg_rsp->Capabilities) | SMB2_NT_FIND | - SMB2_LARGE_FILES) !=3D server->capabilities) + if ((caps | SMB2_NT_FIND | + SMB2_LARGE_FILES) !=3D server->capabilities) { + rc =3D smb_EIO2(smb_eio_trace_neg_info_caps, + caps, server->capabilities); goto vneg_out; + } =20 /* validate negotiate successful */ rc =3D 0; @@ -1758,11 +1793,11 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_ses= s_data *sess_data) if (rc) goto out; =20 - if (offsetof(struct smb2_sess_setup_rsp, Buffer) !=3D - le16_to_cpu(rsp->SecurityBufferOffset)) { - cifs_dbg(VFS, "Invalid security buffer offset %d\n", - le16_to_cpu(rsp->SecurityBufferOffset)); - rc =3D -EIO; + u16 boff =3D le16_to_cpu(rsp->SecurityBufferOffset); + + if (offsetof(struct smb2_sess_setup_rsp, Buffer) !=3D boff) { + cifs_dbg(VFS, "Invalid security buffer offset %d\n", boff); + rc =3D smb_EIO1(smb_eio_trace_sess_buf_off, boff); goto out; } rc =3D decode_ntlmssp_challenge(rsp->Buffer, @@ -1916,7 +1951,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_s= es *ses, =20 if (!server) { WARN(1, "%s: server is NULL!\n", __func__); - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); } =20 sess_data =3D kzalloc(sizeof(struct SMB2_sess_data), GFP_KERNEL); @@ -1966,10 +2001,9 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses = *ses) =20 cifs_dbg(FYI, "disconnect session %p\n", ses); =20 - if (ses && (ses->server)) - server =3D ses->server; - else - return -EIO; + if (!ses || !ses->server) + return smb_EIO(smb_eio_trace_null_pointers); + server =3D ses->server; =20 /* no need to send SMB logoff if uid already closed due to reconnect */ spin_lock(&ses->chan_lock); @@ -2048,7 +2082,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *se= s, const char *tree, cifs_dbg(FYI, "TCON\n"); =20 if (!server || !tree) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 unc_path =3D kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL); if (unc_path =3D=3D NULL) @@ -2186,7 +2220,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *t= con) cifs_dbg(FYI, "Tree Disconnect\n"); =20 if (!ses || !(ses->server)) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 trace_smb3_tdis_enter(xid, tcon->tid, ses->Suid, tcon->tree_name); spin_lock(&ses->chan_lock); @@ -2856,7 +2890,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct= inode *inode, return -ENOMEM; =20 if (!ses || !server) { - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_null_pointers); goto err_free_path; } =20 @@ -2973,7 +3007,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct= inode *inode, */ rsp =3D (struct smb2_create_rsp *)rsp_iov.iov_base; if (rsp =3D=3D NULL) { - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_mkdir_no_rsp); kfree(pc_buf); goto err_free_req; } @@ -3211,7 +3245,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_pa= rms *oparms, __le16 *path, =20 cifs_dbg(FYI, "create/open\n"); if (!ses || !server) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 if (smb3_encryption_required(tcon)) flags |=3D CIFS_TRANSFORM_REQ; @@ -3417,11 +3451,11 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon= *tcon, u64 persistent_fid, int retries =3D 0, cur_sleep =3D 1; =20 if (!tcon) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 ses =3D tcon->ses; if (!ses) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 replay_again: /* reinitialize for possible replay */ @@ -3429,7 +3463,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *= tcon, u64 persistent_fid, server =3D cifs_pick_channel(ses); =20 if (!server) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 cifs_dbg(FYI, "SMB2 IOCTL\n"); =20 @@ -3492,7 +3526,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *= tcon, u64 persistent_fid, * warning) */ if (rsp =3D=3D NULL) { - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_ioctl_no_rsp); goto ioctl_exit; } =20 @@ -3503,16 +3537,18 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon= *tcon, u64 persistent_fid, goto ioctl_exit; /* server returned no data */ else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) { cifs_tcon_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen); + rc =3D smb_EIO2(smb_eio_trace_ioctl_data_len, *plen, rsp_iov.iov_len); *plen =3D 0; - rc =3D -EIO; goto ioctl_exit; } =20 - if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) { - cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen, - le32_to_cpu(rsp->OutputOffset)); + u32 outoff =3D le32_to_cpu(rsp->OutputOffset); + + if (rsp_iov.iov_len - *plen < outoff) { + cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", + *plen, outoff); + rc =3D smb_EIO2(smb_eio_trace_ioctl_out_off, rsp_iov.iov_len - *plen, ou= toff); *plen =3D 0; - rc =3D -EIO; goto ioctl_exit; } =20 @@ -3620,7 +3656,7 @@ __SMB2_close(const unsigned int xid, struct cifs_tcon= *tcon, cifs_dbg(FYI, "Close\n"); =20 if (!ses || !server) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 if (smb3_encryption_required(tcon)) flags |=3D CIFS_TRANSFORM_REQ; @@ -3817,7 +3853,7 @@ query_info(const unsigned int xid, struct cifs_tcon *= tcon, cifs_dbg(FYI, "Query Info\n"); =20 if (!ses) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 replay_again: /* reinitialize for possible replay */ @@ -3826,7 +3862,7 @@ query_info(const unsigned int xid, struct cifs_tcon *= tcon, server =3D cifs_pick_channel(ses); =20 if (!server) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 if (smb3_encryption_required(tcon)) flags |=3D CIFS_TRANSFORM_REQ; @@ -4011,7 +4047,7 @@ SMB2_change_notify(const unsigned int xid, struct cif= s_tcon *tcon, =20 cifs_dbg(FYI, "change notify\n"); if (!ses || !server) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 if (smb3_encryption_required(tcon)) flags |=3D CIFS_TRANSFORM_REQ; @@ -4347,7 +4383,7 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *= tcon, u64 persistent_fid, =20 cifs_dbg(FYI, "flush\n"); if (!ses || !(ses->server)) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 if (smb3_encryption_required(tcon)) flags |=3D CIFS_TRANSFORM_REQ; @@ -4582,11 +4618,12 @@ smb2_readv_callback(struct TCP_Server_Info *server,= struct mid_q_entry *mid) trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed); credits.value =3D le16_to_cpu(shdr->CreditRequest); credits.instance =3D server->reconnect_instance; - rdata->result =3D -EIO; + rdata->result =3D smb_EIO(smb_eio_trace_read_rsp_malformed); break; default: trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown); - rdata->result =3D -EIO; + rdata->result =3D smb_EIO1(smb_eio_trace_read_mid_state_unknown, + mid->mid_state); break; } #ifdef CONFIG_CIFS_SMB_DIRECT @@ -4795,7 +4832,8 @@ SMB2_read(const unsigned int xid, struct cifs_io_parm= s *io_parms, (*nbytes > io_parms->length)) { cifs_dbg(FYI, "bad length %d for count %d\n", *nbytes, io_parms->length); - rc =3D -EIO; + rc =3D smb_EIO2(smb_eio_trace_read_overlarge, + *nbytes, io_parms->length); *nbytes =3D 0; } =20 @@ -4881,11 +4919,12 @@ smb2_writev_callback(struct TCP_Server_Info *server= , struct mid_q_entry *mid) trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed); credits.value =3D le16_to_cpu(rsp->hdr.CreditRequest); credits.instance =3D server->reconnect_instance; - result =3D -EIO; + result =3D smb_EIO(smb_eio_trace_write_rsp_malformed); break; default: trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown); - result =3D -EIO; + result =3D smb_EIO1(smb_eio_trace_write_mid_state_unknown, + mid->mid_state); break; } #ifdef CONFIG_CIFS_SMB_DIRECT @@ -5528,7 +5567,7 @@ SMB2_query_directory(const unsigned int xid, struct c= ifs_tcon *tcon, server =3D cifs_pick_channel(ses); =20 if (!ses || !(ses->server)) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 if (smb3_encryption_required(tcon)) flags |=3D CIFS_TRANSFORM_REQ; @@ -5663,7 +5702,7 @@ send_set_info(const unsigned int xid, struct cifs_tco= n *tcon, server =3D cifs_pick_channel(ses); =20 if (!ses || !server) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 if (!num) return -EINVAL; @@ -5860,7 +5899,7 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon= *tcon, cifs_dbg(FYI, "Query FSInfo level %d\n", level); =20 if ((tcon->ses =3D=3D NULL) || server =3D=3D NULL) - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); =20 rc =3D smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server, (void **) &req, &total_len); diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c index 99fa48bcd459..8b9000a83181 100644 --- a/fs/smb/client/smb2transport.c +++ b/fs/smb/client/smb2transport.c @@ -153,7 +153,7 @@ static int smb2_get_sign_key(struct TCP_Server_Info *se= rver, memcpy(key, ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE); } else { - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_no_auth_key); } break; default: diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h index 28e00c34df1c..252073352e79 100644 --- a/fs/smb/client/trace.h +++ b/fs/smb/client/trace.h @@ -20,6 +20,136 @@ /* * Specify enums for tracing information. */ +#define smb_eio_traces \ + EM(smb_eio_trace_compress_copy, "compress_copy") \ + EM(smb_eio_trace_copychunk_inv_rsp, "copychunk_inv_rsp") \ + EM(smb_eio_trace_copychunk_overcopy_b, "copychunk_overcopy_b") \ + EM(smb_eio_trace_copychunk_overcopy_c, "copychunk_overcopy_c") \ + EM(smb_eio_trace_create_rsp_too_small, "create_rsp_too_small") \ + EM(smb_eio_trace_dfsref_no_rsp, "dfsref_no_rsp") \ + EM(smb_eio_trace_ea_overrun, "ea_overrun") \ + EM(smb_eio_trace_extract_will_pin, "extract_will_pin") \ + EM(smb_eio_trace_forced_shutdown, "forced_shutdown") \ + EM(smb_eio_trace_getacl_bcc_too_small, "getacl_bcc_too_small") \ + EM(smb_eio_trace_getcifsacl_param_count, "getcifsacl_param_count") \ + EM(smb_eio_trace_getdfsrefer_bcc_too_small, "getdfsrefer_bcc_too_small") \ + EM(smb_eio_trace_getextattr_bcc_too_small, "getextattr_bcc_too_small") \ + EM(smb_eio_trace_getextattr_inv_size, "getextattr_inv_size") \ + EM(smb_eio_trace_getsrvinonum_bcc_too_small, "getsrvinonum_bcc_too_small"= ) \ + EM(smb_eio_trace_getsrvinonum_size, "getsrvinonum_size") \ + EM(smb_eio_trace_ioctl_data_len, "ioctl_data_len") \ + EM(smb_eio_trace_ioctl_no_rsp, "ioctl_no_rsp") \ + EM(smb_eio_trace_ioctl_out_off, "ioctl_out_off") \ + EM(smb_eio_trace_lock_bcc_too_small, "lock_bcc_too_small") \ + EM(smb_eio_trace_lock_data_too_small, "lock_data_too_small") \ + EM(smb_eio_trace_malformed_ksid_key, "malformed_ksid_key") \ + EM(smb_eio_trace_malformed_sid_key, "malformed_sid_key") \ + EM(smb_eio_trace_mkdir_no_rsp, "mkdir_no_rsp") \ + EM(smb_eio_trace_neg_bad_rsplen, "neg_bad_rsplen") \ + EM(smb_eio_trace_neg_decode_token, "neg_decode_token") \ + EM(smb_eio_trace_neg_info_caps, "neg_info_caps") \ + EM(smb_eio_trace_neg_info_dialect, "neg_info_dialect") \ + EM(smb_eio_trace_neg_info_fail, "neg_info_fail") \ + EM(smb_eio_trace_neg_info_sec_mode, "neg_info_sec_mode") \ + EM(smb_eio_trace_neg_inval_dialect, "neg_inval_dialect") \ + EM(smb_eio_trace_neg_no_crypt_key, "neg_no_crypt_key") \ + EM(smb_eio_trace_neg_sec_blob_too_small, "neg_sec_blob_too_small") \ + EM(smb_eio_trace_neg_unreq_dialect, "neg_unreq_dialect") \ + EM(smb_eio_trace_no_auth_key, "no_auth_key") \ + EM(smb_eio_trace_no_lease_key, "no_lease_key") \ + EM(smb_eio_trace_not_netfs_writeback, "not_netfs_writeback") \ + EM(smb_eio_trace_null_pointers, "null_pointers") \ + EM(smb_eio_trace_oldqfsinfo_bcc_too_small, "oldqfsinfo_bcc_too_small") \ + EM(smb_eio_trace_pend_del_fail, "pend_del_fail") \ + EM(smb_eio_trace_qalleas_bcc_too_small, "qalleas_bcc_too_small") \ + EM(smb_eio_trace_qalleas_ea_overlong, "qalleas_ea_overlong") \ + EM(smb_eio_trace_qalleas_overlong, "qalleas_overlong") \ + EM(smb_eio_trace_qfileinfo_bcc_too_small, "qfileinfo_bcc_too_small") \ + EM(smb_eio_trace_qfileinfo_invalid, "qfileinfo_invalid") \ + EM(smb_eio_trace_qfsattrinfo_bcc_too_small, "qfsattrinfo_bcc_too_small") \ + EM(smb_eio_trace_qfsdevinfo_bcc_too_small, "qfsdevinfo_bcc_too_small") \ + EM(smb_eio_trace_qfsinfo_bcc_too_small, "qfsinfo_bcc_too_small") \ + EM(smb_eio_trace_qfsposixinfo_bcc_too_small, "qfsposixinfo_bcc_too_small"= ) \ + EM(smb_eio_trace_qfsunixinfo_bcc_too_small, "qfsunixinfo_bcc_too_small") \ + EM(smb_eio_trace_qpathinfo_bcc_too_small, "qpathinfo_bcc_too_small") \ + EM(smb_eio_trace_qpathinfo_invalid, "qpathinfo_invalid") \ + EM(smb_eio_trace_qreparse_data_area, "qreparse_data_area") \ + EM(smb_eio_trace_qreparse_rep_datalen, "qreparse_rep_datalen") \ + EM(smb_eio_trace_qreparse_ret_datalen, "qreparse_ret_datalen") \ + EM(smb_eio_trace_qreparse_setup_count, "qreparse_setup_count") \ + EM(smb_eio_trace_qreparse_sizes_wrong, "qreparse_sizes_wrong") \ + EM(smb_eio_trace_qsym_bcc_too_small, "qsym_bcc_too_small") \ + EM(smb_eio_trace_read_mid_state_unknown, "read_mid_state_unknown") \ + EM(smb_eio_trace_read_overlarge, "read_overlarge") \ + EM(smb_eio_trace_read_rsp_malformed, "read_rsp_malformed") \ + EM(smb_eio_trace_read_rsp_short, "read_rsp_short") \ + EM(smb_eio_trace_read_too_far, "read_too_far") \ + EM(smb_eio_trace_reparse_data_len, "reparse_data_len") \ + EM(smb_eio_trace_reparse_native_len, "reparse_native_len") \ + EM(smb_eio_trace_reparse_native_nul, "reparse_native_nul") \ + EM(smb_eio_trace_reparse_native_sym_len, "reparse_native_sym_len") \ + EM(smb_eio_trace_reparse_nfs_dev, "reparse_nfs_dev") \ + EM(smb_eio_trace_reparse_nfs_nul, "reparse_nfs_nul") \ + EM(smb_eio_trace_reparse_nfs_sockfifo, "reparse_nfs_sockfifo") \ + EM(smb_eio_trace_reparse_nfs_symbuf, "reparse_nfs_symbuf") \ + EM(smb_eio_trace_reparse_nfs_too_short, "reparse_nfs_too_short") \ + EM(smb_eio_trace_reparse_overlong, "reparse_overlong") \ + EM(smb_eio_trace_reparse_rdlen, "reparse_rdlen") \ + EM(smb_eio_trace_reparse_wsl_nul, "reparse_wsl_nul") \ + EM(smb_eio_trace_reparse_wsl_symbuf, "reparse_wsl_symbuf") \ + EM(smb_eio_trace_reparse_wsl_ver, "reparse_wsl_ver") \ + EM(smb_eio_trace_rx_b_read_short, "rx_b_read_short") \ + EM(smb_eio_trace_rx_bad_datalen, "rx_bad_datalen") \ + EM(smb_eio_trace_rx_both_buf, "rx_both_buf") \ + EM(smb_eio_trace_rx_calc_len_too_big, "rx_calc_len_too_big") \ + EM(smb_eio_trace_rx_check_rsp, "rx_check_rsp") \ + EM(smb_eio_trace_rx_copy_to_iter, "rx_copy_to_iter") \ + EM(smb_eio_trace_rx_insuff_res, "rx_insuff_res") \ + EM(smb_eio_trace_rx_inv_bcc, "rx_inv_bcc") \ + EM(smb_eio_trace_rx_mid_unready, "rx_mid_unready") \ + EM(smb_eio_trace_rx_neg_sess_resp, "rx_neg_sess_resp") \ + EM(smb_eio_trace_rx_overlong, "rx_overlong") \ + EM(smb_eio_trace_rx_overpage, "rx_overpage") \ + EM(smb_eio_trace_rx_pos_sess_resp, "rx_pos_sess_resp") \ + EM(smb_eio_trace_rx_rfc1002_magic, "rx_rfc1002_magic") \ + EM(smb_eio_trace_rx_sync_mid_invalid, "rx_sync_mid_invalid") \ + EM(smb_eio_trace_rx_sync_mid_malformed, "rx_sync_mid_malformed") \ + EM(smb_eio_trace_rx_too_short, "rx_too_short") \ + EM(smb_eio_trace_rx_trans2_extract, "rx_trans2_extract") \ + EM(smb_eio_trace_rx_unknown_resp, "rx_unknown_resp") \ + EM(smb_eio_trace_rx_unspec_error, "rx_unspec_error") \ + EM(smb_eio_trace_sess_buf_off, "sess_buf_off") \ + EM(smb_eio_trace_sess_exiting, "sess_exiting") \ + EM(smb_eio_trace_sess_krb_wcc, "sess_krb_wcc") \ + EM(smb_eio_trace_sess_nl2_wcc, "sess_nl2_wcc") \ + EM(smb_eio_trace_sess_rawnl_auth_wcc, "sess_rawnl_auth_wcc") \ + EM(smb_eio_trace_sess_rawnl_neg_wcc, "sess_rawnl_neg_wcc") \ + EM(smb_eio_trace_short_symlink_write, "short_symlink_write") \ + EM(smb_eio_trace_sid_too_many_auth, "sid_too_many_auth") \ + EM(smb_eio_trace_sig_data_too_small, "sig_data_too_small") \ + EM(smb_eio_trace_sig_iter, "sig_iter") \ + EM(smb_eio_trace_smb1_received_error, "smb1_received_error") \ + EM(smb_eio_trace_smb2_received_error, "smb2_received_error") \ + EM(smb_eio_trace_sym_slash, "sym_slash") \ + EM(smb_eio_trace_sym_target_len, "sym_target_len") \ + EM(smb_eio_trace_symlink_file_size, "symlink_file_size") \ + EM(smb_eio_trace_tdis_in_reconnect, "tdis_in_reconnect") \ + EM(smb_eio_trace_tx_chained_async, "tx_chained_async") \ + EM(smb_eio_trace_tx_compress_failed, "tx_compress_failed") \ + EM(smb_eio_trace_tx_copy_iter_to_buf, "tx_copy_iter_to_buf") \ + EM(smb_eio_trace_tx_copy_to_buf, "tx_copy_to_buf") \ + EM(smb_eio_trace_tx_max_compound, "tx_max_compound") \ + EM(smb_eio_trace_tx_miscopy_to_buf, "tx_miscopy_to_buf") \ + EM(smb_eio_trace_tx_need_transform, "tx_need_transform") \ + EM(smb_eio_trace_tx_too_long, "sr_too_long") \ + EM(smb_eio_trace_unixqfileinfo_bcc_too_small, "unixqfileinfo_bcc_too_smal= l") \ + EM(smb_eio_trace_unixqpathinfo_bcc_too_small, "unixqpathinfo_bcc_too_smal= l") \ + EM(smb_eio_trace_user_iter, "user_iter") \ + EM(smb_eio_trace_write_bad_buf_type, "write_bad_buf_type") \ + EM(smb_eio_trace_write_mid_state_unknown, "write_mid_state_unknown") \ + EM(smb_eio_trace_write_rsp_malformed, "write_rsp_malformed") \ + E_(smb_eio_trace_write_too_far, "write_too_far") + #define smb3_rw_credits_traces \ EM(cifs_trace_rw_credits_call_readv_adjust, "rd-call-adj") \ EM(cifs_trace_rw_credits_call_writev_adjust, "wr-call-adj") \ @@ -79,6 +209,7 @@ #define EM(a, b) a, #define E_(a, b) a =20 +enum smb_eio_trace { smb_eio_traces } __mode(byte); enum smb3_rw_credits_trace { smb3_rw_credits_traces } __mode(byte); enum smb3_tcon_ref_trace { smb3_tcon_ref_traces } __mode(byte); =20 @@ -92,6 +223,7 @@ enum smb3_tcon_ref_trace { smb3_tcon_ref_traces } __mode= (byte); #define EM(a, b) TRACE_DEFINE_ENUM(a); #define E_(a, b) TRACE_DEFINE_ENUM(a); =20 +smb_eio_traces; smb3_rw_credits_traces; smb3_tcon_ref_traces; =20 @@ -1616,6 +1748,23 @@ TRACE_EVENT(smb3_rw_credits, __entry->server_credits, __entry->in_flight) ); =20 +TRACE_EVENT(smb3_eio, + TP_PROTO(enum smb_eio_trace trace, unsigned long info, unsigned long = info2), + TP_ARGS(trace, info, info2), + TP_STRUCT__entry( + __field(enum smb_eio_trace, trace) + __field(unsigned long, info) + __field(unsigned long, info2) + ), + TP_fast_assign( + __entry->trace =3D trace; + __entry->info =3D info; + __entry->info2 =3D info2; + ), + TP_printk("%s info=3D%lx,%lx", + __print_symbolic(__entry->trace, smb_eio_traces), + __entry->info, __entry->info2) + ); =20 #undef EM #undef E_ diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index c26d1837d527..cb24659df134 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -402,11 +402,11 @@ smb_send_rqst(struct TCP_Server_Info *server, int num= _rqst, return __smb_send_rqst(server, num_rqst, rqst); =20 if (WARN_ON_ONCE(num_rqst > MAX_COMPOUND - 1)) - return -EIO; + return smb_EIO1(smb_eio_trace_tx_max_compound, num_rqst); =20 if (!server->ops->init_transform_rq) { cifs_server_dbg(VFS, "Encryption requested but transform callback is mis= sing\n"); - return -EIO; + return smb_EIO(smb_eio_trace_tx_need_transform); } =20 new_rqst[0].rq_iov =3D &iov; @@ -753,7 +753,7 @@ int cifs_sync_mid_result(struct mid_q_entry *mid, struc= t TCP_Server_Info *server rc =3D -EAGAIN; break; case MID_RESPONSE_MALFORMED: - rc =3D -EIO; + rc =3D smb_EIO(smb_eio_trace_rx_sync_mid_malformed); break; case MID_SHUTDOWN: rc =3D -EHOSTDOWN; @@ -769,7 +769,7 @@ int cifs_sync_mid_result(struct mid_q_entry *mid, struc= t TCP_Server_Info *server spin_unlock(&server->mid_queue_lock); cifs_server_dbg(VFS, "%s: invalid mid state mid=3D%llu state=3D%d\n", __func__, mid->mid, mid->mid_state); - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_rx_sync_mid_invalid, mid->mid_state); goto sync_mid_done; } spin_unlock(&server->mid_queue_lock); @@ -883,7 +883,7 @@ compound_send_recv(const unsigned int xid, struct cifs_= ses *ses, =20 if (!ses || !ses->server || !server) { cifs_dbg(VFS, "Null session\n"); - return -EIO; + return smb_EIO(smb_eio_trace_null_pointers); } =20 spin_lock(&server->srv_lock); @@ -1043,7 +1043,7 @@ compound_send_recv(const unsigned int xid, struct cif= s_ses *ses, =20 if (!mid[i]->resp_buf || mid[i]->mid_state !=3D MID_RESPONSE_READY) { - rc =3D -EIO; + rc =3D smb_EIO1(smb_eio_trace_rx_mid_unready, mid[i]->mid_state); cifs_dbg(FYI, "Bad MID state?\n"); goto out; } @@ -1215,7 +1215,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, st= ruct mid_q_entry *mid) cifs_dbg(FYI, "%s: server returned short header. got=3D%u expected=3D%zu= \n", __func__, server->total_read, server->vals->read_rsp_size); - rdata->result =3D -EIO; + rdata->result =3D smb_EIO2(smb_eio_trace_read_rsp_short, + server->total_read, server->vals->read_rsp_size); return cifs_readv_discard(server, mid); } =20 @@ -1233,7 +1234,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, st= ruct mid_q_entry *mid) /* data_offset is beyond the end of smallbuf */ cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n", __func__, data_offset); - rdata->result =3D -EIO; + rdata->result =3D smb_EIO1(smb_eio_trace_read_overlarge, + data_offset); return cifs_readv_discard(server, mid); } =20 @@ -1257,7 +1259,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, st= ruct mid_q_entry *mid) data_len =3D server->ops->read_data_length(buf, use_rdma_mr); if (!use_rdma_mr && (data_offset + data_len > buflen)) { /* data_len is corrupt -- discard frame */ - rdata->result =3D -EIO; + rdata->result =3D smb_EIO2(smb_eio_trace_read_rsp_malformed, + data_offset + data_len, buflen); return cifs_readv_discard(server, mid); } =20 diff --git a/fs/smb/client/xattr.c b/fs/smb/client/xattr.c index 029910d56c22..6bc89c59164a 100644 --- a/fs/smb/client/xattr.c +++ b/fs/smb/client/xattr.c @@ -397,7 +397,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *d= ata, size_t buf_size) void *page; =20 if (unlikely(cifs_forced_shutdown(cifs_sb))) - return -EIO; + return smb_EIO(smb_eio_trace_forced_shutdown); =20 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) return -EOPNOTSUPP; From nobody Tue Dec 2 00:25:46 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E3632DD61E for ; Mon, 1 Dec 2025 22:58:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629908; cv=none; b=GtXh5yZ0FOoVerViG1RnOTuG2Okfal967918nVDpZeeyR1JPZ2cwQoms9ojzn2dm6Y7pOzDKs52rk4EX7F9OUsuTj6vyWT+Gs/qsNoU9AILdLUvasKHQ3wgmw0pLsOH0QLofW3xmdFOKuWRkbdq/UWwfWh6IALWavG7zE0kXy5M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764629908; c=relaxed/simple; bh=k8jYh0BI234fc0kGSaHO4a6LHOYk/SwnqwTjktiuA4U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ORKyo1iJFVqKeFQ8Rx/U/FJadQNft0YQoRTm/tXRd92IXrrd0dfwsTMzRrIqw4E2+uZrfl72jQxaxgnjdcryEW33gkLDTcG8E4Gp69CsRi/EA5AYUhH+e0abVJTwQA34rnqWQ4Uihc03udynBvc6rHIg7ObHBKRIxIhAHCDhWlQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=OA/2ynYU; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="OA/2ynYU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764629904; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ig3n4lDacU4107oHuN9fgMztG6qlnWMo9On3Lu47abI=; b=OA/2ynYUhKSYxSGdE7SEubEkzrmHmTaARQ5SkNm9rYFZ44BRTlul2rQ35QWxv9z7ISEDgg f5DBrrgWv/4SAC5RGYzgfpwwc7THDx1ydKRp9wwMkBWDfBWkiluChIRqsVd3Hgs39x1UVF huutVlifnhTRzE5jzUu0CeoUhEOp5/U= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-124-E-QenFeUMnS75cNOSKFv4A-1; Mon, 01 Dec 2025 17:58:18 -0500 X-MC-Unique: E-QenFeUMnS75cNOSKFv4A-1 X-Mimecast-MFC-AGG-ID: E-QenFeUMnS75cNOSKFv4A_1764629897 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 18149180048E; Mon, 1 Dec 2025 22:58:17 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.14]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8DB7030001A4; Mon, 1 Dec 2025 22:58:14 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Stefan Metzmacher , Tom Talpey , linux-cifs@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 9/9] cifs: Do some preparation prior to organising the function declarations Date: Mon, 1 Dec 2025 22:57:30 +0000 Message-ID: <20251201225732.1520128-10-dhowells@redhat.com> In-Reply-To: <20251201225732.1520128-1-dhowells@redhat.com> References: <20251201225732.1520128-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" Make some preparatory cleanups prior to running a script to organise the function declarations within the fs/smb/client/ headers. These include: (1) Remove "inline" from the dummy cifs_proc_init/clean() functions as they are in a .c file. (2) Move should_compress()'s kdoc comment to the .c file and remove kdoc markers from the comments. (3) Rename CIFS_ALLOW_INSECURE_LEGACY in #endif comments to have CONFIG_ on the front to allow the script to recognise it. (4) Don't let comments have bare words at the left margin as that confused the simplistic function detection code in the script. (5) Adjust some argument lists so that when and if the cleanup script is run they don't end up over 100 chars. (6) Fix a few comments to have missing '*' added or the "*/" moved to their own lines so that checkpatch doesn't moan over the cleanup script patch. (7) Move struct cifs_calc_sig_ctx to cifsglob.h. (8) Remove some __KERNEL__ conditionals. Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: linux-cifs@vger.kernel.org --- fs/smb/client/cifs_debug.c | 4 ++-- fs/smb/client/cifs_spnego.h | 2 -- fs/smb/client/cifs_unicode.h | 3 --- fs/smb/client/cifsfs.c | 5 +++-- fs/smb/client/cifsglob.h | 8 +++++++- fs/smb/client/cifsproto.h | 7 +------ fs/smb/client/compress.c | 21 ++++++++++++++++++--- fs/smb/client/compress.h | 19 ++----------------- fs/smb/client/dir.c | 2 +- fs/smb/client/dns_resolve.h | 4 ---- fs/smb/client/fs_context.c | 2 +- fs/smb/client/misc.c | 1 + fs/smb/client/netmisc.c | 2 +- fs/smb/client/smb2file.c | 3 ++- fs/smb/client/smb2inode.c | 1 - fs/smb/client/smb2maperror.c | 3 +-- fs/smb/client/smb2ops.c | 4 ++-- fs/smb/client/smb2pdu.c | 5 +++-- fs/smb/client/smb2proto.h | 2 ++ 19 files changed, 47 insertions(+), 51 deletions(-) diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c index 881d3a88d683..2cb234d4bd2f 100644 --- a/fs/smb/client/cifs_debug.c +++ b/fs/smb/client/cifs_debug.c @@ -1318,11 +1318,11 @@ static const struct proc_ops cifs_mount_params_proc= _ops =3D { }; =20 #else -inline void cifs_proc_init(void) +void cifs_proc_init(void) { } =20 -inline void cifs_proc_clean(void) +void cifs_proc_clean(void) { } #endif /* PROC_FS */ diff --git a/fs/smb/client/cifs_spnego.h b/fs/smb/client/cifs_spnego.h index e4d751b0c812..e70929db3611 100644 --- a/fs/smb/client/cifs_spnego.h +++ b/fs/smb/client/cifs_spnego.h @@ -27,10 +27,8 @@ struct cifs_spnego_msg { uint8_t data[]; }; =20 -#ifdef __KERNEL__ extern struct key_type cifs_spnego_key_type; extern struct key *cifs_get_spnego_key(struct cifs_ses *sesInfo, struct TCP_Server_Info *server); -#endif /* KERNEL */ =20 #endif /* _CIFS_SPNEGO_H */ diff --git a/fs/smb/client/cifs_unicode.h b/fs/smb/client/cifs_unicode.h index e137a0dfbbe9..6e4b99786498 100644 --- a/fs/smb/client/cifs_unicode.h +++ b/fs/smb/client/cifs_unicode.h @@ -54,7 +54,6 @@ #define SFM_MAP_UNI_RSVD 1 #define SFU_MAP_UNI_RSVD 2 =20 -#ifdef __KERNEL__ int cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, const struct nls_table *cp, int map_type); int cifs_utf16_bytes(const __le16 *from, int maxbytes, @@ -69,8 +68,6 @@ extern int cifs_remap(struct cifs_sb_info *cifs_sb); extern __le16 *cifs_strndup_to_utf16(const char *src, const int maxlen, int *utf16_len, const struct nls_table *cp, int remap); -#endif - wchar_t cifs_toupper(wchar_t in); =20 #endif /* _CIFS_UNICODE_H */ diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 44d3dec9743b..00eef3a6dc0e 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include "cifsfs.h" @@ -35,10 +37,9 @@ #define DECLARE_GLOBALS_HERE #include "cifsglob.h" #include "cifsproto.h" +#include "smb2proto.h" #include "cifs_debug.h" #include "cifs_fs_sb.h" -#include -#include #include "cifs_spnego.h" #include "fscache.h" #ifdef CONFIG_CIFS_DFS_UPCALL diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index a8cfe9b87a20..f9c1f553ffd0 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -2118,7 +2118,7 @@ extern struct smb_version_operations smb1_operations; extern struct smb_version_values smb1_values; extern struct smb_version_operations smb20_operations; extern struct smb_version_values smb20_values; -#endif /* CIFS_ALLOW_INSECURE_LEGACY */ +#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ extern struct smb_version_operations smb21_operations; extern struct smb_version_values smb21_values; extern struct smb_version_values smbdefault_values; @@ -2286,4 +2286,10 @@ static inline void mid_execute_callback(struct TCP_S= erver_Info *server, (le32_to_cpu((tcon)->fsAttrInfo.Attributes) & \ FILE_SUPPORTS_REPARSE_POINTS)) =20 +struct cifs_calc_sig_ctx { + struct md5_ctx *md5; + struct hmac_sha256_ctx *hmac; + struct shash_desc *shash; +}; + #endif /* _CIFS_GLOB_H */ diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index 5d54de12f0f4..823ca4f36914 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -594,7 +594,7 @@ extern int cifs_do_set_acl(const unsigned int xid, stru= ct cifs_tcon *tcon, const struct nls_table *nls_codepage, int remap); extern int CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon, const int netfid, __u64 *pExtAttrBits, __u64 *pMask); -#endif /* CIFS_ALLOW_INSECURE_LEGACY */ +#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb); extern bool couldbe_mf_symlink(const struct cifs_fattr *fattr); extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, @@ -626,11 +626,6 @@ int cifs_create_mf_symlink(unsigned int xid, struct ci= fs_tcon *tcon, struct cifs_sb_info *cifs_sb, const unsigned char *path, char *pbuf, unsigned int *pbytes_written); -struct cifs_calc_sig_ctx { - struct md5_ctx *md5; - struct hmac_sha256_ctx *hmac; - struct shash_desc *shash; -}; int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *s= erver, char *signature, struct cifs_calc_sig_ctx *ctx); enum securityEnum cifs_select_sectype(struct TCP_Server_Info *, diff --git a/fs/smb/client/compress.c b/fs/smb/client/compress.c index f03dd9804427..e0c44b46080e 100644 --- a/fs/smb/client/compress.c +++ b/fs/smb/client/compress.c @@ -44,7 +44,7 @@ struct bucket { unsigned int count; }; =20 -/** +/* * has_low_entropy() - Compute Shannon entropy of the sampled data. * @bkt: Bytes counts of the sample. * @slen: Size of the sample. @@ -82,7 +82,7 @@ static bool has_low_entropy(struct bucket *bkt, size_t sl= en) #define BYTE_DIST_BAD 0 #define BYTE_DIST_GOOD 1 #define BYTE_DIST_MAYBE 2 -/** +/* * calc_byte_distribution() - Compute byte distribution on the sampled dat= a. * @bkt: Byte counts of the sample. * @slen: Size of the sample. @@ -182,7 +182,7 @@ static int collect_sample(const struct iov_iter *source= , ssize_t max, u8 *sample return s; } =20 -/** +/* * is_compressible() - Determines if a chunk of data is compressible. * @data: Iterator containing uncompressed data. * @@ -261,6 +261,21 @@ static bool is_compressible(const struct iov_iter *dat= a) return ret; } =20 +/* + * should_compress() - Determines if a request (write) or the response to a + * request (read) should be compressed. + * @tcon: tcon of the request is being sent to + * @rqst: request to evaluate + * + * Return: true iff: + * - compression was successfully negotiated with server + * - server has enabled compression for the share + * - it's a read or write request + * - (write only) request length is >=3D SMB_COMPRESS_MIN_LEN + * - (write only) is_compressible() returns 1 + * + * Return false otherwise. + */ bool should_compress(const struct cifs_tcon *tcon, const struct smb_rqst *= rq) { const struct smb2_hdr *shdr =3D rq->rq_iov->iov_base; diff --git a/fs/smb/client/compress.h b/fs/smb/client/compress.h index f3ed1d3e52fb..63aea32fbe92 100644 --- a/fs/smb/client/compress.h +++ b/fs/smb/client/compress.h @@ -29,26 +29,11 @@ #ifdef CONFIG_CIFS_COMPRESSION typedef int (*compress_send_fn)(struct TCP_Server_Info *, int, struct smb_= rqst *); =20 -int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, comp= ress_send_fn send_fn); =20 -/** - * should_compress() - Determines if a request (write) or the response to a - * request (read) should be compressed. - * @tcon: tcon of the request is being sent to - * @rqst: request to evaluate - * - * Return: true iff: - * - compression was successfully negotiated with server - * - server has enabled compression for the share - * - it's a read or write request - * - (write only) request length is >=3D SMB_COMPRESS_MIN_LEN - * - (write only) is_compressible() returns 1 - * - * Return false otherwise. - */ +int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, comp= ress_send_fn send_fn); bool should_compress(const struct cifs_tcon *tcon, const struct smb_rqst *= rq); =20 -/** +/* * smb_compress_alg_valid() - Validate a compression algorithm. * @alg: Compression algorithm to check. * @valid_none: Conditional check whether NONE algorithm should be diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index 4ad69dc77e09..747256025e49 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -457,7 +457,7 @@ static int cifs_do_create(struct inode *inode, struct d= entry *direntry, unsigned =20 int cifs_atomic_open(struct inode *inode, struct dentry *direntry, - struct file *file, unsigned oflags, umode_t mode) + struct file *file, unsigned int oflags, umode_t mode) { int rc; unsigned int xid; diff --git a/fs/smb/client/dns_resolve.h b/fs/smb/client/dns_resolve.h index 0dc706f2c422..36bc4a6a55bf 100644 --- a/fs/smb/client/dns_resolve.h +++ b/fs/smb/client/dns_resolve.h @@ -15,8 +15,6 @@ #include "cifsglob.h" #include "cifsproto.h" =20 -#ifdef __KERNEL__ - int dns_resolve_name(const char *dom, const char *name, size_t namelen, struct sockaddr *ip_addr); =20 @@ -36,6 +34,4 @@ static inline int dns_resolve_unc(const char *dom, const = char *unc, return dns_resolve_name(dom, name, namelen, ip_addr); } =20 -#endif /* KERNEL */ - #endif /* _DNS_RESOLVE_H */ diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c index 2a0d8b87bd8e..0a96bd9d0a16 100644 --- a/fs/smb/client/fs_context.c +++ b/fs/smb/client/fs_context.c @@ -505,7 +505,7 @@ cifs_parse_smb_version(struct fs_context *fc, char *val= ue, struct smb3_fs_contex case Smb_20: cifs_errorf(fc, "vers=3D2.0 mount not permitted when legacy dialects dis= abled\n"); return 1; -#endif /* CIFS_ALLOW_INSECURE_LEGACY */ +#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ case Smb_21: ctx->ops =3D &smb21_operations; ctx->vals =3D &smb21_values; diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c index eb7368367c14..9529fa385938 100644 --- a/fs/smb/client/misc.c +++ b/fs/smb/client/misc.c @@ -18,6 +18,7 @@ #include "nterr.h" #include "cifs_unicode.h" #include "smb2pdu.h" +#include "smb2proto.h" #include "cifsfs.h" #ifdef CONFIG_CIFS_DFS_UPCALL #include "dns_resolve.h" diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c index e5a465a018c0..ae15f0bef009 100644 --- a/fs/smb/client/netmisc.c +++ b/fs/smb/client/netmisc.c @@ -200,7 +200,7 @@ cifs_set_port(struct sockaddr *addr, const unsigned sho= rt int port) } =20 /*************************************************************************= **** -convert a NT status code to a dos class/code + *convert a NT status code to a dos class/code *************************************************************************= ****/ /* NT status -> dos error map */ static const struct { diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c index 68d37f11f3f3..7f11ae6bb785 100644 --- a/fs/smb/client/smb2file.c +++ b/fs/smb/client/smb2file.c @@ -140,7 +140,8 @@ int smb2_parse_symlink_response(struct cifs_sb_info *ci= fs_sb, const struct kvec cifs_sb); } =20 -int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,= __u32 *oplock, void *buf) +int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, + __u32 *oplock, void *buf) { int rc; __le16 *smb2_path; diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index 3e45e41f5713..2ded3246600c 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -21,7 +21,6 @@ #include "cifs_unicode.h" #include "fscache.h" #include "smb2glob.h" -#include "smb2pdu.h" #include "smb2proto.h" #include "cached_dir.h" #include "../common/smb2status.h" diff --git a/fs/smb/client/smb2maperror.c b/fs/smb/client/smb2maperror.c index b179d7369fba..4fc22456c39e 100644 --- a/fs/smb/client/smb2maperror.c +++ b/fs/smb/client/smb2maperror.c @@ -11,10 +11,9 @@ #include "cifsglob.h" #include "cifsproto.h" #include "cifs_debug.h" -#include "smb2pdu.h" #include "smb2proto.h" -#include "../common/smb2status.h" #include "smb2glob.h" +#include "../common/smb2status.h" #include "trace.h" =20 struct status_to_posix_error { diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 3328d6a89038..a16ded46b5a2 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -17,9 +17,9 @@ #include #include "cifsfs.h" #include "cifsglob.h" -#include "smb2pdu.h" -#include "smb2proto.h" #include "cifsproto.h" +#include "smb2proto.h" +#include "smb2pdu.h" #include "cifs_debug.h" #include "cifs_unicode.h" #include "../common/smb2status.h" diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 1aefe5079362..2a822a5188aa 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -26,8 +26,8 @@ #include #include #include "cifsglob.h" -#include "cifsacl.h" #include "cifsproto.h" +#include "cifsacl.h" #include "smb2proto.h" #include "cifs_unicode.h" #include "cifs_debug.h" @@ -3949,7 +3949,8 @@ int SMB2_query_info(const unsigned int xid, struct ci= fs_tcon *tcon, /* currently unused, as now we are doing compounding instead (see smb311_p= osix_query_path_info) */ int SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon, - u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u= 32 *plen) + u64 persistent_fid, u64 volatile_fid, + struct smb311_posix_qinfo *data, u32 *plen) { size_t output_len =3D sizeof(struct smb311_posix_qinfo *) + (sizeof(struct smb_sid) * 2) + (PATH_MAX * 2); diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h index 441df217c796..152e888512aa 100644 --- a/fs/smb/client/smb2proto.h +++ b/fs/smb/client/smb2proto.h @@ -9,8 +9,10 @@ */ #ifndef _SMB2PROTO_H #define _SMB2PROTO_H + #include #include +#include "cached_dir.h" =20 struct statfs; struct smb_rqst;