Skip to content

Commit 3ded18a

Browse files
Paulo Alcantarasmfrench
authored andcommitted
smb: client: cleanup smb2_query_reparse_point()
Use smb2_compound_op() with SMB2_OP_GET_REPARSE to get reparse point. Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 514d793 commit 3ded18a

3 files changed

Lines changed: 39 additions & 139 deletions

File tree

fs/smb/client/smb2inode.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,3 +1053,36 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
10531053
}
10541054
return rc ? ERR_PTR(rc) : new;
10551055
}
1056+
1057+
int smb2_query_reparse_point(const unsigned int xid,
1058+
struct cifs_tcon *tcon,
1059+
struct cifs_sb_info *cifs_sb,
1060+
const char *full_path,
1061+
u32 *tag, struct kvec *rsp,
1062+
int *rsp_buftype)
1063+
{
1064+
struct cifs_open_info_data data = {};
1065+
struct cifsFileInfo *cfile;
1066+
struct kvec in_iov = { .iov_base = &data, .iov_len = sizeof(data), };
1067+
int rc;
1068+
1069+
cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
1070+
1071+
cifs_get_readable_path(tcon, full_path, &cfile);
1072+
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
1073+
FILE_READ_ATTRIBUTES, FILE_OPEN,
1074+
OPEN_REPARSE_POINT, ACL_NO_MODE, &in_iov,
1075+
&(int){SMB2_OP_GET_REPARSE}, 1, cfile,
1076+
NULL, NULL, NULL, NULL);
1077+
if (rc)
1078+
goto out;
1079+
1080+
*tag = data.reparse.tag;
1081+
*rsp = data.reparse.io.iov;
1082+
*rsp_buftype = data.reparse.io.buftype;
1083+
memset(&data.reparse.io.iov, 0, sizeof(data.reparse.io.iov));
1084+
data.reparse.io.buftype = CIFS_NO_BUFFER;
1085+
out:
1086+
cifs_free_open_info(&data);
1087+
return rc;
1088+
}

fs/smb/client/smb2ops.c

Lines changed: 0 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -2997,145 +2997,6 @@ static int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
29972997
return parse_reparse_point(buf, plen, cifs_sb, true, data);
29982998
}
29992999

