smb3: fill in statfs fsid and correct namelen
authorSteve French <stfrench@microsoft.com>
Mon, 25 Jun 2018 04:18:52 +0000 (23:18 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Sep 2018 07:26:33 +0000 (09:26 +0200)
commit 21ba3845b59c733a79ed4fe1c4f3732e7ece9df7 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/cifs/cifsfs.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h

index 490c5fc9e69c6f075c6009b7d5fea3a1314f7a28..44a7b2dea6882ad3769cd9e5e22aef355bb186b5 100644 (file)
@@ -197,14 +197,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 badbb50140b1d727be58fb97253ca86210d14992..e9f246fe9d800be105f48963dd8894ade2f8d16b 100644 (file)
@@ -332,6 +332,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 */
        SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
index 71b81980787fce27a478e080faf276e80f9d65a1..e317e9a400c14ddb0677dc529653b45006ab1e1f 100644 (file)
@@ -3455,6 +3455,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;
@@ -3495,6 +3498,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 c2ec934be96891a645537140df279b0fb3e2fcbe..e5245405972566b77b3d35f97315f2f16a2748d3 100644 (file)
@@ -1108,6 +1108,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