aboutsummaryrefslogtreecommitdiff
path: root/fs/cifs/smb2inode.c
diff options
context:
space:
mode:
authorLinus Torvalds2020-06-13 13:43:56 -0700
committerLinus Torvalds2020-06-13 13:43:56 -0700
commitf82e7b57b5fc48199e2f26ffafe2f96f7338ad3d (patch)
tree600f2f00d844ce755d08ff154cc629eb4f842586 /fs/cifs/smb2inode.c
parent4f9b3a377549e2b585f5e1910c247913b49e6c83 (diff)
parenta7a519a4926214ba4161bc30109f4a8d69defb8d (diff)
Merge tag '5.8-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
Pull more cifs updates from Steve French: "12 cifs/smb3 fixes, 2 for stable. - add support for idsfromsid on create and chgrp/chown allowing ability to save owner information more naturally for some workloads - improve query info (getattr) when SMB3.1.1 posix extensions are negotiated by using new query info level" * tag '5.8-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6: smb3: Add debug message for new file creation with idsfromsid mount option cifs: fix chown and chgrp when idsfromsid mount option enabled smb3: allow uid and gid owners to be set on create with idsfromsid mount option smb311: Add tracepoints for new compound posix query info smb311: add support for using info level for posix extensions query smb311: Add support for lookup with posix extensions query info smb311: Add support for SMB311 query info (non-compounded) SMB311: Add support for query info using posix extensions (level 100) smb3: add indatalen that can be a non-zero value to calculation of credit charge in smb2 ioctl smb3: fix typo in mount options displayed in /proc/mounts cifs: Add get_security_type_str function to return sec type. smb3: extend fscache mount volume coherency check
Diffstat (limited to 'fs/cifs/smb2inode.c')
-rw-r--r--fs/cifs/smb2inode.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index 0a116fc490a9..b9db73687eaa 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -166,6 +166,40 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid,
full_path);
break;
+ case SMB2_OP_POSIX_QUERY_INFO:
+ rqst[num_rqst].rq_iov = &vars->qi_iov[0];
+ rqst[num_rqst].rq_nvec = 1;
+
+ if (cfile)
+ rc = SMB2_query_info_init(tcon, server,
+ &rqst[num_rqst],
+ cfile->fid.persistent_fid,
+ cfile->fid.volatile_fid,
+ SMB_FIND_FILE_POSIX_INFO,
+ SMB2_O_INFO_FILE, 0,
+ /* TBD: fix following to allow for longer SIDs */
+ sizeof(struct smb311_posix_qinfo *) + (PATH_MAX * 2) +
+ (sizeof(struct cifs_sid) * 2), 0, NULL);
+ else {
+ rc = SMB2_query_info_init(tcon, server,
+ &rqst[num_rqst],
+ COMPOUND_FID,
+ COMPOUND_FID,
+ SMB_FIND_FILE_POSIX_INFO,
+ SMB2_O_INFO_FILE, 0,
+ sizeof(struct smb311_posix_qinfo *) + (PATH_MAX * 2) +
+ (sizeof(struct cifs_sid) * 2), 0, NULL);
+ if (!rc) {
+ smb2_set_next_command(tcon, &rqst[num_rqst]);
+ smb2_set_related(&rqst[num_rqst]);
+ }
+ }
+
+ if (rc)
+ goto finished;
+ num_rqst++;
+ trace_smb3_posix_query_info_compound_enter(xid, ses->Suid, tcon->tid, full_path);
+ break;
case SMB2_OP_DELETE:
trace_smb3_delete_enter(xid, ses->Suid, tcon->tid, full_path);
break;
@@ -379,6 +413,24 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
trace_smb3_query_info_compound_done(xid, ses->Suid,
tcon->tid);
break;
+ case SMB2_OP_POSIX_QUERY_INFO:
+ if (rc == 0) {
+ qi_rsp = (struct smb2_query_info_rsp *)
+ rsp_iov[1].iov_base;
+ rc = smb2_validate_and_copy_iov(
+ le16_to_cpu(qi_rsp->OutputBufferOffset),
+ le32_to_cpu(qi_rsp->OutputBufferLength),
+ &rsp_iov[1], sizeof(struct smb311_posix_qinfo) /* add SIDs */, ptr);
+ }
+ if (rqst[1].rq_iov)
+ SMB2_query_info_free(&rqst[1]);
+ if (rqst[2].rq_iov)
+ SMB2_close_free(&rqst[2]);
+ if (rc)
+ trace_smb3_posix_query_info_compound_err(xid, ses->Suid, tcon->tid, rc);
+ else
+ trace_smb3_posix_query_info_compound_done(xid, ses->Suid, tcon->tid);
+ break;
case SMB2_OP_DELETE:
if (rc)
trace_smb3_delete_err(xid, ses->Suid, tcon->tid, rc);
@@ -512,6 +564,59 @@ out:
return rc;
}
+
+int
+smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb, const char *full_path,
+ struct smb311_posix_qinfo *data, bool *adjust_tz, bool *symlink)
+{
+ int rc;
+ __u32 create_options = 0;
+ struct cifsFileInfo *cfile;
+ struct smb311_posix_qinfo *smb2_data;
+
+ *adjust_tz = false;
+ *symlink = false;
+
+ /* BB TODO: Make struct larger when add support for parsing owner SIDs */
+ smb2_data = kzalloc(sizeof(struct smb311_posix_qinfo),
+ GFP_KERNEL);
+ if (smb2_data == NULL)
+ return -ENOMEM;
+
+ /*
+ * BB TODO: Add support for using the cached root handle.
+ * Create SMB2_query_posix_info worker function to do non-compounded query
+ * when we already have an open file handle for this. For now this is fast enough
+ * (always using the compounded version).
+ */
+
+ cifs_get_readable_path(tcon, full_path, &cfile);
+ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+ FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
+ ACL_NO_MODE, smb2_data, SMB2_OP_POSIX_QUERY_INFO, cfile);
+ if (rc == -EOPNOTSUPP) {
+ /* BB TODO: When support for special files added to Samba re-verify this path */
+ *symlink = true;
+ create_options |= OPEN_REPARSE_POINT;
+
+ /* Failed on a symbolic link - query a reparse point info */
+ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+ FILE_READ_ATTRIBUTES, FILE_OPEN,
+ create_options, ACL_NO_MODE,
+ smb2_data, SMB2_OP_POSIX_QUERY_INFO, NULL);
+ }
+ if (rc)
+ goto out;
+
+ /* TODO: will need to allow for the 2 SIDs when add support for getting owner UID/GID */
+ memcpy(data, smb2_data, sizeof(struct smb311_posix_qinfo));
+
+out:
+ kfree(smb2_data);
+ return rc;
+}
+
int
smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode,
struct cifs_tcon *tcon, const char *name,