3000-
static int smb2_query_reparse_point(const unsigned int xid,
3001-
struct cifs_tcon *tcon,
3002-
struct cifs_sb_info *cifs_sb,
3003-
const char *full_path,
3004-
u32 *tag, struct kvec *rsp,
3005-
int *rsp_buftype)
3006-
{
3007-
struct smb2_compound_vars *vars;
3008-
int rc;
3009-
__le16 *utf16_path = NULL;
3010-
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
3011-
struct cifs_open_parms oparms;
3012-
struct cifs_fid fid;
3013-
struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
3014-
int flags = CIFS_CP_CREATE_CLOSE_OP;
3015-
struct smb_rqst *rqst;
3016-
int resp_buftype[3];
3017-
struct kvec *rsp_iov;
3018-
struct smb2_ioctl_rsp *ioctl_rsp;
3019-
struct reparse_data_buffer *reparse_buf;
3020-
u32 off, count, len;
3021-
3022-
cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
3023-
3024-
if (smb3_encryption_required(tcon))
3025-
flags |= CIFS_TRANSFORM_REQ;
3026-
3027-
utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
3028-
if (!utf16_path)
3029-
return -ENOMEM;
3030-
3031-
resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
3032-
vars = kzalloc(sizeof(*vars), GFP_KERNEL);
3033-
if (!vars) {
3034-
rc = -ENOMEM;
3035-
goto out_free_path;
3036-
}
3037-
rqst = vars->rqst;
3038-
rsp_iov = vars->rsp_iov;
3039-
3040-
/*
3041-
* setup smb2open - TODO add optimization to call cifs_get_readable_path
3042-
* to see if there is a handle already open that we can use
3043-
*/
3044-
rqst[0].rq_iov = vars->open_iov;
3045-
rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
3046-
3047-
oparms = (struct cifs_open_parms) {
3048-
.tcon = tcon,
3049-
.path = full_path,
3050-
.desired_access = FILE_READ_ATTRIBUTES,
3051-
.disposition = FILE_OPEN,
3052-
.create_options = cifs_create_options(cifs_sb, OPEN_REPARSE_POINT),
3053-
.fid = &fid,
3054-
};
3055-
3056-
rc = SMB2_open_init(tcon, server,
3057-
&rqst[0], &oplock, &oparms, utf16_path);
3058-
if (rc)
3059-
goto query_rp_exit;
3060-
smb2_set_next_command(tcon, &rqst[0]);
3061-
3062-
3063-
/* IOCTL */
3064-
rqst[1].rq_iov = vars->io_iov;
3065-
rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
3066-
3067-
rc = SMB2_ioctl_init(tcon, server,
3068-
&rqst[1], COMPOUND_FID,
3069-
COMPOUND_FID, FSCTL_GET_REPARSE_POINT, NULL, 0,
3070-
CIFSMaxBufSize -
3071-
MAX_SMB2_CREATE_RESPONSE_SIZE -
3072-
MAX_SMB2_CLOSE_RESPONSE_SIZE);
3073-
if (rc)
3074-
goto query_rp_exit;
3075-
3076-
smb2_set_next_command(tcon, &rqst[1]);
3077-
smb2_set_related(&rqst[1]);
3078-
3079-
/* Close */
3080-
rqst[2].rq_iov = &vars->close_iov;
3081-
rqst[2].rq_nvec = 1;
3082-
3083-
rc = SMB2_close_init(tcon, server,
3084-
&rqst[2], COMPOUND_FID, COMPOUND_FID, false);
3085-
if (rc)
3086-
goto query_rp_exit;
3087-
3088-
smb2_set_related(&rqst[2]);
3089-
3090-
rc = compound_send_recv(xid, tcon->ses, server,
3091-
flags, 3, rqst,
3092-
resp_buftype, rsp_iov);
3093-
3094-
ioctl_rsp = rsp_iov[1].iov_base;
3095-
3096-
/*
3097-
* Open was successful and we got an ioctl response.
3098-
*/
3099-
if (rc == 0) {
3100-
/* See MS-FSCC 2.3.23 */
3101-
off = le32_to_cpu(ioctl_rsp->OutputOffset);
3102-
count = le32_to_cpu(ioctl_rsp->OutputCount);
3103-
if (check_add_overflow(off, count, &len) ||
3104-
len > rsp_iov[1].iov_len) {
3105-
cifs_tcon_dbg(VFS, "%s: invalid ioctl: off=%d count=%d\n",
3106-
__func__, off, count);
3107-
rc = -EIO;
3108-
goto query_rp_exit;
3109-
}
3110-
3111-
reparse_buf = (void *)((u8 *)ioctl_rsp + off);
3112-
len = sizeof(*reparse_buf);
3113-
if (count < len ||
3114-
count < le16_to_cpu(reparse_buf->ReparseDataLength) + len) {
3115-
cifs_tcon_dbg(VFS, "%s: invalid ioctl: off=%d count=%d\n",
3116-
__func__, off, count);
3117-
rc = -EIO;
3118-
goto query_rp_exit;
3119-
}
3120-
*tag = le32_to_cpu(reparse_buf->ReparseTag);
3121-
*rsp = rsp_iov[1];
3122-
*rsp_buftype = resp_buftype[1];
3123-
resp_buftype[1] = CIFS_NO_BUFFER;
3124-
}
3125-
3126-
query_rp_exit:
3127-
SMB2_open_free(&rqst[0]);
3128-
SMB2_ioctl_free(&rqst[1]);
3129-
SMB2_close_free(&rqst[2]);
3130-
free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
3131-
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
3132-
free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
3133-
kfree(vars);
3134-
out_free_path:
3135-
kfree(utf16_path);
3136-
return rc;
3137-
}
3138-
31393000
static struct cifs_ntsd *
31403001
get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb,
31413002
const struct cifs_fid *cifsfid, u32 *pacllen, u32 info)

fs/smb/client/smb2proto.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
6262
struct cifs_tcon *tcon,
6363
const char *full_path,
6464
struct kvec *iov);
65+
int smb2_query_reparse_point(const unsigned int xid,
66+
struct cifs_tcon *tcon,
67+
struct cifs_sb_info *cifs_sb,
68+
const char *full_path,
69+
u32 *tag, struct kvec *rsp,
70+
int *rsp_buftype);
6571
int smb2_query_path_info(const unsigned int xid,
6672
struct cifs_tcon *tcon,
6773
struct cifs_sb_info *cifs_sb,

0 commit comments

Comments
 (0)