diff options
author | Steve French <smfrench@gmail.com> | 2013-10-09 02:07:00 -0500 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-10-28 09:22:55 -0500 |
commit | 34f626406c09dd45878ce75170abab342985ec24 (patch) | |
tree | 6904e8c808392920874febebf28129e6d1a1b974 /fs/cifs/smb2pdu.c | |
parent | 64a5cfa6db94c5abba2cafe77aca077dd1e3283b (diff) | |
download | lwn-34f626406c09dd45878ce75170abab342985ec24.tar.gz lwn-34f626406c09dd45878ce75170abab342985ec24.zip |
Query file system attributes from server on SMB2, not just cifs, mounts
Currently SMB2 and SMB3 mounts do not query the file system attributes
from the server at mount time as is done for cifs. These can be useful for debugging.
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/smb2pdu.c')
-rw-r--r-- | fs/cifs/smb2pdu.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index bbafa12e83b2..df12cf8bd979 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2339,7 +2339,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0); if (rc) { cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); - goto qinf_exit; + goto qfsinf_exit; } rsp = (struct smb2_query_info_rsp *)iov.iov_base; @@ -2351,7 +2351,45 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, if (!rc) copy_fs_info_to_kstatfs(info, fsdata); -qinf_exit: +qfsinf_exit: + free_rsp_buf(resp_buftype, iov.iov_base); + return rc; +} + +int +SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid) +{ + struct smb2_query_info_rsp *rsp = NULL; + struct kvec iov; + int rc = 0; + int resp_buftype; + struct cifs_ses *ses = tcon->ses; + unsigned int rsp_len, offset; + + rc = build_qfs_info_req(&iov, tcon, SMB_QUERY_FS_ATTRIBUTE_INFO, + sizeof(FILE_SYSTEM_ATTRIBUTE_INFO), + persistent_fid, volatile_fid); + if (rc) + return rc; + + rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0); + if (rc) { + cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); + goto qfsattr_exit; + } + rsp = (struct smb2_query_info_rsp *)iov.iov_base; + + rsp_len = le32_to_cpu(rsp->OutputBufferLength); + offset = le16_to_cpu(rsp->OutputBufferOffset); + rc = validate_buf(offset, rsp_len, &rsp->hdr, MIN_FS_ATTR_INFO_SIZE); + if (!rc) { + memcpy(&tcon->fsAttrInfo, 4 /* RFC1001 len */ + offset + + (char *)&rsp->hdr, min_t(unsigned int, + rsp_len, sizeof(FILE_SYSTEM_ATTRIBUTE_INFO))); + } + +qfsattr_exit: free_rsp_buf(resp_buftype, iov.iov_base); return rc; } |