linux-cifs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/8] smb: client: reduce stack usage in cifs_try_adding_channels()
@ 2023-07-28 19:50 Paulo Alcantara
  2023-07-28 19:50 ` [PATCH 2/8] smb: client: reduce stack usage in smb_send_rqst() Paulo Alcantara
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Paulo Alcantara @ 2023-07-28 19:50 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara, kernel test robot

Clang warns about exceeded stack frame size

  fs/smb/client/sess.c:160:5: warning: stack frame size (1368) exceeds
  limit (1024) in 'cifs_try_adding_channels' [-Wframe-larger-than]

It turns out that cifs_ses_add_channel() got inlined into
cifs_try_adding_channels() which had a stack-allocated variable @ctx
of 624 bytes in size.  Fix this by making it heap-allocated.

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202307270640.5ODmPwDl-lkp@intel.com/
Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/sess.c | 68 ++++++++++++++++++++++++++------------------
 1 file changed, 41 insertions(+), 27 deletions(-)

diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
index c57ca2050b73..5292216d9947 100644
--- a/fs/smb/client/sess.c
+++ b/fs/smb/client/sess.c
@@ -360,11 +360,11 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
 {
 	struct TCP_Server_Info *chan_server;
 	struct cifs_chan *chan;
-	struct smb3_fs_context ctx = {NULL};
+	struct smb3_fs_context *ctx;
 	static const char unc_fmt[] = "\\%s\\foo";
-	char unc[sizeof(unc_fmt)+SERVER_NAME_LEN_WITH_NULL] = {0};
 	struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr;
 	struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr;
+	size_t len;
 	int rc;
 	unsigned int xid = get_xid();
 
@@ -388,54 +388,64 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
 	 * the session and server without caring about memory
 	 * management.
 	 */
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx) {
+		rc = -ENOMEM;
+		goto out_free_xid;
+	}
 
 	/* Always make new connection for now (TODO?) */
-	ctx.nosharesock = true;
+	ctx->nosharesock = true;
 
 	/* Auth */
-	ctx.domainauto = ses->domainAuto;
-	ctx.domainname = ses->domainName;
+	ctx->domainauto = ses->domainAuto;
+	ctx->domainname = ses->domainName;
 
 	/* no hostname for extra channels */
-	ctx.server_hostname = "";
+	ctx->server_hostname = "";
 
-	ctx.username = ses->user_name;
-	ctx.password = ses->password;
-	ctx.sectype = ses->sectype;
-	ctx.sign = ses->sign;
+	ctx->username = ses->user_name;
+	ctx->password = ses->password;
+	ctx->sectype = ses->sectype;
+	ctx->sign = ses->sign;
 
 	/* UNC and paths */
 	/* XXX: Use ses->server->hostname? */
-	sprintf(unc, unc_fmt, ses->ip_addr);
-	ctx.UNC = unc;
-	ctx.prepath = "";
+	len = sizeof(unc_fmt) + SERVER_NAME_LEN_WITH_NULL;
+	ctx->UNC = kzalloc(len, GFP_KERNEL);
+	if (!ctx->UNC) {
+		rc = -ENOMEM;
+		goto out_free_ctx;
+	}
+	scnprintf(ctx->UNC, len, unc_fmt, ses->ip_addr);
+	ctx->prepath = "";
 
 	/* Reuse same version as master connection */
-	ctx.vals = ses->server->vals;
-	ctx.ops = ses->server->ops;
+	ctx->vals = ses->server->vals;
+	ctx->ops = ses->server->ops;
 
-	ctx.noblocksnd = ses->server->noblocksnd;
-	ctx.noautotune = ses->server->noautotune;
-	ctx.sockopt_tcp_nodelay = ses->server->tcp_nodelay;
-	ctx.echo_interval = ses->server->echo_interval / HZ;
-	ctx.max_credits = ses->server->max_credits;
+	ctx->noblocksnd = ses->server->noblocksnd;
+	ctx->noautotune = ses->server->noautotune;
+	ctx->sockopt_tcp_nodelay = ses->server->tcp_nodelay;
+	ctx->echo_interval = ses->server->echo_interval / HZ;
+	ctx->max_credits = ses->server->max_credits;
 
 	/*
 	 * This will be used for encoding/decoding user/domain/pw
 	 * during sess setup auth.
 	 */
-	ctx.local_nls = cifs_sb->local_nls;
+	ctx->local_nls = cifs_sb->local_nls;
 
 	/* Use RDMA if possible */
-	ctx.rdma = iface->rdma_capable;
-	memcpy(&ctx.dstaddr, &iface->sockaddr, sizeof(struct sockaddr_storage));
+	ctx->rdma = iface->rdma_capable;
+	memcpy(&ctx->dstaddr, &iface->sockaddr, sizeof(ctx->dstaddr));
 
 	/* reuse master con client guid */
-	memcpy(&ctx.client_guid, ses->server->client_guid,
-	       SMB2_CLIENT_GUID_SIZE);
-	ctx.use_client_guid = true;
+	memcpy(&ctx->client_guid, ses->server->client_guid,
+	       sizeof(ctx->client_guid));
+	ctx->use_client_guid = true;
 
-	chan_server = cifs_get_tcp_session(&ctx, ses->server);
+	chan_server = cifs_get_tcp_session(ctx, ses->server);
 
 	spin_lock(&ses->chan_lock);
 	chan = &ses->chans[ses->chan_count];
@@ -497,6 +507,10 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
 		cifs_put_tcp_session(chan->server, 0);
 	}
 
+	kfree(ctx->UNC);
+out_free_ctx:
+	kfree(ctx);
+out_free_xid:
 	free_xid(xid);
 	return rc;
 }
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/8] smb: client: reduce stack usage in smb_send_rqst()
  2023-07-28 19:50 [PATCH 1/8] smb: client: reduce stack usage in cifs_try_adding_channels() Paulo Alcantara
@ 2023-07-28 19:50 ` Paulo Alcantara
  2023-07-28 19:50 ` [PATCH 3/8] smb: client: reduce stack usage in cifs_get_inode_info() Paulo Alcantara
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Paulo Alcantara @ 2023-07-28 19:50 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara

Clang warns about exceeded stack frame size

  fs/smb/client/transport.c:420:1: warning: stack frame size (1048)
  exceeds limit (1024) in 'smb_send_rqst' [-Wframe-larger-than]

Fix this by allocating a structure that will hold transform header and
compound requests.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/transport.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index f280502a2aee..1b5d9794ed5b 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -416,13 +416,19 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
 	return rc;
 }
 
+struct send_req_vars {
+	struct smb2_transform_hdr tr_hdr;
+	struct smb_rqst rqst[MAX_COMPOUND];
+	struct kvec iov;
+};
+
 static int
 smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
 	      struct smb_rqst *rqst, int flags)
 {
-	struct kvec iov;
-	struct smb2_transform_hdr *tr_hdr;
-	struct smb_rqst cur_rqst[MAX_COMPOUND];
+	struct send_req_vars *vars;
+	struct smb_rqst *cur_rqst;
+	struct kvec *iov;
 	int rc;
 
 	if (!(flags & CIFS_TRANSFORM_REQ))
@@ -436,16 +442,15 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
 		return -EIO;
 	}
 
-	tr_hdr = kzalloc(sizeof(*tr_hdr), GFP_NOFS);
-	if (!tr_hdr)
+	vars = kzalloc(sizeof(*vars), GFP_NOFS);
+	if (!vars)
 		return -ENOMEM;
+	cur_rqst = vars->rqst;
+	iov = &vars->iov;
 
-	memset(&cur_rqst[0], 0, sizeof(cur_rqst));
-	memset(&iov, 0, sizeof(iov));
-
-	iov.iov_base = tr_hdr;
-	iov.iov_len = sizeof(*tr_hdr);
-	cur_rqst[0].rq_iov = &iov;
+	iov->iov_base = &vars->tr_hdr;
+	iov->iov_len = sizeof(vars->tr_hdr);
+	cur_rqst[0].rq_iov = iov;
 	cur_rqst[0].rq_nvec = 1;
 
 	rc = server->ops->init_transform_rq(server, num_rqst + 1,
@@ -456,7 +461,7 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
 	rc = __smb_send_rqst(server, num_rqst + 1, &cur_rqst[0]);
 	smb3_free_compound_rqst(num_rqst, &cur_rqst[1]);
 out:
-	kfree(tr_hdr);
+	kfree(vars);
 	return rc;
 }
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/8] smb: client: reduce stack usage in cifs_get_inode_info()
  2023-07-28 19:50 [PATCH 1/8] smb: client: reduce stack usage in cifs_try_adding_channels() Paulo Alcantara
  2023-07-28 19:50 ` [PATCH 2/8] smb: client: reduce stack usage in smb_send_rqst() Paulo Alcantara
