Commit f4e5ceb6 authored by Paulo Alcantara's avatar Paulo Alcantara Committed by Steve French

smb: client: reduce stack usage in smb2_set_ea()

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 structure that will hold most of the large
variables.
Signed-off-by: default avatarPaulo Alcantara (SUSE) <pc@manguebit.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 933148a4
...@@ -2214,4 +2214,17 @@ static inline void cifs_sg_set_buf(struct sg_table *sgtable, ...@@ -2214,4 +2214,17 @@ static inline void cifs_sg_set_buf(struct sg_table *sgtable,
} }
} }
struct smb2_compound_vars {
struct cifs_open_parms oparms;
struct kvec rsp_iov[3];
struct smb_rqst rqst[3];
struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
struct kvec qi_iov;
struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
struct kvec close_iov;
struct smb2_file_rename_info rename_info;
struct smb2_file_link_info link_info;
};
#endif /* _CIFS_GLOB_H */ #endif /* _CIFS_GLOB_H */
...@@ -35,19 +35,6 @@ free_set_inf_compound(struct smb_rqst *rqst) ...@@ -35,19 +35,6 @@ free_set_inf_compound(struct smb_rqst *rqst)
SMB2_close_free(&rqst[2]); SMB2_close_free(&rqst[2]);
} }
struct cop_vars {
struct cifs_open_parms oparms;
struct kvec rsp_iov[3];
struct smb_rqst rqst[3];
struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
struct kvec qi_iov[1];
struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
struct kvec close_iov[1];
struct smb2_file_rename_info rename_info;
struct smb2_file_link_info link_info;
};
/* /*
* note: If cfile is passed, the reference to it is dropped here. * note: If cfile is passed, the reference to it is dropped here.
* So make sure that you do not reuse cfile after return from this func. * So make sure that you do not reuse cfile after return from this func.
...@@ -63,7 +50,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -63,7 +50,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
__u8 **extbuf, size_t *extbuflen, __u8 **extbuf, size_t *extbuflen,
struct kvec *out_iov, int *out_buftype) struct kvec *out_iov, int *out_buftype)
{ {
struct cop_vars *vars = NULL; struct smb2_compound_vars *vars = NULL;
struct kvec *rsp_iov; struct kvec *rsp_iov;
struct smb_rqst *rqst; struct smb_rqst *rqst;
int rc; int rc;
...@@ -134,7 +121,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -134,7 +121,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
/* Operation */ /* Operation */
switch (command) { switch (command) {
case SMB2_OP_QUERY_INFO: case SMB2_OP_QUERY_INFO:
rqst[num_rqst].rq_iov = &vars->qi_iov[0]; rqst[num_rqst].rq_iov = &vars->qi_iov;
rqst[num_rqst].rq_nvec = 1; rqst[num_rqst].rq_nvec = 1;
if (cfile) if (cfile)
...@@ -168,7 +155,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -168,7 +155,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
full_path); full_path);
break; break;
case SMB2_OP_POSIX_QUERY_INFO: case SMB2_OP_POSIX_QUERY_INFO:
rqst[num_rqst].rq_iov = &vars->qi_iov[0]; rqst[num_rqst].rq_iov = &vars->qi_iov;
rqst[num_rqst].rq_nvec = 1; rqst[num_rqst].rq_nvec = 1;
if (cfile) if (cfile)
...@@ -376,7 +363,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -376,7 +363,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
goto after_close; goto after_close;
/* Close */ /* Close */
flags |= CIFS_CP_CREATE_CLOSE_OP; flags |= CIFS_CP_CREATE_CLOSE_OP;
rqst[num_rqst].rq_iov = &vars->close_iov[0]; rqst[num_rqst].rq_iov = &vars->close_iov;
rqst[num_rqst].rq_nvec = 1; rqst[num_rqst].rq_nvec = 1;
rc = SMB2_close_init(tcon, server, rc = SMB2_close_init(tcon, server,
&rqst[num_rqst], COMPOUND_FID, &rqst[num_rqst], COMPOUND_FID,
......
...@@ -1075,31 +1075,28 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1075,31 +1075,28 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
return rc; return rc;
} }
static int static int
smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
const char *path, const char *ea_name, const void *ea_value, const char *path, const char *ea_name, const void *ea_value,
const __u16 ea_value_len, const struct nls_table *nls_codepage, const __u16 ea_value_len, const struct nls_table *nls_codepage,
struct cifs_sb_info *cifs_sb) struct cifs_sb_info *cifs_sb)
{ {
struct smb2_compound_vars *vars;
struct cifs_ses *ses = tcon->ses; struct cifs_ses *ses = tcon->ses;
struct TCP_Server_Info *server = cifs_pick_channel(ses); struct TCP_Server_Info *server = cifs_pick_channel(ses);
struct smb_rqst *rqst;
struct kvec *rsp_iov;
__le16 *utf16_path = NULL; __le16 *utf16_path = NULL;
int ea_name_len = strlen(ea_name); int ea_name_len = strlen(ea_name);
int flags = CIFS_CP_CREATE_CLOSE_OP; int flags = CIFS_CP_CREATE_CLOSE_OP;
int len; int len;
struct smb_rqst rqst[3];
int resp_buftype[3]; int resp_buftype[3];
struct kvec rsp_iov[3];
struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
struct cifs_open_parms oparms; struct cifs_open_parms oparms;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE; __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
struct cifs_fid fid; struct cifs_fid fid;
struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
unsigned int size[1]; unsigned int size[1];
void *data[1]; void *data[1];
struct smb2_file_full_ea_info *ea = NULL; struct smb2_file_full_ea_info *ea = NULL;
struct kvec close_iov[1];
struct smb2_query_info_rsp *rsp; struct smb2_query_info_rsp *rsp;
int rc, used_len = 0; int rc, used_len = 0;
...@@ -1113,9 +1110,14 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1113,9 +1110,14 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
if (!utf16_path) if (!utf16_path)
return -ENOMEM; return -ENOMEM;
memset(rqst, 0, sizeof(rqst));
resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; 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 (ses->server->ops->query_all_EAs) {
if (!ea_value) { if (!ea_value) {
...@@ -1160,8 +1162,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1160,8 +1162,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
} }
/* Open */ /* Open */
memset(&open_iov, 0, sizeof(open_iov)); rqst[0].rq_iov = vars->open_iov;
rqst[0].rq_iov = open_iov;
rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE; rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
oparms = (struct cifs_open_parms) { oparms = (struct cifs_open_parms) {
...@@ -1181,8 +1182,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1181,8 +1182,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
/* Set Info */ /* Set Info */
memset(&si_iov, 0, sizeof(si_iov)); rqst[1].rq_iov = vars->si_iov;
rqst[1].rq_iov = si_iov;
rqst[1].rq_nvec = 1; rqst[1].rq_nvec = 1;
len = sizeof(*ea) + ea_name_len + ea_value_len + 1; len = sizeof(*ea) + ea_name_len + ea_value_len + 1;
...@@ -1210,10 +1210,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1210,10 +1210,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
smb2_set_next_command(tcon, &rqst[1]); smb2_set_next_command(tcon, &rqst[1]);
smb2_set_related(&rqst[1]); smb2_set_related(&rqst[1]);
/* Close */ /* Close */
memset(&close_iov, 0, sizeof(close_iov)); rqst[2].rq_iov = &vars->close_iov;
rqst[2].rq_iov = close_iov;
rqst[2].rq_nvec = 1; rqst[2].rq_nvec = 1;
rc = SMB2_close_init(tcon, server, rc = SMB2_close_init(tcon, server,
&rqst[2], COMPOUND_FID, COMPOUND_FID, false); &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
...@@ -1228,13 +1226,15 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1228,13 +1226,15 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
sea_exit: sea_exit:
kfree(ea); kfree(ea);
kfree(utf16_path);
SMB2_open_free(&rqst[0]); SMB2_open_free(&rqst[0]);
SMB2_set_info_free(&rqst[1]); SMB2_set_info_free(&rqst[1]);
SMB2_close_free(&rqst[2]); SMB2_close_free(&rqst[2]);
free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); 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[1], rsp_iov[1].iov_base);
free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
kfree(vars);
out_free_path:
kfree(utf16_path);
return rc; return rc;
} }
#endif #endif
...@@ -1445,16 +1445,6 @@ SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -1445,16 +1445,6 @@ SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
return rc; return rc;
} }
struct iqi_vars {
struct smb_rqst rqst[3];
struct kvec rsp_iov[3];
struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
struct kvec qi_iov[1];
struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
struct kvec close_iov[1];
};
static int static int
smb2_ioctl_query_info(const unsigned int xid, smb2_ioctl_query_info(const unsigned int xid,
struct cifs_tcon *tcon, struct cifs_tcon *tcon,
...@@ -1462,7 +1452,7 @@ smb2_ioctl_query_info(const unsigned int xid, ...@@ -1462,7 +1452,7 @@ smb2_ioctl_query_info(const unsigned int xid,
__le16 *path, int is_dir, __le16 *path, int is_dir,
unsigned long p) unsigned long p)
{ {
struct iqi_vars *vars; struct smb2_compound_vars *vars;
struct smb_rqst *rqst; struct smb_rqst *rqst;
struct kvec *rsp_iov; struct kvec *rsp_iov;
struct cifs_ses *ses = tcon->ses; struct cifs_ses *ses = tcon->ses;
...@@ -1580,7 +1570,7 @@ smb2_ioctl_query_info(const unsigned int xid, ...@@ -1580,7 +1570,7 @@ smb2_ioctl_query_info(const unsigned int xid,
rc = -EINVAL; rc = -EINVAL;
goto free_open_req; goto free_open_req;
} }
rqst[1].rq_iov = &vars->si_iov[0]; rqst[1].rq_iov = vars->si_iov;
rqst[1].rq_nvec = 1; rqst[1].rq_nvec = 1;
/* MS-FSCC 2.4.13 FileEndOfFileInformation */ /* MS-FSCC 2.4.13 FileEndOfFileInformation */
...@@ -1592,7 +1582,7 @@ smb2_ioctl_query_info(const unsigned int xid, ...@@ -1592,7 +1582,7 @@ smb2_ioctl_query_info(const unsigned int xid,
SMB2_O_INFO_FILE, 0, data, size); SMB2_O_INFO_FILE, 0, data, size);
free_req1_func = SMB2_set_info_free; free_req1_func = SMB2_set_info_free;
} else if (qi.flags == PASSTHRU_QUERY_INFO) { } else if (qi.flags == PASSTHRU_QUERY_INFO) {
rqst[1].rq_iov = &vars->qi_iov[0]; rqst[1].rq_iov = &vars->qi_iov;
rqst[1].rq_nvec = 1; rqst[1].rq_nvec = 1;
rc = SMB2_query_info_init(tcon, server, rc = SMB2_query_info_init(tcon, server,
...@@ -1614,7 +1604,7 @@ smb2_ioctl_query_info(const unsigned int xid, ...@@ -1614,7 +1604,7 @@ smb2_ioctl_query_info(const unsigned int xid,
smb2_set_related(&rqst[1]); smb2_set_related(&rqst[1]);
/* Close */ /* Close */
rqst[2].rq_iov = &vars->close_iov[0]; rqst[2].rq_iov = &vars->close_iov;
rqst[2].rq_nvec = 1; rqst[2].rq_nvec = 1;
rc = SMB2_close_init(tcon, server, rc = SMB2_close_init(tcon, server,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment