diff options
Diffstat (limited to 'fs/smb/client/smb2ops.c')
-rw-r--r-- | fs/smb/client/smb2ops.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index d31ea7e7fd84..015d13d9054d 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -2513,15 +2513,13 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, struct kvec *rsp, int *buftype, struct cifs_sb_info *cifs_sb) { + struct smb2_compound_vars *vars; 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]; + struct smb_rqst *rqst; 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]; + struct kvec *rsp_iov; u8 oplock = SMB2_OPLOCK_LEVEL_NONE; struct cifs_open_parms oparms; struct cifs_fid fid; @@ -2538,9 +2536,14 @@ 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. @@ -2549,8 +2552,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) { @@ -2568,8 +2570,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) { @@ -2596,8 +2597,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, @@ -2628,7 +2628,6 @@ 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]); @@ -2636,6 +2635,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; } |