@ 2023-07-28 19:50 ` Paulo Alcantara
  2023-07-28 19:50 ` [PATCH 4/8] smb: client: reduce stack usage in smb2_set_ea() Paulo Alcantara
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Paulo Alcantara @ 2023-07-28 19:50 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara

Clang warns about exceeded stack frame size

  fs/smb/client/inode.c:963:5: warning: stack frame size (1144)
  exceeds limit (1024) in 'cifs_get_inode_info' [-Wframe-larger-than]

It turns out that cifs_sfu_type() got inlined into
cifs_get_inode_info() which contains some stack-allocated variables
like @fid(96), @oparms(56), @io_parms(64), @buf(24).  Fix this by
marking cifs_sfu_type() as noinline_for_stack.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/inode.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index c3eeae07e139..7f2a7b22427c 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -473,9 +473,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
 }
 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 
-static int
-cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
-	      struct cifs_sb_info *cifs_sb, unsigned int xid)
+static noinline_for_stack int cifs_sfu_type(struct cifs_fattr *fattr,
+					    const char *path,
+					    struct cifs_sb_info *cifs_sb,
+					    unsigned int xid)
 {
 	int rc;
 	__u32 oplock;
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/8] smb: client: reduce stack usage in smb2_set_ea()
  2023-07-28 19:50 [PATCH 1/8] smb: client: reduce stack usage in cifs_try_adding_channels() Paulo Alcantara
  2023-07-28 19:50 ` [PATCH 2/8] smb: client: reduce stack usage in smb_send_rqst() Paulo Alcantara
  2023-07-28 19:50 ` [PATCH 3/8] smb: client: reduce stack usage in cifs_get_inode_info() Paulo Alcantara
