]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
smb3: fill in statfs fsid and correct namelen
authorSteve French <stfrench@microsoft.com>
Mon, 25 Jun 2018 04:18:52 +0000 (23:18 -0500)
committerSteve French <stfrench@microsoft.com>
Tue, 7 Aug 2018 19:15:41 +0000 (14:15 -0500)
Fil in the correct namelen (typically 255 not 4096) in the
statfs response and also fill in a reasonably unique fsid
(in this case taken from the volume id, and the creation time
of the volume).

In the case of the POSIX statfs all fields are now filled in,
and in the case of non-POSIX mounts, all fields are filled
in which can be.

Signed-off-by: Steve French <stfrench@gmail.com>
CC: Stable <stable@vger.kernel.org>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
fs/cifs/cifsfs.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h

index d5aa7ae917bf1c4d08b4f055bc80051713d94801..69ec5427769cd55dacb1a3c8339838b762779577 100644 (file)
@@ -209,14 +209,16 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
 
        xid = get_xid();
 
-       /*
-        * PATH_MAX may be too long - it would presumably be total path,
-        * but note that some servers (includinng Samba 3) have a shorter
-        * maximum path.
-        *
-        * Instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO.
-        */
-       buf->f_namelen = PATH_MAX;
+       if (le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength) > 0)
+               buf->f_namelen =
+                      le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength);
+       else
+               buf->f_namelen = PATH_MAX;
+
+       buf->f_fsid.val[0] = tcon->vol_serial_number;
+       /* are using part of create time for more randomness, see man statfs */
+       buf->f_fsid.val[1] =  (int)le64_to_cpu(tcon->vol_create_time);
+
        buf->f_files = 0;       /* undefined */
        buf->f_ffree = 0;       /* unlimited */
 
index ae64cbef5e07257a811b35adbe6db517a25f271f..09506d918ecb8656fa746f6563870084f5b1b1a4 100644 (file)
@@ -548,6 +548,8 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
                        FS_ATTRIBUTE_INFORMATION);
        SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
                        FS_DEVICE_INFORMATION);
+       SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+                       FS_VOLUME_INFORMATION);
        SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
                        FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
        if (no_cached_open)
index 641fe79708d0e3dde139a2e6728c2b506645f97a..6852ff5f06be53c19c762ace8a4ed74de2d67ecd 100644 (file)
@@ -4045,6 +4045,9 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
        } else if (level == FS_SECTOR_SIZE_INFORMATION) {
                max_len = sizeof(struct smb3_fs_ss_info);
                min_len = sizeof(struct smb3_fs_ss_info);
+       } else if (level == FS_VOLUME_INFORMATION) {
+               max_len = sizeof(struct smb3_fs_vol_info) + MAX_VOL_LABEL_LEN;
+               min_len = sizeof(struct smb3_fs_vol_info);
        } else {
                cifs_dbg(FYI, "Invalid qfsinfo level %d\n", level);
                return -EINVAL;
@@ -4089,6 +4092,11 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
                tcon->ss_flags = le32_to_cpu(ss_info->Flags);
                tcon->perf_sector_size =
                        le32_to_cpu(ss_info->PhysicalBytesPerSectorForPerf);
+       } else if (level == FS_VOLUME_INFORMATION) {
+               struct smb3_fs_vol_info *vol_info = (struct smb3_fs_vol_info *)
+                       (offset + (char *)rsp);
+               tcon->vol_serial_number = vol_info->VolumeSerialNumber;
+               tcon->vol_create_time = vol_info->VolumeCreationTime;
        }
 
 qfsattr_exit:
index a671adcc44a6c8c6d460585c9b2c8d6b546fc015..c2a4526512b5501b09196e1c7396b811baa865cc 100644 (file)
@@ -1248,6 +1248,17 @@ struct smb3_fs_ss_info {
        __le32 ByteOffsetForPartitionAlignment;
 } __packed;
 
+/* volume info struct - see MS-FSCC 2.5.9 */
+#define MAX_VOL_LABEL_LEN      32
+struct smb3_fs_vol_info {
+       __le64  VolumeCreationTime;
+       __u32   VolumeSerialNumber;
+       __le32  VolumeLabelLength; /* includes trailing null */
+       __u8    SupportsObjects; /* True if eg like NTFS, supports objects */
+       __u8    Reserved;
+       __u8    VolumeLabel[0]; /* variable len */
+} __packed;
+
 /* partial list of QUERY INFO levels */
 #define FILE_DIRECTORY_INFORMATION     1
 #define FILE_FULL_DIRECTORY_INFORMATION 2