Query device characteristics at mount time from server on SMB2/3 not just on cifs...
authorSteven French <smfrench@gmail.com>
Wed, 9 Oct 2013 18:36:35 +0000 (13:36 -0500)
committerSteve French <smfrench@gmail.com>
Sat, 2 Nov 2013 17:52:38 +0000 (12:52 -0500)
Currently SMB2 and SMB3 mounts do not query the device information at mount time
from the server as is done for cifs.  These can be useful for debugging.
This is a minor patch, that extends the previous one (which added ability to
query file system attributes at mount time - this returns the device
characteristics - also via in /proc/fs/cifs/DebugData)

Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2proto.h

index a53e2053ae9df9699ebfc1e85cf9ed5c69f4197c..79084d67f3fb2293b3ebc87608818bf9f6d5dc0c 100644 (file)
@@ -229,7 +229,10 @@ smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
        if (rc)
                return;
 
-       SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid);
+       SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+                       FS_ATTRIBUTE_INFORMATION);
+       SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+                       FS_DEVICE_INFORMATION);
        SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
        return;
 }
index df12cf8bd979719d8d53bd17d937a0b9dcdd31e4..7887cf50e5fb101cb0bba642eb1f91734ee28aa0 100644 (file)
@@ -2358,17 +2358,27 @@ qfsinf_exit:
 
 int
 SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
-             u64 persistent_fid, u64 volatile_fid)
+             u64 persistent_fid, u64 volatile_fid, int level)
 {
        struct smb2_query_info_rsp *rsp = NULL;
        struct kvec iov;
        int rc = 0;
-       int resp_buftype;
+       int resp_buftype, max_len, min_len;
        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),
+       if (level == FS_DEVICE_INFORMATION) {
+               max_len = sizeof(FILE_SYSTEM_DEVICE_INFO);
+               min_len = sizeof(FILE_SYSTEM_DEVICE_INFO);
+       } else if (level == FS_ATTRIBUTE_INFORMATION) {
+               max_len = sizeof(FILE_SYSTEM_ATTRIBUTE_INFO);
+               min_len = MIN_FS_ATTR_INFO_SIZE;
+       } else {
+               cifs_dbg(FYI, "Invalid qfsinfo level %d", level);
+               return -EINVAL;
+       }
+
+       rc = build_qfs_info_req(&iov, tcon, level, max_len,
                                persistent_fid, volatile_fid);
        if (rc)
                return rc;
@@ -2382,12 +2392,17 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
 
        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) {
+       rc = validate_buf(offset, rsp_len, &rsp->hdr, min_len);
+       if (rc)
+               goto qfsattr_exit;
+
+       if (level == FS_ATTRIBUTE_INFORMATION)
                memcpy(&tcon->fsAttrInfo, 4 /* RFC1001 len */ + offset
                        + (char *)&rsp->hdr, min_t(unsigned int,
-                       rsp_len, sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)));
-       }
+                       rsp_len, max_len));
+       else if (level == FS_DEVICE_INFORMATION)
+               memcpy(&tcon->fsDevInfo, 4 /* RFC1001 len */ + offset
+                       + (char *)&rsp->hdr, sizeof(FILE_SYSTEM_DEVICE_INFO));
 
 qfsattr_exit:
        free_rsp_buf(resp_buftype, iov.iov_base);
index 68dc00d5fb126fb3c8ea218724a1a8c56d4aa06e..313813e4c19b300357bfc5f6db225a3be85d1121 100644 (file)
@@ -151,7 +151,7 @@ extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
                         u64 persistent_file_id, u64 volatile_file_id,
                         struct kstatfs *FSData);
 extern int SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
-                        u64 persistent_file_id, u64 volatile_file_id);
+                        u64 persistent_file_id, u64 volatile_file_id, int lvl);
 extern int SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon,
                     const __u64 persist_fid, const __u64 volatile_fid,
                     const __u32 pid, const __u64 length, const __u64 offset,