@ 2023-07-28 19:50 ` Paulo Alcantara
  2023-07-28 19:50 ` [PATCH 5/8] smb: client: reduce stack usage in smb2_query_info_compound() Paulo Alcantara
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Paulo Alcantara @ 2023-07-28 19:50 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara

Clang warns about exceeded stack frame size

  fs/smb/client/smb2ops.c:1080:1: warning: stack frame size (1432)
  exceeds limit (1024) in 'smb2_set_ea' [-Wframe-larger-than]

Fix this by allocating a set_ea_vars structure that will hold most of
the large structures.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/smb2ops.c | 40 +++++++++++++++++++++++++---------------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 0f62bc373ad0..5c8bcaf41556 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -1075,6 +1075,13 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
 	return rc;
 }
 
+struct set_ea_vars {
+	struct smb_rqst rqst[3];
+	struct kvec rsp_iov[3];
+	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
+	struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
+	struct kvec close_iov;
+};
 
 static int
 smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
@@ -1082,25 +1089,23 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
 	    const __u16 ea_value_len, const struct nls_table *nls_codepage,
 	    struct cifs_sb_info *cifs_sb)
 {
+	struct smb2_query_info_rsp *rsp;
 	struct cifs_ses *ses = tcon->ses;
+	struct set_ea_vars *vars;
 	struct TCP_Server_Info *server = cifs_pick_channel(ses);
+	struct smb_rqst *rqst;
+	struct kvec *rsp_iov;
 	__le16 *utf16_path = NULL;
 	int ea_name_len = strlen(ea_name);
 	int flags = CIFS_CP_CREATE_CLOSE_OP;
 	int len;
-	struct smb_rqst rqst[3];
 	int resp_buftype[3];
-	struct kvec rsp_iov[3];
-	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
 	struct cifs_open_parms oparms;
 	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 	struct cifs_fid fid;
-	struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
 	unsigned int size[1];
 	void *data[1];
 	struct smb2_file_full_ea_info *ea = NULL;
-	struct kvec close_iov[1];
-	struct smb2_query_info_rsp *rsp;
 	int rc, used_len = 0;
 
 	if (smb3_encryption_required(tcon))
@@ -1113,9 +1118,15 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
 	if (!utf16_path)
 		return -ENOMEM;
 
-	memset(rqst, 0, sizeof(rqst));
 	resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
-	memset(rsp_iov, 0, sizeof(rsp_iov));
+
+	vars = kzalloc(sizeof(*vars), GFP_KERNEL);
+	if (!vars) {
+		rc = -ENOMEM;
+		goto out_free_path;
+	}
+	rqst = vars->rqst;
+	rsp_iov = vars->rsp_iov;
 
 	if (ses->server->ops->query_all_EAs) {
 		if (!ea_value) {
@@ -1160,8 +1171,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
 	}
 
 	/* Open */
-	memset(&open_iov, 0, sizeof(open_iov));
-	rqst[0].rq_iov = open_iov;
+	rqst[0].rq_iov = vars->open_iov;
 	rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
 
 	oparms = (struct cifs_open_parms) {
@@ -1181,8 +1191,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
 
 
 	/* Set Info */
-	memset(&si_iov, 0, sizeof(si_iov));
-	rqst[1].rq_iov = si_iov;
+	rqst[1].rq_iov = vars->si_iov;
 	rqst[1].rq_nvec = 1;
 
 	len = sizeof(*ea) + ea_name_len + ea_value_len + 1;
@@ -1212,8 +1221,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
 
 
 	/* Close */
-	memset(&close_iov, 0, sizeof(close_iov));
-	rqst[2].rq_iov = close_iov;
+	rqst[2].rq_iov = &vars->close_iov;
 	rqst[2].rq_nvec = 1;
 	rc = SMB2_close_init(tcon, server,
 			     &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
@@ -1228,13 +1236,15 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
 
  sea_exit:
 	kfree(ea);
-	kfree(utf16_path);
 	SMB2_open_free(&rqst[0]);
 	SMB2_set_info_free(&rqst[1]);
 	SMB2_close_free(&rqst[2]);
 	free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
 	free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
 	free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
+	kfree(vars);
+out_free_path:
+	kfree(utf16_path);
 	return rc;
 }
 #endif
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/8] smb: client: reduce stack usage in smb2_query_info_compound()
  2023-07-28 19:50 [PATCH 1/8] smb: client: reduce stack usage in cifs_try_adding_channels() Paulo Alcantara
                   ` (2 preceding siblings ...)
  2023-07-28 19:50 ` [PATCH 4/8] smb: client: reduce stack usage in smb2_set_ea() Paulo Alcantara
@ 2023-07-28 19:50 ` Paulo Alcantara
  2023-07-28 19:50 ` [PATCH 6/8] smb: client: reduce stack usage in smb2_query_reparse_tag() Paulo Alcantara
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Paulo Alcantara @ 2023-07-28 19:50 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara

Clang warns about exceeded stack frame size

  fs/smb/client/smb2ops.c:2530:1: warning: stack frame size (1336)
  exceeds limit (1024) in 'smb2_query_info_compound'
  [-Wframe-larger-than]

Fix this by allocating a qi_vars structure that will hold most of the
large structures.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/smb2ops.c | 40 ++++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 5c8bcaf41556..d16036c86aa4 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -2522,6 +2522,14 @@ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
 	shdr->NextCommand = cpu_to_le32(len);
 }
 
+struct qi_vars {
+	struct smb_rqst rqst[3];
+	struct kvec rsp_iov[3];
+	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
+	struct kvec qi_iov;
+	struct kvec close_iov;
+};
+
 /*
  * Passes the query info response back to the caller on success.
  * Caller need to free this with free_rsp_buf().
@@ -2536,15 +2544,13 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 	struct cifs_ses *ses = tcon->ses;
 	struct TCP_Server_Info *server = cifs_pick_channel(ses);
 	int flags = CIFS_CP_CREATE_CLOSE_OP;
-	struct smb_rqst rqst[3];
 	int resp_buftype[3];
-	struct kvec rsp_iov[3];
-	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
-	struct kvec qi_iov[1];
-	struct kvec close_iov[1];
 	u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 	struct cifs_open_parms oparms;
+	struct smb_rqst *rqst;
 	struct cifs_fid fid;
+	struct qi_vars *vars;
+	struct kvec *rsp_iov;
 	int rc;
 	__le16 *utf16_path;
 	struct cached_fid *cfid = NULL;
@@ -2558,9 +2564,15 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
 
-	memset(rqst, 0, sizeof(rqst));
 	resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
-	memset(rsp_iov, 0, sizeof(rsp_iov));
+
+	vars = kzalloc(sizeof(*vars), GFP_KERNEL);
+	if (!vars) {
+		rc = -ENOMEM;
+		goto out_free_path;
+	}
+	rqst = vars->rqst;
+	rsp_iov = vars->rsp_iov;
 
 	/*
 	 * We can only call this for things we know are directories.
@@ -2569,8 +2581,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 		open_cached_dir(xid, tcon, path, cifs_sb, false,
 				&cfid); /* cfid null if open dir failed */
 
-	memset(&open_iov, 0, sizeof(open_iov));
-	rqst[0].rq_iov = open_iov;
+	rqst[0].rq_iov = vars->open_iov;
 	rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
 
 	oparms = (struct cifs_open_parms) {
@@ -2588,8 +2599,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 		goto qic_exit;
 	smb2_set_next_command(tcon, &rqst[0]);
 
-	memset(&qi_iov, 0, sizeof(qi_iov));
-	rqst[1].rq_iov = qi_iov;
+	rqst[1].rq_iov = &vars->qi_iov;
 	rqst[1].rq_nvec = 1;
 
 	if (cfid) {
@@ -2616,8 +2626,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 		smb2_set_related(&rqst[1]);
 	}
 
-	memset(&close_iov, 0, sizeof(close_iov));
-	rqst[2].rq_iov = close_iov;
+	rqst[2].rq_iov = &vars->close_iov;
 	rqst[2].rq_nvec = 1;
 
 	rc = SMB2_close_init(tcon, server,
@@ -2648,7 +2657,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 	*buftype = resp_buftype[1];
 
  qic_exit:
-	kfree(utf16_path);
+
 	SMB2_open_free(&rqst[0]);
 	SMB2_query_info_free(&rqst[1]);
 	SMB2_close_free(&rqst[2]);
@@ -2656,6 +2665,9 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 	free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
 	if (cfid)
 		close_cached_dir(cfid);
+	kfree(vars);
+out_free_path:
+	kfree(utf16_path);
 	return rc;
 }
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/8] smb: client: reduce stack usage in smb2_query_reparse_tag()
  2023-07-28 19:50 [PATCH 1/8] smb: client: reduce stack usage in cifs_try_adding_channels() Paulo Alcantara
                   ` (3 preceding siblings ...)
  2023-07-28 19:50 ` [PATCH 5/8] smb: client: reduce stack usage in smb2_query_info_compound() Paulo Alcantara
@ 2023-07-28 19:50 ` Paulo Alcantara
  2023-07-28 19:50 ` [PATCH 7/8] smb: client: reduce stack usage in smb2_query_symlink() Paulo Alcantara
  2023-07-28 19:50 ` [PATCH 8/8] smb: client: reduce stack usage in cifs_demultiplex_thread() Paulo Alcantara
  6 siblings, 0 replies; 10+ messages in thread
From: Paulo Alcantara @ 2023-07-28 19:50 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara

Clang warns about exceeded stack frame size

  fs/smb/client/smb2ops.c:3117:1: warning: stack frame size (1336)
  exceeds limit (1024) in 'smb2_query_reparse_tag'
  [-Wframe-larger-than]

Fix this by allocating a qr_vars structure that will hold most of the
large structures.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/smb2ops.c | 44 ++++++++++++++++++++++++++---------------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index d16036c86aa4..d6a15d5ec4d2 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -3113,6 +3113,14 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 	return rc;
 }
 
+struct qr_vars {
+	struct smb_rqst rqst[3];
+	struct kvec rsp_iov[3];
+	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
+	struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
+	struct kvec close_iov;
+};
+
 int
 smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
 		   struct cifs_sb_info *cifs_sb, const char *full_path,
@@ -3124,13 +3132,11 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
 	struct cifs_open_parms oparms;
 	struct cifs_fid fid;
 	struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
+	struct smb_rqst *rqst;
+	struct qr_vars *vars;
+	struct kvec *rsp_iov;
 	int flags = CIFS_CP_CREATE_CLOSE_OP;
-	struct smb_rqst rqst[3];
 	int resp_buftype[3];
-	struct kvec rsp_iov[3];
-	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
-	struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
-	struct kvec close_iov[1];
 	struct smb2_ioctl_rsp *ioctl_rsp;
 	struct reparse_data_buffer *reparse_buf;
 	u32 plen;
@@ -3140,20 +3146,25 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
 
-	memset(rqst, 0, sizeof(rqst));
-	resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
-	memset(rsp_iov, 0, sizeof(rsp_iov));
-
 	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
 	if (!utf16_path)
 		return -ENOMEM;
 
+	resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
+
+	vars = kzalloc(sizeof(*vars), GFP_KERNEL);
+	if (!vars) {
+		rc = -ENOMEM;
+		goto out_free_path;
+	}
+	rqst = vars->rqst;
+	rsp_iov = vars->rsp_iov;
+
 	/*
 	 * setup smb2open - TODO add optimization to call cifs_get_readable_path
 	 * to see if there is a handle already open that we can use
 	 */
-	memset(&open_iov, 0, sizeof(open_iov));
-	rqst[0].rq_iov = open_iov;
+	rqst[0].rq_iov = vars->open_iov;
 	rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
 
 	oparms = (struct cifs_open_parms) {
@@ -3173,8 +3184,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
 
 
 	/* IOCTL */
-	memset(&io_iov, 0, sizeof(io_iov));
-	rqst[1].rq_iov = io_iov;
+	rqst[1].rq_iov = vars->io_iov;
 	rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
 
 	rc = SMB2_ioctl_init(tcon, server,
@@ -3191,8 +3201,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
 
 
 	/* Close */
-	memset(&close_iov, 0, sizeof(close_iov));
-	rqst[2].rq_iov = close_iov;
+	rqst[2].rq_iov = &vars->close_iov;
 	rqst[2].rq_nvec = 1;
 
 	rc = SMB2_close_init(tcon, server,
@@ -3230,13 +3239,16 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
 	}
 
  query_rp_exit:
-	kfree(utf16_path);
+
 	SMB2_open_free(&rqst[0]);
 	SMB2_ioctl_free(&rqst[1]);
 	SMB2_close_free(&rqst[2]);
 	free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
 	free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
 	free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
+	kfree(vars);
+out_free_path:
+	kfree(utf16_path);
 	return rc;
 }
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/8] smb: client: reduce stack usage in smb2_query_symlink()
  2023-07-28 19:50 [PATCH 1/8] smb: client: reduce stack usage in cifs_try_adding_channels() Paulo Alcantara
                   ` (4 preceding siblings ...)
  2023-07-28 19:50 ` [PATCH 6/8] smb: client: reduce stack usage in smb2_query_reparse_tag() Paulo Alcantara
@ 2023-07-28 19:50 ` Paulo Alcantara
  2023-07-28 20:04   ` Enzo Matsumiya
  2023-07-28 19:50 ` [PATCH 8/8] smb: client: reduce stack usage in cifs_demultiplex_thread() Paulo Alcantara
  6 siblings, 1 reply; 10+ messages in thread
From: Paulo Alcantara @ 2023-07-28 19:50 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara

Clang warns about exceeded stack frame size

  fs/smb/client/smb2ops.c:2974:1: warning: stack frame size (1368)
  exceeds limit (1024) in 'smb2_query_symlink' [-Wframe-larger-than]

Fix this by allocating a qs_vars structure that will hold most of the
large structures.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/smb2ops.c | 43 ++++++++++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index d6a15d5ec4d2..9136c77cd407 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -2970,6 +2970,14 @@ parse_reparse_point(struct reparse_data_buffer *buf,
 	}
 }
 
