Loading fs/cifs/cifsglob.h +1 −0 Original line number Diff line number Diff line Loading @@ -1082,6 +1082,7 @@ struct cifs_open_parms { int create_options; const char *path; struct cifs_fid *fid; umode_t mode; bool reconnect:1; }; Loading fs/cifs/connect.c +11 −0 Original line number Diff line number Diff line Loading @@ -3963,6 +3963,12 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) goto remote_path_check; } #ifdef CONFIG_CIFS_SMB311 /* if new SMB3.11 POSIX extensions are supported do not remap / and \ */ if (tcon->posix_extensions) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; #endif /* SMB3.11 */ /* tell server which Unix caps we support */ if (cap_unix(tcon->ses)) { /* reset of caps checks mount to see if unix extensions Loading Loading @@ -4424,6 +4430,11 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) goto out; } #ifdef CONFIG_CIFS_SMB311 /* if new SMB3.11 POSIX extensions are supported do not remap / and \ */ if (tcon->posix_extensions) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; #endif /* SMB3.11 */ if (cap_unix(ses)) reset_cifs_unix_caps(0, tcon, NULL, vol_info); Loading fs/cifs/dir.c +1 −1 Original line number Diff line number Diff line Loading @@ -369,7 +369,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, oparms.path = full_path; oparms.fid = fid; oparms.reconnect = false; oparms.mode = mode; rc = server->ops->open(xid, &oparms, oplock, buf); if (rc) { cifs_dbg(FYI, "cifs_create returned 0x%x\n", rc); Loading fs/cifs/smb2misc.c +6 −0 Original line number Diff line number Diff line Loading @@ -455,8 +455,14 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb) /* Windows doesn't allow paths beginning with \ */ if (from[0] == '\\') start_of_path = from + 1; #ifdef CONFIG_CIFS_SMB311 /* SMB311 POSIX extensions paths do not include leading slash */ else if (cifs_sb_master_tcon(cifs_sb)->posix_extensions) start_of_path = from + 1; #endif /* 311 */ else start_of_path = from; to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len, cifs_sb->local_nls, map_type); return to; Loading fs/cifs/smb2pdu.c +82 −2 Original line number Diff line number Diff line Loading @@ -519,6 +519,64 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp, return rc; } static struct create_posix * create_posix_buf(umode_t mode) { struct create_posix *buf; buf = kzalloc(sizeof(struct create_posix), GFP_KERNEL); if (!buf) return NULL; buf->ccontext.DataOffset = cpu_to_le16(offsetof(struct create_posix, Mode)); buf->ccontext.DataLength = cpu_to_le32(4); buf->ccontext.NameOffset = cpu_to_le16(offsetof(struct create_posix, Name)); buf->ccontext.NameLength = cpu_to_le16(16); /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */ buf->Name[0] = 0x93; buf->Name[1] = 0xAD; buf->Name[2] = 0x25; buf->Name[3] = 0x50; buf->Name[4] = 0x9C; buf->Name[5] = 0xB4; buf->Name[6] = 0x11; buf->Name[7] = 0xE7; buf->Name[8] = 0xB4; buf->Name[9] = 0x23; buf->Name[10] = 0x83; buf->Name[11] = 0xDE; buf->Name[12] = 0x96; buf->Name[13] = 0x8B; buf->Name[14] = 0xCD; buf->Name[15] = 0x7C; buf->Mode = cpu_to_le32(mode); cifs_dbg(FYI, "mode on posix create 0%o", mode); return buf; } static int add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode) { struct smb2_create_req *req = iov[0].iov_base; unsigned int num = *num_iovec; iov[num].iov_base = create_posix_buf(mode); if (iov[num].iov_base == NULL) return -ENOMEM; iov[num].iov_len = sizeof(struct create_posix); if (!req->CreateContextsOffset) req->CreateContextsOffset = cpu_to_le32( sizeof(struct smb2_create_req) + iov[num - 1].iov_len); le32_add_cpu(&req->CreateContextsLength, sizeof(struct create_posix)); *num_iovec = num + 1; return 0; } #else static void assemble_neg_contexts(struct smb2_negotiate_req *req, unsigned int *total_len) Loading Loading @@ -1837,7 +1895,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, struct TCP_Server_Info *server; struct cifs_tcon *tcon = oparms->tcon; struct cifs_ses *ses = tcon->ses; struct kvec iov[4]; struct kvec iov[5]; /* make sure at least one for each open context */ struct kvec rsp_iov = {NULL, 0}; int resp_buftype; int uni_path_len; Loading @@ -1846,7 +1904,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, int rc = 0; unsigned int n_iov = 2; __u32 file_attributes = 0; char *dhc_buf = NULL, *lc_buf = NULL; char *dhc_buf = NULL, *lc_buf = NULL, *pc_buf = NULL; int flags = 0; unsigned int total_len; Loading Loading @@ -1963,6 +2021,27 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, dhc_buf = iov[n_iov-1].iov_base; } #ifdef CONFIG_CIFS_SMB311 if (tcon->posix_extensions) { if (n_iov > 2) { struct create_context *ccontext = (struct create_context *)iov[n_iov-1].iov_base; ccontext->Next = cpu_to_le32(iov[n_iov-1].iov_len); } rc = add_posix_context(iov, &n_iov, oparms->mode); if (rc) { cifs_small_buf_release(req); kfree(copy_path); kfree(lc_buf); kfree(dhc_buf); return rc; } pc_buf = iov[n_iov-1].iov_base; } #endif /* SMB311 */ rc = smb2_send_recv(xid, ses, iov, n_iov, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); Loading Loading @@ -2004,6 +2083,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, kfree(copy_path); kfree(lc_buf); kfree(dhc_buf); kfree(pc_buf); free_rsp_buf(resp_buftype, rsp); return rc; } Loading Loading
fs/cifs/cifsglob.h +1 −0 Original line number Diff line number Diff line Loading @@ -1082,6 +1082,7 @@ struct cifs_open_parms { int create_options; const char *path; struct cifs_fid *fid; umode_t mode; bool reconnect:1; }; Loading
fs/cifs/connect.c +11 −0 Original line number Diff line number Diff line Loading @@ -3963,6 +3963,12 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) goto remote_path_check; } #ifdef CONFIG_CIFS_SMB311 /* if new SMB3.11 POSIX extensions are supported do not remap / and \ */ if (tcon->posix_extensions) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; #endif /* SMB3.11 */ /* tell server which Unix caps we support */ if (cap_unix(tcon->ses)) { /* reset of caps checks mount to see if unix extensions Loading Loading @@ -4424,6 +4430,11 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) goto out; } #ifdef CONFIG_CIFS_SMB311 /* if new SMB3.11 POSIX extensions are supported do not remap / and \ */ if (tcon->posix_extensions) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; #endif /* SMB3.11 */ if (cap_unix(ses)) reset_cifs_unix_caps(0, tcon, NULL, vol_info); Loading
fs/cifs/dir.c +1 −1 Original line number Diff line number Diff line Loading @@ -369,7 +369,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, oparms.path = full_path; oparms.fid = fid; oparms.reconnect = false; oparms.mode = mode; rc = server->ops->open(xid, &oparms, oplock, buf); if (rc) { cifs_dbg(FYI, "cifs_create returned 0x%x\n", rc); Loading
fs/cifs/smb2misc.c +6 −0 Original line number Diff line number Diff line Loading @@ -455,8 +455,14 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb) /* Windows doesn't allow paths beginning with \ */ if (from[0] == '\\') start_of_path = from + 1; #ifdef CONFIG_CIFS_SMB311 /* SMB311 POSIX extensions paths do not include leading slash */ else if (cifs_sb_master_tcon(cifs_sb)->posix_extensions) start_of_path = from + 1; #endif /* 311 */ else start_of_path = from; to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len, cifs_sb->local_nls, map_type); return to; Loading
fs/cifs/smb2pdu.c +82 −2 Original line number Diff line number Diff line Loading @@ -519,6 +519,64 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp, return rc; } static struct create_posix * create_posix_buf(umode_t mode) { struct create_posix *buf; buf = kzalloc(sizeof(struct create_posix), GFP_KERNEL); if (!buf) return NULL; buf->ccontext.DataOffset = cpu_to_le16(offsetof(struct create_posix, Mode)); buf->ccontext.DataLength = cpu_to_le32(4); buf->ccontext.NameOffset = cpu_to_le16(offsetof(struct create_posix, Name)); buf->ccontext.NameLength = cpu_to_le16(16); /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */ buf->Name[0] = 0x93; buf->Name[1] = 0xAD; buf->Name[2] = 0x25; buf->Name[3] = 0x50; buf->Name[4] = 0x9C; buf->Name[5] = 0xB4; buf->Name[6] = 0x11; buf->Name[7] = 0xE7; buf->Name[8] = 0xB4; buf->Name[9] = 0x23; buf->Name[10] = 0x83; buf->Name[11] = 0xDE; buf->Name[12] = 0x96; buf->Name[13] = 0x8B; buf->Name[14] = 0xCD; buf->Name[15] = 0x7C; buf->Mode = cpu_to_le32(mode); cifs_dbg(FYI, "mode on posix create 0%o", mode); return buf; } static int add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode) { struct smb2_create_req *req = iov[0].iov_base; unsigned int num = *num_iovec; iov[num].iov_base = create_posix_buf(mode); if (iov[num].iov_base == NULL) return -ENOMEM; iov[num].iov_len = sizeof(struct create_posix); if (!req->CreateContextsOffset) req->CreateContextsOffset = cpu_to_le32( sizeof(struct smb2_create_req) + iov[num - 1].iov_len); le32_add_cpu(&req->CreateContextsLength, sizeof(struct create_posix)); *num_iovec = num + 1; return 0; } #else static void assemble_neg_contexts(struct smb2_negotiate_req *req, unsigned int *total_len) Loading Loading @@ -1837,7 +1895,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, struct TCP_Server_Info *server; struct cifs_tcon *tcon = oparms->tcon; struct cifs_ses *ses = tcon->ses; struct kvec iov[4]; struct kvec iov[5]; /* make sure at least one for each open context */ struct kvec rsp_iov = {NULL, 0}; int resp_buftype; int uni_path_len; Loading @@ -1846,7 +1904,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, int rc = 0; unsigned int n_iov = 2; __u32 file_attributes = 0; char *dhc_buf = NULL, *lc_buf = NULL; char *dhc_buf = NULL, *lc_buf = NULL, *pc_buf = NULL; int flags = 0; unsigned int total_len; Loading Loading @@ -1963,6 +2021,27 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, dhc_buf = iov[n_iov-1].iov_base; } #ifdef CONFIG_CIFS_SMB311 if (tcon->posix_extensions) { if (n_iov > 2) { struct create_context *ccontext = (struct create_context *)iov[n_iov-1].iov_base; ccontext->Next = cpu_to_le32(iov[n_iov-1].iov_len); } rc = add_posix_context(iov, &n_iov, oparms->mode); if (rc) { cifs_small_buf_release(req); kfree(copy_path); kfree(lc_buf); kfree(dhc_buf); return rc; } pc_buf = iov[n_iov-1].iov_base; } #endif /* SMB311 */ rc = smb2_send_recv(xid, ses, iov, n_iov, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); Loading Loading @@ -2004,6 +2083,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, kfree(copy_path); kfree(lc_buf); kfree(dhc_buf); kfree(pc_buf); free_rsp_buf(resp_buftype, rsp); return rc; } Loading