]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Aug 2018 16:54:39 +0000 (09:54 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Aug 2018 16:54:39 +0000 (09:54 -0700)
added patches:
btrfs-don-t-leak-ret-from-do_chunk_alloc.patch
btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch
cifs-add-missing-debug-entries-for-kconfig-options.patch
cifs-check-kmalloc-before-use.patch
smb3-do-not-send-smb3-set_info-if-nothing-changed.patch
smb3-don-t-request-leases-in-symlink-creation-and-query.patch
smb3-fill-in-statfs-fsid-and-correct-namelen.patch

queue-4.4/btrfs-don-t-leak-ret-from-do_chunk_alloc.patch [new file with mode: 0644]
queue-4.4/btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch [new file with mode: 0644]
queue-4.4/cifs-add-missing-debug-entries-for-kconfig-options.patch [new file with mode: 0644]
queue-4.4/cifs-check-kmalloc-before-use.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/smb3-do-not-send-smb3-set_info-if-nothing-changed.patch [new file with mode: 0644]
queue-4.4/smb3-don-t-request-leases-in-symlink-creation-and-query.patch [new file with mode: 0644]
queue-4.4/smb3-fill-in-statfs-fsid-and-correct-namelen.patch [new file with mode: 0644]

diff --git a/queue-4.4/btrfs-don-t-leak-ret-from-do_chunk_alloc.patch b/queue-4.4/btrfs-don-t-leak-ret-from-do_chunk_alloc.patch
new file mode 100644 (file)
index 0000000..ffe8527
--- /dev/null
@@ -0,0 +1,35 @@
+From 4559b0a71749c442d34f7cfb9e72c9e58db83948 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Thu, 19 Jul 2018 10:49:51 -0400
+Subject: btrfs: don't leak ret from do_chunk_alloc
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 4559b0a71749c442d34f7cfb9e72c9e58db83948 upstream.
+
+If we're trying to make a data reservation and we have to allocate a
+data chunk we could leak ret == 1, as do_chunk_alloc() will return 1 if
+it allocated a chunk.  Since the end of the function is the success path
+just return 0.
+
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/extent-tree.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4128,7 +4128,7 @@ commit_trans:
+                                     data_sinfo->flags, bytes, 1);
+       spin_unlock(&data_sinfo->lock);
+-      return ret;
++      return 0;
+ }
+ /*
diff --git a/queue-4.4/btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch b/queue-4.4/btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch
new file mode 100644 (file)
index 0000000..0aa797c
--- /dev/null
@@ -0,0 +1,141 @@
+From 0d836392cadd5535f4184d46d901a82eb276ed62 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Fri, 20 Jul 2018 10:59:06 +0100
+Subject: Btrfs: fix mount failure after fsync due to hard link recreation
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 0d836392cadd5535f4184d46d901a82eb276ed62 upstream.
+
+If we end up with logging an inode reference item which has the same name
+but different index from the one we have persisted, we end up failing when
+replaying the log with an errno value of -EEXIST. The error comes from
+btrfs_add_link(), which is called from add_inode_ref(), when we are
+replaying an inode reference item.
+
+Example scenario where this happens:
+
+  $ mkfs.btrfs -f /dev/sdb
+  $ mount /dev/sdb /mnt
+
+  $ touch /mnt/foo
+  $ ln /mnt/foo /mnt/bar
+
+  $ sync
+
+  # Rename the first hard link (foo) to a new name and rename the second
+  # hard link (bar) to the old name of the first hard link (foo).
+  $ mv /mnt/foo /mnt/qwerty
+  $ mv /mnt/bar /mnt/foo
+
+  # Create a new file, in the same parent directory, with the old name of
+  # the second hard link (bar) and fsync this new file.
+  # We do this instead of calling fsync on foo/qwerty because if we did
+  # that the fsync resulted in a full transaction commit, not triggering
+  # the problem.
+  $ touch /mnt/bar
+  $ xfs_io -c "fsync" /mnt/bar
+
+  <power fail>
+
+  $ mount /dev/sdb /mnt
+  mount: mount /dev/sdb on /mnt failed: File exists
+
+So fix this by checking if a conflicting inode reference exists (same
+name, same parent but different index), removing it (and the associated
+dir index entries from the parent inode) if it exists, before attempting
+to add the new reference.
+
+A test case for fstests follows soon.
+
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/tree-log.c |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 66 insertions(+)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -1188,6 +1188,46 @@ static int ref_get_fields(struct extent_
+       return 0;
+ }
++static int btrfs_inode_ref_exists(struct inode *inode, struct inode *dir,
++                                const u8 ref_type, const char *name,
++                                const int namelen)
++{
++      struct btrfs_key key;
++      struct btrfs_path *path;
++      const u64 parent_id = btrfs_ino(BTRFS_I(dir));
++      int ret;
++
++      path = btrfs_alloc_path();
++      if (!path)
++              return -ENOMEM;
++
++      key.objectid = btrfs_ino(BTRFS_I(inode));
++      key.type = ref_type;
++      if (key.type == BTRFS_INODE_REF_KEY)
++              key.offset = parent_id;
++      else
++              key.offset = btrfs_extref_hash(parent_id, name, namelen);
++
++      ret = btrfs_search_slot(NULL, BTRFS_I(inode)->root, &key, path, 0, 0);
++      if (ret < 0)
++              goto out;
++      if (ret > 0) {
++              ret = 0;
++              goto out;
++      }
++      if (key.type == BTRFS_INODE_EXTREF_KEY)
++              ret = btrfs_find_name_in_ext_backref(path->nodes[0],
++                                                   path->slots[0], parent_id,
++                                                   name, namelen, NULL);
++      else
++              ret = btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
++                                               name, namelen, NULL);
++
++out:
++      btrfs_free_path(path);
++      return ret;
++}
++
+ /*
+  * replay one inode back reference item found in the log tree.
+  * eb, slot and key refer to the buffer and key found in the log tree.
+@@ -1295,6 +1335,32 @@ static noinline int add_inode_ref(struct
+                               }
+                       }
++                      /*
++                       * If a reference item already exists for this inode
++                       * with the same parent and name, but different index,
++                       * drop it and the corresponding directory index entries
++                       * from the parent before adding the new reference item
++                       * and dir index entries, otherwise we would fail with
++                       * -EEXIST returned from btrfs_add_link() below.
++                       */
++                      ret = btrfs_inode_ref_exists(inode, dir, key->type,
++                                                   name, namelen);
++                      if (ret > 0) {
++                              ret = btrfs_unlink_inode(trans, root,
++                                                       BTRFS_I(dir),
++                                                       BTRFS_I(inode),
++                                                       name, namelen);
++                              /*
++                               * If we dropped the link count to 0, bump it so
++                               * that later the iput() on the inode will not
++                               * free it. We will fixup the link count later.
++                               */
++                              if (!ret && inode->i_nlink == 0)
++                                      inc_nlink(inode);
++                      }
++                      if (ret < 0)
++                              goto out;
++
+                       /* insert our name */
+                       ret = btrfs_add_link(trans, dir, inode, name, namelen,
+                                            0, ref_index);
diff --git a/queue-4.4/cifs-add-missing-debug-entries-for-kconfig-options.patch b/queue-4.4/cifs-add-missing-debug-entries-for-kconfig-options.patch
new file mode 100644 (file)
index 0000000..3330cb8
--- /dev/null
@@ -0,0 +1,84 @@
+From 950132afd59385caf6e2b84e5235d069fa10681d Mon Sep 17 00:00:00 2001
+From: Steve French <stfrench@microsoft.com>
+Date: Thu, 28 Jun 2018 18:46:40 -0500
+Subject: cifs: add missing debug entries for kconfig options
+
+From: Steve French <stfrench@microsoft.com>
+
+commit 950132afd59385caf6e2b84e5235d069fa10681d upstream.
+
+/proc/fs/cifs/DebugData displays the features (Kconfig options)
+used to build cifs.ko but it was missing some, and needed comma
+separator.  These can be useful in debugging certain problems
+so we know which optional features were enabled in the user's build.
+Also clarify them, by making them more closely match the
+corresponding CONFIG_CIFS_* parm.
+
+Old format:
+Features: dfs fscache posix spnego xattr acl
+
+New format:
+Features: DFS,FSCACHE,SMB_DIRECT,STATS,DEBUG2,ALLOW_INSECURE_LEGACY,CIFS_POSIX,UPCALL(SPNEGO),XATTR,ACL
+
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Reviewed-by: Paulo Alcantara <palcantara@suse.de>
+CC: Stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifs_debug.c |   30 +++++++++++++++++++++++-------
+ 1 file changed, 23 insertions(+), 7 deletions(-)
+
+--- a/fs/cifs/cifs_debug.c
++++ b/fs/cifs/cifs_debug.c
+@@ -123,25 +123,41 @@ static int cifs_debug_data_proc_show(str
+       seq_printf(m, "CIFS Version %s\n", CIFS_VERSION);
+       seq_printf(m, "Features:");
+ #ifdef CONFIG_CIFS_DFS_UPCALL
+-      seq_printf(m, " dfs");
++      seq_printf(m, " DFS");
+ #endif
+ #ifdef CONFIG_CIFS_FSCACHE
+-      seq_printf(m, " fscache");
++      seq_printf(m, ",FSCACHE");
++#endif
++#ifdef CONFIG_CIFS_SMB_DIRECT
++      seq_printf(m, ",SMB_DIRECT");
++#endif
++#ifdef CONFIG_CIFS_STATS2
++      seq_printf(m, ",STATS2");
++#elif defined(CONFIG_CIFS_STATS)
++      seq_printf(m, ",STATS");
++#endif
++#ifdef CONFIG_CIFS_DEBUG2
++      seq_printf(m, ",DEBUG2");
++#elif defined(CONFIG_CIFS_DEBUG)
++      seq_printf(m, ",DEBUG");
++#endif
++#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
++      seq_printf(m, ",ALLOW_INSECURE_LEGACY");
+ #endif
+ #ifdef CONFIG_CIFS_WEAK_PW_HASH
+-      seq_printf(m, " lanman");
++      seq_printf(m, ",WEAK_PW_HASH");
+ #endif
+ #ifdef CONFIG_CIFS_POSIX
+-      seq_printf(m, " posix");
++      seq_printf(m, ",CIFS_POSIX");
+ #endif
+ #ifdef CONFIG_CIFS_UPCALL
+-      seq_printf(m, " spnego");
++      seq_printf(m, ",UPCALL(SPNEGO)");
+ #endif
+ #ifdef CONFIG_CIFS_XATTR
+-      seq_printf(m, " xattr");
++      seq_printf(m, ",XATTR");
+ #endif
+ #ifdef CONFIG_CIFS_ACL
+-      seq_printf(m, " acl");
++      seq_printf(m, ",ACL");
+ #endif
+       seq_putc(m, '\n');
+       seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
diff --git a/queue-4.4/cifs-check-kmalloc-before-use.patch b/queue-4.4/cifs-check-kmalloc-before-use.patch
new file mode 100644 (file)
index 0000000..0a3d8e1
--- /dev/null
@@ -0,0 +1,38 @@
+From 126c97f4d0d1b5b956e8b0740c81a2b2a2ae548c Mon Sep 17 00:00:00 2001
+From: Nicholas Mc Guire <hofrat@osadl.org>
+Date: Thu, 23 Aug 2018 12:24:02 +0200
+Subject: cifs: check kmalloc before use
+
+From: Nicholas Mc Guire <hofrat@osadl.org>
+
+commit 126c97f4d0d1b5b956e8b0740c81a2b2a2ae548c upstream.
+
+The kmalloc was not being checked - if it fails issue a warning
+and return -ENOMEM to the caller.
+
+Signed-off-by: Nicholas Mc Guire <hofrat@osadl.org>
+Fixes: b8da344b74c8 ("cifs: dynamic allocation of ntlmssp blob")
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+cc: Stable <stable@vger.kernel.org>`
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/sess.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -398,6 +398,12 @@ int build_ntlmssp_auth_blob(unsigned cha
+               goto setup_ntlmv2_ret;
+       }
+       *pbuffer = kmalloc(size_of_ntlmssp_blob(ses), GFP_KERNEL);
++      if (!*pbuffer) {
++              rc = -ENOMEM;
++              cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
++              *buflen = 0;
++              goto setup_ntlmv2_ret;
++      }
+       sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
+       memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
index a674c4a0fc86fd2dfcaa3d66504039404611a713..87a7b2254b3a0f745441c14afcd27b2ddd3587a0 100644 (file)
@@ -38,3 +38,10 @@ drivers-net-lmc-fix-case-value-for-target-abort-error.patch
 scsi-fcoe-drop-frames-in-els-logo-error-path.patch
 scsi-vmw_pvscsi-return-did_reset-for-status-sam_stat_command_terminated.patch
 mm-memory.c-check-return-value-of-ioremap_prot.patch
+cifs-add-missing-debug-entries-for-kconfig-options.patch
+cifs-check-kmalloc-before-use.patch
+smb3-do-not-send-smb3-set_info-if-nothing-changed.patch
+smb3-don-t-request-leases-in-symlink-creation-and-query.patch
+smb3-fill-in-statfs-fsid-and-correct-namelen.patch
+btrfs-don-t-leak-ret-from-do_chunk_alloc.patch
+btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch
diff --git a/queue-4.4/smb3-do-not-send-smb3-set_info-if-nothing-changed.patch b/queue-4.4/smb3-do-not-send-smb3-set_info-if-nothing-changed.patch
new file mode 100644 (file)
index 0000000..3eccc33
--- /dev/null
@@ -0,0 +1,53 @@
+From fd09b7d3b352105f08b8e02f7afecf7e816380ef Mon Sep 17 00:00:00 2001
+From: Steve French <stfrench@microsoft.com>
+Date: Thu, 2 Aug 2018 20:28:18 -0500
+Subject: smb3: Do not send SMB3 SET_INFO if nothing changed
+
+From: Steve French <stfrench@microsoft.com>
+
+commit fd09b7d3b352105f08b8e02f7afecf7e816380ef upstream.
+
+An earlier commit had a typo which prevented the
+optimization from working:
+
+commit 18dd8e1a65dd ("Do not send SMB3 SET_INFO request if nothing is changing")
+
+Thank you to Metze for noticing this.  Also clear a
+reserved field in the FILE_BASIC_INFO struct we send
+that should be zero (all the other fields in that
+struct were set or cleared explicitly already in
+cifs_set_file_info).
+
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+CC: Stable <stable@vger.kernel.org> # 4.9.x+
+Reported-by: Stefan Metzmacher <metze@samba.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/inode.c     |    2 ++
+ fs/cifs/smb2inode.c |    2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -1063,6 +1063,8 @@ cifs_set_file_info(struct inode *inode,
+       if (!server->ops->set_file_info)
+               return -ENOSYS;
++      info_buf.Pad = 0;
++
+       if (attrs->ia_valid & ATTR_ATIME) {
+               set_time = true;
+               info_buf.LastAccessTime =
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -267,7 +267,7 @@ smb2_set_file_info(struct inode *inode,
+       int rc;
+       if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) &&
+-          (buf->LastWriteTime == 0) && (buf->ChangeTime) &&
++          (buf->LastWriteTime == 0) && (buf->ChangeTime == 0) &&
+           (buf->Attributes == 0))
+               return 0; /* would be a no op, no sense sending this */
diff --git a/queue-4.4/smb3-don-t-request-leases-in-symlink-creation-and-query.patch b/queue-4.4/smb3-don-t-request-leases-in-symlink-creation-and-query.patch
new file mode 100644 (file)
index 0000000..640416a
--- /dev/null
@@ -0,0 +1,42 @@
+From 22783155f4bf956c346a81624ec9258930a6fe06 Mon Sep 17 00:00:00 2001
+From: Steve French <stfrench@microsoft.com>
+Date: Fri, 27 Jul 2018 22:01:49 -0500
+Subject: smb3: don't request leases in symlink creation and query
+
+From: Steve French <stfrench@microsoft.com>
+
+commit 22783155f4bf956c346a81624ec9258930a6fe06 upstream.
+
+Fixes problem pointed out by Pavel in discussions about commit
+729c0c9dd55204f0c9a823ac8a7bfa83d36c7e78
+
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
+CC: Stable <stable@vger.kernel.org> # 3.18.x+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/link.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/cifs/link.c
++++ b/fs/cifs/link.c
+@@ -419,7 +419,7 @@ smb3_query_mf_symlink(unsigned int xid,
+       struct cifs_io_parms io_parms;
+       int buf_type = CIFS_NO_BUFFER;
+       __le16 *utf16_path;
+-      __u8 oplock = SMB2_OPLOCK_LEVEL_II;
++      __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+       struct smb2_file_all_info *pfile_info = NULL;
+       oparms.tcon = tcon;
+@@ -481,7 +481,7 @@ smb3_create_mf_symlink(unsigned int xid,
+       struct cifs_io_parms io_parms;
+       int create_options = CREATE_NOT_DIR;
+       __le16 *utf16_path;
+-      __u8 oplock = SMB2_OPLOCK_LEVEL_EXCLUSIVE;
++      __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+       struct kvec iov[2];
+       if (backup_cred(cifs_sb))
diff --git a/queue-4.4/smb3-fill-in-statfs-fsid-and-correct-namelen.patch b/queue-4.4/smb3-fill-in-statfs-fsid-and-correct-namelen.patch
new file mode 100644 (file)
index 0000000..402fbd0
--- /dev/null
@@ -0,0 +1,112 @@
+From 21ba3845b59c733a79ed4fe1c4f3732e7ece9df7 Mon Sep 17 00:00:00 2001
+From: Steve French <stfrench@microsoft.com>
+Date: Sun, 24 Jun 2018 23:18:52 -0500
+Subject: smb3: fill in statfs fsid and correct namelen
+
+From: Steve French <stfrench@microsoft.com>
+
+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  |   18 ++++++++++--------
+ fs/cifs/smb2ops.c |    2 ++
+ fs/cifs/smb2pdu.c |    8 ++++++++
+ fs/cifs/smb2pdu.h |   11 +++++++++++
+ 4 files changed, 31 insertions(+), 8 deletions(-)
+
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -189,14 +189,16 @@ cifs_statfs(struct dentry *dentry, struc
+       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 */
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -316,6 +316,8 @@ smb3_qfs_tcon(const unsigned int xid, st
+       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);
+       return;
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -2875,6 +2875,9 @@ SMB2_QFS_attr(const unsigned int xid, st
+       } 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;
+@@ -2911,6 +2914,11 @@ SMB2_QFS_attr(const unsigned int xid, st
+               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:
+--- a/fs/cifs/smb2pdu.h
++++ b/fs/cifs/smb2pdu.h
+@@ -1085,6 +1085,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