+struct qs_vars {
+	struct smb_rqst rqst[3];
+	struct kvec rsp_iov[3];
+	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
+	struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
+	struct kvec close_iov;
+};
+
 static int
 smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 		   struct cifs_sb_info *cifs_sb, const char *full_path,
@@ -2979,16 +2987,14 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 	__le16 *utf16_path = NULL;
 	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 	struct cifs_open_parms oparms;
+	struct smb_rqst *rqst;
 	struct cifs_fid fid;
+	struct qs_vars *vars;
 	struct kvec err_iov = {NULL, 0};
+	struct kvec *rsp_iov;
 	struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
 	int flags = CIFS_CP_CREATE_CLOSE_OP;
-	struct smb_rqst rqst[3];
 	int resp_buftype[3];
-	struct kvec rsp_iov[3];
-	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
-	struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
-	struct kvec close_iov[1];
 	struct smb2_create_rsp *create_rsp;
 	struct smb2_ioctl_rsp *ioctl_rsp;
 	struct reparse_data_buffer *reparse_buf;
@@ -3002,17 +3008,22 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
 
-	memset(rqst, 0, sizeof(rqst));
-	resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
-	memset(rsp_iov, 0, sizeof(rsp_iov));
-
 	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
 	if (!utf16_path)
 		return -ENOMEM;
 
