Commit 21ba3845 authored by Steve French's avatar Steve French
Browse files

smb3: fill in statfs fsid and correct namelen



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: default avatarSteve French <stfrench@gmail.com>
CC: Stable <stable@vger.kernel.org>
Reviewed-by: default avatarAurelien Aptel <aaptel@suse.com>
parent a12d0c59
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -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.
	 */
	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 */

+2 −0
Original line number Diff line number Diff line
@@ -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)
+8 −0
Original line number Diff line number Diff line
@@ -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:
+11 −0
Original line number Diff line number Diff line
@@ -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