+	resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
+
+	vars = kzalloc(sizeof(*vars), GFP_KERNEL);
+	if (!vars) {
+		rc = -ENOMEM;
+		goto out_free_path;
+	}
+	rqst = vars->rqst;
+	rsp_iov = vars->rsp_iov;
+
 	/* Open */
-	memset(&open_iov, 0, sizeof(open_iov));
-	rqst[0].rq_iov = open_iov;
+	rqst[0].rq_iov = vars->open_iov;
 	rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
 
 	oparms = (struct cifs_open_parms) {
@@ -3032,8 +3043,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 
 
 	/* IOCTL */
-	memset(&io_iov, 0, sizeof(io_iov));
-	rqst[1].rq_iov = io_iov;
+	rqst[1].rq_iov = vars->io_iov;
 	rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
 
 	rc = SMB2_ioctl_init(tcon, server,
@@ -3050,8 +3060,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 
 
 	/* Close */
-	memset(&close_iov, 0, sizeof(close_iov));
-	rqst[2].rq_iov = close_iov;
+	rqst[2].rq_iov = &vars->close_iov;
 	rqst[2].rq_nvec = 1;
 
 	rc = SMB2_close_init(tcon, server,
@@ -3103,13 +3112,15 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 
  querty_exit:
 	cifs_dbg(FYI, "query symlink rc %d\n", rc);
-	kfree(utf16_path);
 	SMB2_open_free(&rqst[0]);
 	SMB2_ioctl_free(&rqst[1]);
 	SMB2_close_free(&rqst[2]);
 	free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
 	free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
 	free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
+	kfree(vars);
+out_free_path:
+	kfree(utf16_path);
 	return rc;
 }
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 8/8] smb: client: reduce stack usage in cifs_demultiplex_thread()
  2023-07-28 19:50 [PATCH 1/8] smb: client: reduce stack usage in cifs_try_adding_channels() Paulo Alcantara
                   ` (5 preceding siblings ...)
  2023-07-28 19:50 ` [PATCH 7/8] smb: client: reduce stack usage in smb2_query_symlink() Paulo Alcantara
@ 2023-07-28 19:50 ` Paulo Alcantara
  6 siblings, 0 replies; 10+ messages in thread
From: Paulo Alcantara @ 2023-07-28 19:50 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara

Clang warns about exceeded stack frame size

  fs/smb/client/connect.c:1109:1: warning: stack frame size (1048)
  exceeds limit (1024) in 'cifs_demultiplex_thread'
  [-Wframe-larger-than]

It turns out that clean_demultiplex_info() got inlined into
cifs_demultiplex_thread(), so mark it as noinline_for_stack to save
some stack space.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/connect.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 238538dde4e3..ace1ec273364 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -911,8 +911,8 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
 	return 0;
 }
 
-
-static void clean_demultiplex_info(struct TCP_Server_Info *server)
+static noinline_for_stack void
+clean_demultiplex_info(struct TCP_Server_Info *server)
 {
 	int length;
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 7/8] smb: client: reduce stack usage in smb2_query_symlink()
  2023-07-28 19:50 ` [PATCH 7/8] smb: client: reduce stack usage in smb2_query_symlink() Paulo Alcantara
@ 2023-07-28 20:04   ` Enzo Matsumiya
  2023-07-28 20:32     ` Steve French
  0 siblings, 1 reply; 10+ messages in thread
From: Enzo Matsumiya @ 2023-07-28 20:04 UTC (permalink / raw)
  To: Paulo Alcantara; +Cc: smfrench, linux-cifs

On 07/28, Paulo Alcantara wrote:
>Clang warns about exceeded stack frame size
>
>  fs/smb/client/smb2ops.c:2974:1: warning: stack frame size (1368)
>  exceeds limit (1024) in 'smb2_query_symlink' [-Wframe-larger-than]
>
>Fix this by allocating a qs_vars structure that will hold most of the
>large structures.
>
>Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
>---
> fs/smb/client/smb2ops.c | 43 ++++++++++++++++++++++++++---------------
> 1 file changed, 27 insertions(+), 16 deletions(-)
>
>diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
>index d6a15d5ec4d2..9136c77cd407 100644
>--- a/fs/smb/client/smb2ops.c
>+++ b/fs/smb/client/smb2ops.c
>@@ -2970,6 +2970,14 @@ parse_reparse_point(struct reparse_data_buffer *buf,
> 	}
> }
>
>+struct qs_vars {
>+	struct smb_rqst rqst[3];
>+	struct kvec rsp_iov[3];
>+	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
>+	struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
>+	struct kvec close_iov;
>+};

I think structs qs_vars, qr_vars, and qi_vars should be a single "struct
query_vars" instead of having 2 repeated + 1 very similar differently
named structs around.

Then for smb2_query_info_compound() you use only io_iov[0].

And later on, maybe even embed such struct in "struct cop_vars"
(smb2inode.c) to avoid even more duplicate code.

Other than that,

Reviewed-by: Enzo Matsumiya <ematsumiya@suse.de>

for this and all the other patches in this series.


Cheers,

Enzo

>+
> static int
> smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
> 		   struct cifs_sb_info *cifs_sb, const char *full_path,
>@@ -2979,16 +2987,14 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
> 	__le16 *utf16_path = NULL;
> 	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
> 	struct cifs_open_parms oparms;
>+	struct smb_rqst *rqst;
> 	struct cifs_fid fid;
>+	struct qs_vars *vars;
> 	struct kvec err_iov = {NULL, 0};
>+	struct kvec *rsp_iov;
> 	struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
> 	int flags = CIFS_CP_CREATE_CLOSE_OP;
>-	struct smb_rqst rqst[3];
> 	int resp_buftype[3];
>-	struct kvec rsp_iov[3];
>-	struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
>-	struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
>-	struct kvec close_iov[1];
> 	struct smb2_create_rsp *create_rsp;
> 	struct smb2_ioctl_rsp *ioctl_rsp;
> 	struct reparse_data_buffer *reparse_buf;
>@@ -3002,17 +3008,22 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
> 	if (smb3_encryption_required(tcon))
> 		flags |= CIFS_TRANSFORM_REQ;
>
>-	memset(rqst, 0, sizeof(rqst));
>-	resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
>-	memset(rsp_iov, 0, sizeof(rsp_iov));
>-
> 	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
> 	if (!utf16_path)
> 		return -ENOMEM;
>
>+	resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
>+
>+	vars = kzalloc(sizeof(*vars), GFP_KERNEL);
>+	if (!vars) {
>+		rc = -ENOMEM;
>+		goto out_free_path;
>+	}
>+	rqst = vars->rqst;
>+	rsp_iov = vars->rsp_iov;
>+
> 	/* Open */
>-	memset(&open_iov, 0, sizeof(open_iov));
>-	rqst[0].rq_iov = open_iov;
>+	rqst[0].rq_iov = vars->open_iov;
> 	rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
>
> 	oparms = (struct cifs_open_parms) {
>@@ -3032,8 +3043,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
>
>
> 	/* IOCTL */
>-	memset(&io_iov, 0, sizeof(io_iov));
>-	rqst[1].rq_iov = io_iov;
>+	rqst[1].rq_iov = vars->io_iov;
> 	rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
>
> 	rc = SMB2_ioctl_init(tcon, server,
>@@ -3050,8 +3060,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
>
>
> 	/* Close */
>-	memset(&close_iov, 0, sizeof(close_iov));
>-	rqst[2].rq_iov = close_iov;
>+	rqst[2].rq_iov = &vars->close_iov;
> 	rqst[2].rq_nvec = 1;
>
> 	rc = SMB2_close_init(tcon, server,
>@@ -3103,13 +3112,15 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
>
>  querty_exit:
> 	cifs_dbg(FYI, "query symlink rc %d\n", rc);
>-	kfree(utf16_path);
> 	SMB2_open_free(&rqst[0]);
> 	SMB2_ioctl_free(&rqst[1]);
> 	SMB2_close_free(&rqst[2]);
> 	free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
> 	free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
> 	free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
>+	kfree(vars);
>+out_free_path:
>+	kfree(utf16_path);
> 	return rc;
> }
>
>-- 
>2.41.0
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 7/8] smb: client: reduce stack usage in smb2_query_symlink()
  2023-07-28 20:04   ` Enzo Matsumiya
@ 2023-07-28 20:32     ` Steve French
  0 siblings, 0 replies; 10+ messages in thread
From: Steve French @ 2023-07-28 20:32 UTC (permalink / raw)
  To: Enzo Matsumiya; +Cc: Paulo Alcantara, linux-cifs

probably best to limit additional cleanup (and thus patch size) of
these so they don't get confusing and harder to backport.

We also have lots of testcases (xfstest features and failures) to work
through one by one that are high priority.

The obvious question is - are any of these high enough priority to go
into e.g. rc4 or rc5 - or wait till the merge window?

On Fri, Jul 28, 2023 at 3:04 PM Enzo Matsumiya <ematsumiya@suse.de> wrote:
>
> On 07/28, Paulo Alcantara wrote:
> >Clang warns about exceeded stack frame size
> >
> >  fs/smb/client/smb2ops.c:2974:1: warning: stack frame size (1368)
> >  exceeds limit (1024) in 'smb2_query_symlink' [-Wframe-larger-than]
> >
> >Fix this by allocating a qs_vars structure that will hold most of the
> >large structures.
> >
> >Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
> >---
> > fs/smb/client/smb2ops.c | 43 ++++++++++++++++++++++++++---------------
> > 1 file changed, 27 insertions(+), 16 deletions(-)
> >
> >diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
> >index d6a15d5ec4d2..9136c77cd407 100644
> >--- a/fs/smb/client/smb2ops.c
> >+++ b/fs/smb/client/smb2ops.c
> >@@ -2970,6 +2970,14 @@ parse_reparse_point(struct reparse_data_buffer *buf,
> >       }
> > }
> >
> >+struct qs_vars {
> >+      struct smb_rqst rqst[3];
> >+      struct kvec rsp_iov[3];
> >+      struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
> >+      struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
> >+      struct kvec close_iov;
> >+};
>
> I think structs qs_vars, qr_vars, and qi_vars should be a single "struct
> query_vars" instead of having 2 repeated + 1 very similar differently
> named structs around.
>
> Then for smb2_query_info_compound() you use only io_iov[0].
>
> And later on, maybe even embed such struct in "struct cop_vars"
> (smb2inode.c) to avoid even more duplicate code.
>
> Other than that,
>
> Reviewed-by: Enzo Matsumiya <ematsumiya@suse.de>
>
> for this and all the other patches in this series.
>
>
> Cheers,
>
> Enzo
>
> >+
> > static int
> > smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
> >                  struct cifs_sb_info *cifs_sb, const char *full_path,
> >@@ -2979,16 +2987,14 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
> >       __le16 *utf16_path = NULL;
> >       __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
> >       struct cifs_open_parms oparms;
> >+      struct smb_rqst *rqst;
> >       struct cifs_fid fid;
> >+      struct qs_vars *vars;
> >       struct kvec err_iov = {NULL, 0};
> >+      struct kvec *rsp_iov;
> >       struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
> >       int flags = CIFS_CP_CREATE_CLOSE_OP;
> >-      struct smb_rqst rqst[3];
> >       int resp_buftype[3];
> >-      struct kvec rsp_iov[3];
> >-      struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
> >-      struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
> >-      struct kvec close_iov[1];
> >       struct smb2_create_rsp *create_rsp;
> >       struct smb2_ioctl_rsp *ioctl_rsp;
> >       struct reparse_data_buffer *reparse_buf;
> >@@ -3002,17 +3008,22 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
> >       if (smb3_encryption_required(tcon))
> >               flags |= CIFS_TRANSFORM_REQ;
> >
> >-      memset(rqst, 0, sizeof(rqst));
> >-      resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
> >-      memset(rsp_iov, 0, sizeof(rsp_iov));
> >-
> >       utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
> >       if (!utf16_path)
> >               return -ENOMEM;
> >
> >+      resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
> >+
> >+      vars = kzalloc(sizeof(*vars), GFP_KERNEL);
> >+      if (!vars) {
> >+              rc = -ENOMEM;
> >+              goto out_free_path;
> >+      }
> >+      rqst = vars->rqst;
> >+      rsp_iov = vars->rsp_iov;
> >+
> >       /* Open */
> >-      memset(&open_iov, 0, sizeof(open_iov));
> >-      rqst[0].rq_iov = open_iov;
> >+      rqst[0].rq_iov = vars->open_iov;
> >       rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
> >
> >       oparms = (struct cifs_open_parms) {
> >@@ -3032,8 +3043,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
> >
> >
> >       /* IOCTL */
> >-      memset(&io_iov, 0, sizeof(io_iov));
> >-      rqst[1].rq_iov = io_iov;
> >+      rqst[1].rq_iov = vars->io_iov;
> >       rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
> >
> >       rc = SMB2_ioctl_init(tcon, server,
> >@@ -3050,8 +3060,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
> >
> >
> >       /* Close */
> >-      memset(&close_iov, 0, sizeof(close_iov));
> >-      rqst[2].rq_iov = close_iov;
> >+      rqst[2].rq_iov = &vars->close_iov;
> >       rqst[2].rq_nvec = 1;
> >
> >       rc = SMB2_close_init(tcon, server,
> >@@ -3103,13 +3112,15 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
> >
> >  querty_exit:
> >       cifs_dbg(FYI, "query symlink rc %d\n", rc);
> >-      kfree(utf16_path);
> >       SMB2_open_free(&rqst[0]);
> >       SMB2_ioctl_free(&rqst[1]);
> >       SMB2_close_free(&rqst[2]);
> >       free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
> >       free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
> >       free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
> >+      kfree(vars);
> >+out_free_path:
> >+      kfree(utf16_path);
> >       return rc;
> > }
> >
> >--
> >2.41.0
> >



-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-07-28 20:32 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-28 19:50 [PATCH 1/8] smb: client: reduce stack usage in cifs_try_adding_channels() Paulo Alcantara
2023-07-28 19:50 ` [PATCH 2/8] smb: client: reduce stack usage in smb_send_rqst() Paulo Alcantara
2023-07-28 19:50 ` [PATCH 3/8] smb: client: reduce stack usage in cifs_get_inode_info() Paulo Alcantara
2023-07-28 19:50 ` [PATCH 4/8] smb: client: reduce stack usage in smb2_set_ea() Paulo Alcantara
2023-07-28 19:50 ` [PATCH 5/8] smb: client: reduce stack usage in smb2_query_info_compound() Paulo Alcantara
2023-07-28 19:50 ` [PATCH 6/8] smb: client: reduce stack usage in smb2_query_reparse_tag() Paulo Alcantara
2023-07-28 19:50 ` [PATCH 7/8] smb: client: reduce stack usage in smb2_query_symlink() Paulo Alcantara
2023-07-28 20:04   ` Enzo Matsumiya
2023-07-28 20:32     ` Steve French
2023-07-28 19:50 ` [PATCH 8/8] smb: client: reduce stack usage in cifs_demultiplex_thread() Paulo Alcantara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).