]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Aug 2018 16:54:32 +0000 (09:54 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Aug 2018 16:54:32 +0000 (09:54 -0700)
added patches:
btrfs-don-t-leak-ret-from-do_chunk_alloc.patch
btrfs-fix-btrfs_write_inode-vs-delayed-iput-deadlock.patch
btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch
btrfs-fix-send-failure-when-root-has-deleted-files-still-open.patch
btrfs-send-fix-incorrect-file-layout-after-hole-punching-beyond-eof.patch
btrfs-use-correct-compare-function-of-dirty_metadata_bytes.patch
cifs-add-missing-debug-entries-for-kconfig-options.patch
cifs-add-missing-support-for-acls-in-smb-3.11.patch
cifs-check-kmalloc-before-use.patch
cifs-fix-uninitialized-ptr-deref-in-smb2-signing.patch
cifs-use-a-refcount-to-protect-open-closing-the-cached-file-handle.patch
hwmon-k10temp-27c-offset-needed-for-threadripper2.patch
smb3-do-not-send-smb3-set_info-if-nothing-changed.patch
smb3-don-t-request-leases-in-symlink-creation-and-query.patch
smb3-enumerating-snapshots-was-leaving-part-of-the-data-off-end.patch
smb3-fill-in-statfs-fsid-and-correct-namelen.patch

17 files changed:
queue-4.18/btrfs-don-t-leak-ret-from-do_chunk_alloc.patch [new file with mode: 0644]
queue-4.18/btrfs-fix-btrfs_write_inode-vs-delayed-iput-deadlock.patch [new file with mode: 0644]
queue-4.18/btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch [new file with mode: 0644]
queue-4.18/btrfs-fix-send-failure-when-root-has-deleted-files-still-open.patch [new file with mode: 0644]
queue-4.18/btrfs-send-fix-incorrect-file-layout-after-hole-punching-beyond-eof.patch [new file with mode: 0644]
queue-4.18/btrfs-use-correct-compare-function-of-dirty_metadata_bytes.patch [new file with mode: 0644]
queue-4.18/cifs-add-missing-debug-entries-for-kconfig-options.patch [new file with mode: 0644]
queue-4.18/cifs-add-missing-support-for-acls-in-smb-3.11.patch [new file with mode: 0644]
queue-4.18/cifs-check-kmalloc-before-use.patch [new file with mode: 0644]
queue-4.18/cifs-fix-uninitialized-ptr-deref-in-smb2-signing.patch [new file with mode: 0644]
queue-4.18/cifs-use-a-refcount-to-protect-open-closing-the-cached-file-handle.patch [new file with mode: 0644]
queue-4.18/hwmon-k10temp-27c-offset-needed-for-threadripper2.patch [new file with mode: 0644]
queue-4.18/series
queue-4.18/smb3-do-not-send-smb3-set_info-if-nothing-changed.patch [new file with mode: 0644]
queue-4.18/smb3-don-t-request-leases-in-symlink-creation-and-query.patch [new file with mode: 0644]
queue-4.18/smb3-enumerating-snapshots-was-leaving-part-of-the-data-off-end.patch [new file with mode: 0644]
queue-4.18/smb3-fill-in-statfs-fsid-and-correct-namelen.patch [new file with mode: 0644]

diff --git a/queue-4.18/btrfs-don-t-leak-ret-from-do_chunk_alloc.patch b/queue-4.18/btrfs-don-t-leak-ret-from-do_chunk_alloc.patch
new file mode 100644 (file)
index 0000000..f7940ee
--- /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
+@@ -4358,7 +4358,7 @@ commit_trans:
+                                     data_sinfo->flags, bytes, 1);
+       spin_unlock(&data_sinfo->lock);
+-      return ret;
++      return 0;
+ }
+ int btrfs_check_data_free_space(struct inode *inode,
diff --git a/queue-4.18/btrfs-fix-btrfs_write_inode-vs-delayed-iput-deadlock.patch b/queue-4.18/btrfs-fix-btrfs_write_inode-vs-delayed-iput-deadlock.patch
new file mode 100644 (file)
index 0000000..00ce2d7
--- /dev/null
@@ -0,0 +1,112 @@
+From 3c4276936f6fbe52884b4ea4e6cc120b890a0f9f Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Fri, 20 Jul 2018 11:46:10 -0700
+Subject: Btrfs: fix btrfs_write_inode vs delayed iput deadlock
+
+From: Josef Bacik <jbacik@fb.com>
+
+commit 3c4276936f6fbe52884b4ea4e6cc120b890a0f9f upstream.
+
+We recently ran into the following deadlock involving
+btrfs_write_inode():
+
+[  +0.005066]  __schedule+0x38e/0x8c0
+[  +0.007144]  schedule+0x36/0x80
+[  +0.006447]  bit_wait+0x11/0x60
+[  +0.006446]  __wait_on_bit+0xbe/0x110
+[  +0.007487]  ? bit_wait_io+0x60/0x60
+[  +0.007319]  __inode_wait_for_writeback+0x96/0xc0
+[  +0.009568]  ? autoremove_wake_function+0x40/0x40
+[  +0.009565]  inode_wait_for_writeback+0x21/0x30
+[  +0.009224]  evict+0xb0/0x190
+[  +0.006099]  iput+0x1a8/0x210
+[  +0.006103]  btrfs_run_delayed_iputs+0x73/0xc0
+[  +0.009047]  btrfs_commit_transaction+0x799/0x8c0
+[  +0.009567]  btrfs_write_inode+0x81/0xb0
+[  +0.008008]  __writeback_single_inode+0x267/0x320
+[  +0.009569]  writeback_sb_inodes+0x25b/0x4e0
+[  +0.008702]  wb_writeback+0x102/0x2d0
+[  +0.007487]  wb_workfn+0xa4/0x310
+[  +0.006794]  ? wb_workfn+0xa4/0x310
+[  +0.007143]  process_one_work+0x150/0x410
+[  +0.008179]  worker_thread+0x6d/0x520
+[  +0.007490]  kthread+0x12c/0x160
+[  +0.006620]  ? put_pwq_unlocked+0x80/0x80
+[  +0.008185]  ? kthread_park+0xa0/0xa0
+[  +0.007484]  ? do_syscall_64+0x53/0x150
+[  +0.007837]  ret_from_fork+0x29/0x40
+
+Writeback calls:
+
+btrfs_write_inode
+  btrfs_commit_transaction
+    btrfs_run_delayed_iputs
+
+If iput() is called on that same inode, evict() will wait for writeback
+forever.
+
+btrfs_write_inode() was originally added way back in 4730a4bc5bf3
+("btrfs_dirty_inode") to support O_SYNC writes. However, ->write_inode()
+hasn't been used for O_SYNC since 148f948ba877 ("vfs: Introduce new
+helpers for syncing after writing to O_SYNC file or IS_SYNC inode"), so
+btrfs_write_inode() is actually unnecessary (and leads to a bunch of
+unnecessary commits). Get rid of it, which also gets rid of the
+deadlock.
+
+CC: stable@vger.kernel.org # 3.2+
+Signed-off-by: Josef Bacik <jbacik@fb.com>
+[Omar: new commit message]
+Signed-off-by: Omar Sandoval <osandov@fb.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/inode.c |   26 --------------------------
+ fs/btrfs/super.c |    1 -
+ 2 files changed, 27 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -6027,32 +6027,6 @@ err:
+       return ret;
+ }
+-int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+-{
+-      struct btrfs_root *root = BTRFS_I(inode)->root;
+-      struct btrfs_trans_handle *trans;
+-      int ret = 0;
+-      bool nolock = false;
+-
+-      if (test_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags))
+-              return 0;
+-
+-      if (btrfs_fs_closing(root->fs_info) &&
+-                      btrfs_is_free_space_inode(BTRFS_I(inode)))
+-              nolock = true;
+-
+-      if (wbc->sync_mode == WB_SYNC_ALL) {
+-              if (nolock)
+-                      trans = btrfs_join_transaction_nolock(root);
+-              else
+-                      trans = btrfs_join_transaction(root);
+-              if (IS_ERR(trans))
+-                      return PTR_ERR(trans);
+-              ret = btrfs_commit_transaction(trans);
+-      }
+-      return ret;
+-}
+-
+ /*
+  * This is somewhat expensive, updating the tree every time the
+  * inode changes.  But, it is most likely to find the inode in cache.
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -2331,7 +2331,6 @@ static const struct super_operations btr
+       .sync_fs        = btrfs_sync_fs,
+       .show_options   = btrfs_show_options,
+       .show_devname   = btrfs_show_devname,
+-      .write_inode    = btrfs_write_inode,
+       .alloc_inode    = btrfs_alloc_inode,
+       .destroy_inode  = btrfs_destroy_inode,
+       .statfs         = btrfs_statfs,
diff --git a/queue-4.18/btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch b/queue-4.18/btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch
new file mode 100644 (file)
index 0000000..f72e351
--- /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
+@@ -1291,6 +1291,46 @@ again:
+       return ret;
+ }
++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.
+@@ -1400,6 +1440,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, BTRFS_I(dir),
+                                       BTRFS_I(inode),
diff --git a/queue-4.18/btrfs-fix-send-failure-when-root-has-deleted-files-still-open.patch b/queue-4.18/btrfs-fix-send-failure-when-root-has-deleted-files-still-open.patch
new file mode 100644 (file)
index 0000000..11a09f3
--- /dev/null
@@ -0,0 +1,275 @@
+From 46b2f4590aab71d31088a265c86026b1e96c9de4 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Tue, 24 Jul 2018 11:54:04 +0100
+Subject: Btrfs: fix send failure when root has deleted files still open
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 46b2f4590aab71d31088a265c86026b1e96c9de4 upstream.
+
+The more common use case of send involves creating a RO snapshot and then
+use it for a send operation. In this case it's not possible to have inodes
+in the snapshot that have a link count of zero (inode with an orphan item)
+since during snapshot creation we do the orphan cleanup. However, other
+less common use cases for send can end up seeing inodes with a link count
+of zero and in this case the send operation fails with a ENOENT error
+because any attempt to generate a path for the inode, with the purpose
+of creating it or updating it at the receiver, fails since there are no
+inode reference items. One use case it to use a regular subvolume for
+a send operation after turning it to RO mode or turning a RW snapshot
+into RO mode and then using it for a send operation. In both cases, if a
+file gets all its hard links deleted while there is an open file
+descriptor before turning the subvolume/snapshot into RO mode, the send
+operation will encounter an inode with a link count of zero and then
+fail with errno ENOENT.
+
+Example using a full send with a subvolume:
+
+  $ mkfs.btrfs -f /dev/sdb
+  $ mount /dev/sdb /mnt
+
+  $ btrfs subvolume create /mnt/sv1
+  $ touch /mnt/sv1/foo
+  $ touch /mnt/sv1/bar
+
+  # keep an open file descriptor on file bar
+  $ exec 73</mnt/sv1/bar
+  $ unlink /mnt/sv1/bar
+
+  # Turn the subvolume to RO mode and use it for a full send, while
+  # holding the open file descriptor.
+  $ btrfs property set /mnt/sv1 ro true
+
+  $ btrfs send -f /tmp/full.send /mnt/sv1
+  At subvol /mnt/sv1
+  ERROR: send ioctl failed with -2: No such file or directory
+
+Example using an incremental send with snapshots:
+
+  $ mkfs.btrfs -f /dev/sdb
+  $ mount /dev/sdb /mnt
+
+  $ btrfs subvolume create /mnt/sv1
+  $ touch /mnt/sv1/foo
+  $ touch /mnt/sv1/bar
+
+  $ btrfs subvolume snapshot -r /mnt/sv1 /mnt/snap1
+
+  $ echo "hello world" >> /mnt/sv1/bar
+
+  $ btrfs subvolume snapshot -r /mnt/sv1 /mnt/snap2
+
+  # Turn the second snapshot to RW mode and delete file foo while
+  # holding an open file descriptor on it.
+  $ btrfs property set /mnt/snap2 ro false
+  $ exec 73</mnt/snap2/foo
+  $ unlink /mnt/snap2/foo
+
+  # Set the second snapshot back to RO mode and do an incremental send.
+  $ btrfs property set /mnt/snap2 ro true
+
+  $ btrfs send -f /tmp/inc.send -p /mnt/snap1 /mnt/snap2
+  At subvol /mnt/snap2
+  ERROR: send ioctl failed with -2: No such file or directory
+
+So fix this by ignoring inodes with a link count of zero if we are either
+doing a full send or if they do not exist in the parent snapshot (they
+are new in the send snapshot), and unlink all paths found in the parent
+snapshot when doing an incremental send (and ignoring all other inode
+items, such as xattrs and extents).
+
+A test case for fstests follows soon.
+
+CC: stable@vger.kernel.org # 4.4+
+Reported-by: Martin Wilck <martin.wilck@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/send.c |  137 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 129 insertions(+), 8 deletions(-)
+
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -100,6 +100,7 @@ struct send_ctx {
+       u64 cur_inode_rdev;
+       u64 cur_inode_last_extent;
+       u64 cur_inode_next_write_offset;
++      bool ignore_cur_inode;
+       u64 send_progress;
+@@ -5799,6 +5800,9 @@ static int finish_inode_if_needed(struct
+       int pending_move = 0;
+       int refs_processed = 0;
++      if (sctx->ignore_cur_inode)
++              return 0;
++
+       ret = process_recorded_refs_if_needed(sctx, at_end, &pending_move,
+                                             &refs_processed);
+       if (ret < 0)
+@@ -5917,6 +5921,93 @@ out:
+       return ret;
+ }
++struct parent_paths_ctx {
++      struct list_head *refs;
++      struct send_ctx *sctx;
++};
++
++static int record_parent_ref(int num, u64 dir, int index, struct fs_path *name,
++                           void *ctx)
++{
++      struct parent_paths_ctx *ppctx = ctx;
++
++      return record_ref(ppctx->sctx->parent_root, dir, name, ppctx->sctx,
++                        ppctx->refs);
++}
++
++/*
++ * Issue unlink operations for all paths of the current inode found in the
++ * parent snapshot.
++ */
++static int btrfs_unlink_all_paths(struct send_ctx *sctx)
++{
++      LIST_HEAD(deleted_refs);
++      struct btrfs_path *path;
++      struct btrfs_key key;
++      struct parent_paths_ctx ctx;
++      int ret;
++
++      path = alloc_path_for_send();
++      if (!path)
++              return -ENOMEM;
++
++      key.objectid = sctx->cur_ino;
++      key.type = BTRFS_INODE_REF_KEY;
++      key.offset = 0;
++      ret = btrfs_search_slot(NULL, sctx->parent_root, &key, path, 0, 0);
++      if (ret < 0)
++              goto out;
++
++      ctx.refs = &deleted_refs;
++      ctx.sctx = sctx;
++
++      while (true) {
++              struct extent_buffer *eb = path->nodes[0];
++              int slot = path->slots[0];
++
++              if (slot >= btrfs_header_nritems(eb)) {
++                      ret = btrfs_next_leaf(sctx->parent_root, path);
++                      if (ret < 0)
++                              goto out;
++                      else if (ret > 0)
++                              break;
++                      continue;
++              }
++
++              btrfs_item_key_to_cpu(eb, &key, slot);
++              if (key.objectid != sctx->cur_ino)
++                      break;
++              if (key.type != BTRFS_INODE_REF_KEY &&
++                  key.type != BTRFS_INODE_EXTREF_KEY)
++                      break;
++
++              ret = iterate_inode_ref(sctx->parent_root, path, &key, 1,
++                                      record_parent_ref, &ctx);
++              if (ret < 0)
++                      goto out;
++
++              path->slots[0]++;
++      }
++
++      while (!list_empty(&deleted_refs)) {
++              struct recorded_ref *ref;
++
++              ref = list_first_entry(&deleted_refs, struct recorded_ref, list);
++              ret = send_unlink(sctx, ref->full_path);
++              if (ret < 0)
++                      goto out;
++              fs_path_free(ref->full_path);
++              list_del(&ref->list);
++              kfree(ref);
++      }
++      ret = 0;
++out:
++      btrfs_free_path(path);
++      if (ret)
++              __free_recorded_refs(&deleted_refs);
++      return ret;
++}
++
+ static int changed_inode(struct send_ctx *sctx,
+                        enum btrfs_compare_tree_result result)
+ {
+@@ -5931,6 +6022,7 @@ static int changed_inode(struct send_ctx
+       sctx->cur_inode_new_gen = 0;
+       sctx->cur_inode_last_extent = (u64)-1;
+       sctx->cur_inode_next_write_offset = 0;
++      sctx->ignore_cur_inode = false;
+       /*
+        * Set send_progress to current inode. This will tell all get_cur_xxx
+@@ -5971,6 +6063,33 @@ static int changed_inode(struct send_ctx
+                       sctx->cur_inode_new_gen = 1;
+       }
++      /*
++       * Normally we do not find inodes with a link count of zero (orphans)
++       * because the most common case is to create a snapshot and use it
++       * for a send operation. However other less common use cases involve
++       * using a subvolume and send it after turning it to RO mode just
++       * after deleting all hard links of a file while holding an open
++       * file descriptor against it or turning a RO snapshot into RW mode,
++       * keep an open file descriptor against a file, delete it and then
++       * turn the snapshot back to RO mode before using it for a send
++       * operation. So if we find such cases, ignore the inode and all its
++       * items completely if it's a new inode, or if it's a changed inode
++       * make sure all its previous paths (from the parent snapshot) are all
++       * unlinked and all other the inode items are ignored.
++       */
++      if (result == BTRFS_COMPARE_TREE_NEW ||
++          result == BTRFS_COMPARE_TREE_CHANGED) {
++              u32 nlinks;
++
++              nlinks = btrfs_inode_nlink(sctx->left_path->nodes[0], left_ii);
++              if (nlinks == 0) {
++                      sctx->ignore_cur_inode = true;
++                      if (result == BTRFS_COMPARE_TREE_CHANGED)
++                              ret = btrfs_unlink_all_paths(sctx);
++                      goto out;
++              }
++      }
++
+       if (result == BTRFS_COMPARE_TREE_NEW) {
+               sctx->cur_inode_gen = left_gen;
+               sctx->cur_inode_new = 1;
+@@ -6309,15 +6428,17 @@ static int changed_cb(struct btrfs_path
+           key->objectid == BTRFS_FREE_SPACE_OBJECTID)
+               goto out;
+-      if (key->type == BTRFS_INODE_ITEM_KEY)
++      if (key->type == BTRFS_INODE_ITEM_KEY) {
+               ret = changed_inode(sctx, result);
+-      else if (key->type == BTRFS_INODE_REF_KEY ||
+-               key->type == BTRFS_INODE_EXTREF_KEY)
+-              ret = changed_ref(sctx, result);
+-      else if (key->type == BTRFS_XATTR_ITEM_KEY)
+-              ret = changed_xattr(sctx, result);
+-      else if (key->type == BTRFS_EXTENT_DATA_KEY)
+-              ret = changed_extent(sctx, result);
++      } else if (!sctx->ignore_cur_inode) {
++              if (key->type == BTRFS_INODE_REF_KEY ||
++                  key->type == BTRFS_INODE_EXTREF_KEY)
++                      ret = changed_ref(sctx, result);
++              else if (key->type == BTRFS_XATTR_ITEM_KEY)
++                      ret = changed_xattr(sctx, result);
++              else if (key->type == BTRFS_EXTENT_DATA_KEY)
++                      ret = changed_extent(sctx, result);
++      }
+ out:
+       return ret;
diff --git a/queue-4.18/btrfs-send-fix-incorrect-file-layout-after-hole-punching-beyond-eof.patch b/queue-4.18/btrfs-send-fix-incorrect-file-layout-after-hole-punching-beyond-eof.patch
new file mode 100644 (file)
index 0000000..46b4a6d
--- /dev/null
@@ -0,0 +1,95 @@
+From 22d3151c2c4cb517a309154d1e828a28106508c7 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Mon, 30 Jul 2018 12:39:58 +0100
+Subject: Btrfs: send, fix incorrect file layout after hole punching beyond eof
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 22d3151c2c4cb517a309154d1e828a28106508c7 upstream.
+
+When doing an incremental send, if we have a file in the parent snapshot
+that has prealloc extents beyond EOF and in the send snapshot it got a
+hole punch that partially covers the prealloc extents, the send stream,
+when replayed by a receiver, can result in a file that has a size bigger
+than it should and filled with zeroes past the correct EOF.
+
+For example:
+
+  $ mkfs.btrfs -f /dev/sdb
+  $ mount /dev/sdb /mnt
+
+  $ xfs_io -f -c "falloc -k 0 4M" /mnt/foobar
+  $ xfs_io -c "pwrite -S 0xea 0 1M" /mnt/foobar
+
+  $ btrfs subvolume snapshot -r /mnt /mnt/snap1
+  $ btrfs send -f /tmp/1.send /mnt/snap1
+
+  $ xfs_io -c "fpunch 1M 2M" /mnt/foobar
+
+  $ btrfs subvolume snapshot -r /mnt /mnt/snap2
+  $ btrfs send -f /tmp/2.send -p /mnt/snap1 /mnt/snap2
+
+  $ stat --format %s /mnt/snap2/foobar
+  1048576
+  $ md5sum /mnt/snap2/foobar
+  d31659e82e87798acd4669a1e0a19d4f  /mnt/snap2/foobar
+
+  $ umount /mnt
+  $ mkfs.btrfs -f /dev/sdc
+  $ mount /dev/sdc /mnt
+
+  $ btrfs receive -f /mnt/1.snap /mnt
+  $ btrfs receive -f /mnt/2.snap /mnt
+
+  $ stat --format %s /mnt/snap2/foobar
+  3145728
+  # --> should be 1Mb and not 3Mb (which was the end offset of hole
+  #     punch operation)
+  $ md5sum /mnt/snap2/foobar
+  117baf295297c2a995f92da725b0b651  /mnt/snap2/foobar
+  # --> should be d31659e82e87798acd4669a1e0a19d4f as in the original fs
+
+This issue actually happens only since commit ffa7c4296e93 ("Btrfs: send,
+do not issue unnecessary truncate operations"), but before that commit we
+were issuing a write operation full of zeroes (to "punch" a hole) which
+was extending the file size beyond the correct value and then immediately
+issue a truncate operation to the correct size and undoing the previous
+write operation. Since the send protocol does not support fallocate, for
+extent preallocation and hole punching, fix this by not even attempting
+to send a "hole" (regular write full of zeroes) if it starts at an offset
+greater then or equals to the file's size. This approach, besides being
+much more simple then making send issue the truncate operation, adds the
+benefit of avoiding the useless pair of write of zeroes and truncate
+operations, saving time and IO at the receiver and reducing the size of
+the send stream.
+
+A test case for fstests follows soon.
+
+Fixes: ffa7c4296e93 ("Btrfs: send, do not issue unnecessary truncate operations")
+CC: stable@vger.kernel.org # 4.17+
+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/send.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -5007,6 +5007,15 @@ static int send_hole(struct send_ctx *sc
+       u64 len;
+       int ret = 0;
++      /*
++       * A hole that starts at EOF or beyond it. Since we do not yet support
++       * fallocate (for extent preallocation and hole punching), sending a
++       * write of zeroes starting at EOF or beyond would later require issuing
++       * a truncate operation which would undo the write and achieve nothing.
++       */
++      if (offset >= sctx->cur_inode_size)
++              return 0;
++
+       if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
+               return send_update_extent(sctx, offset, end - offset);
diff --git a/queue-4.18/btrfs-use-correct-compare-function-of-dirty_metadata_bytes.patch b/queue-4.18/btrfs-use-correct-compare-function-of-dirty_metadata_bytes.patch
new file mode 100644 (file)
index 0000000..44cb566
--- /dev/null
@@ -0,0 +1,50 @@
+From d814a49198eafa6163698bdd93961302f3a877a4 Mon Sep 17 00:00:00 2001
+From: Ethan Lien <ethanlien@synology.com>
+Date: Mon, 2 Jul 2018 15:44:58 +0800
+Subject: btrfs: use correct compare function of dirty_metadata_bytes
+
+From: Ethan Lien <ethanlien@synology.com>
+
+commit d814a49198eafa6163698bdd93961302f3a877a4 upstream.
+
+We use customized, nodesize batch value to update dirty_metadata_bytes.
+We should also use batch version of compare function or we will easily
+goto fast path and get false result from percpu_counter_compare().
+
+Fixes: e2d845211eda ("Btrfs: use percpu counter for dirty metadata count")
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Ethan Lien <ethanlien@synology.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/disk-io.c |   10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -961,8 +961,9 @@ static int btree_writepages(struct addre
+               fs_info = BTRFS_I(mapping->host)->root->fs_info;
+               /* this is a bit racy, but that's ok */
+-              ret = percpu_counter_compare(&fs_info->dirty_metadata_bytes,
+-                                           BTRFS_DIRTY_METADATA_THRESH);
++              ret = __percpu_counter_compare(&fs_info->dirty_metadata_bytes,
++                                           BTRFS_DIRTY_METADATA_THRESH,
++                                           fs_info->dirty_metadata_batch);
+               if (ret < 0)
+                       return 0;
+       }
+@@ -4150,8 +4151,9 @@ static void __btrfs_btree_balance_dirty(
+       if (flush_delayed)
+               btrfs_balance_delayed_items(fs_info);
+-      ret = percpu_counter_compare(&fs_info->dirty_metadata_bytes,
+-                                   BTRFS_DIRTY_METADATA_THRESH);
++      ret = __percpu_counter_compare(&fs_info->dirty_metadata_bytes,
++                                   BTRFS_DIRTY_METADATA_THRESH,
++                                   fs_info->dirty_metadata_batch);
+       if (ret > 0) {
+               balance_dirty_pages_ratelimited(fs_info->btree_inode->i_mapping);
+       }
diff --git a/queue-4.18/cifs-add-missing-debug-entries-for-kconfig-options.patch b/queue-4.18/cifs-add-missing-debug-entries-for-kconfig-options.patch
new file mode 100644 (file)
index 0000000..7f0dcf6
--- /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
+@@ -160,25 +160,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.18/cifs-add-missing-support-for-acls-in-smb-3.11.patch b/queue-4.18/cifs-add-missing-support-for-acls-in-smb-3.11.patch
new file mode 100644 (file)
index 0000000..2dd6d99
--- /dev/null
@@ -0,0 +1,36 @@
+From c1777df1a5d541cda918ff0450c8adcc8b69c2fd Mon Sep 17 00:00:00 2001
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+Date: Fri, 10 Aug 2018 11:03:55 +1000
+Subject: cifs: add missing support for ACLs in SMB 3.11
+
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+
+commit c1777df1a5d541cda918ff0450c8adcc8b69c2fd upstream.
+
+We were missing the methods for get_acl and friends for the 3.11
+dialect.
+
+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+CC: Stable <stable@vger.kernel.org>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2ops.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -3366,6 +3366,11 @@ struct smb_version_operations smb311_ope
+       .query_all_EAs = smb2_query_eas,
+       .set_EA = smb2_set_ea,
+ #endif /* CIFS_XATTR */
++#ifdef CONFIG_CIFS_ACL
++      .get_acl = get_smb2_acl,
++      .get_acl_by_fid = get_smb2_acl_by_fid,
++      .set_acl = set_smb2_acl,
++#endif /* CIFS_ACL */
+       .next_header = smb2_next_header,
+ };
+ #endif /* CIFS_SMB311 */
diff --git a/queue-4.18/cifs-check-kmalloc-before-use.patch b/queue-4.18/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);
diff --git a/queue-4.18/cifs-fix-uninitialized-ptr-deref-in-smb2-signing.patch b/queue-4.18/cifs-fix-uninitialized-ptr-deref-in-smb2-signing.patch
new file mode 100644 (file)
index 0000000..25137f5
--- /dev/null
@@ -0,0 +1,55 @@
+From a5c62f4833c2c8e6e0f35367b99b717b78f5c029 Mon Sep 17 00:00:00 2001
+From: Aurelien Aptel <aaptel@suse.com>
+Date: Thu, 2 Aug 2018 16:39:52 +0200
+Subject: CIFS: fix uninitialized ptr deref in smb2 signing
+
+From: Aurelien Aptel <aaptel@suse.com>
+
+commit a5c62f4833c2c8e6e0f35367b99b717b78f5c029 upstream.
+
+server->secmech.sdeschmacsha256 is not properly initialized before
+smb2_shash_allocate(), set shash after that call.
+
+also fix typo in error message
+
+Fixes: 8de8c4608fe9 ("cifs: Fix validation of signed data in smb2")
+
+Signed-off-by: Aurelien Aptel <aaptel@suse.com>
+Reviewed-by: Paulo Alcantara <palcantara@suse.com>
+Reported-by: Xiaoli Feng <xifeng@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+CC: Stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2transport.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/cifs/smb2transport.c
++++ b/fs/cifs/smb2transport.c
+@@ -173,7 +173,7 @@ smb2_calc_signature(struct smb_rqst *rqs
+       struct kvec *iov = rqst->rq_iov;
+       struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base;
+       struct cifs_ses *ses;
+-      struct shash_desc *shash = &server->secmech.sdeschmacsha256->shash;
++      struct shash_desc *shash;
+       struct smb_rqst drqst;
+       ses = smb2_find_smb_ses(server, shdr->SessionId);
+@@ -187,7 +187,7 @@ smb2_calc_signature(struct smb_rqst *rqs
+       rc = smb2_crypto_shash_allocate(server);
+       if (rc) {
+-              cifs_dbg(VFS, "%s: shah256 alloc failed\n", __func__);
++              cifs_dbg(VFS, "%s: sha256 alloc failed\n", __func__);
+               return rc;
+       }
+@@ -198,6 +198,7 @@ smb2_calc_signature(struct smb_rqst *rqs
+               return rc;
+       }
++      shash = &server->secmech.sdeschmacsha256->shash;
+       rc = crypto_shash_init(shash);
+       if (rc) {
+               cifs_dbg(VFS, "%s: Could not init sha256", __func__);
diff --git a/queue-4.18/cifs-use-a-refcount-to-protect-open-closing-the-cached-file-handle.patch b/queue-4.18/cifs-use-a-refcount-to-protect-open-closing-the-cached-file-handle.patch
new file mode 100644 (file)
index 0000000..d269012
--- /dev/null
@@ -0,0 +1,126 @@
+From 9da6ec7775d2cd76df53fbf4f1f35f6d490204f5 Mon Sep 17 00:00:00 2001
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+Date: Tue, 31 Jul 2018 08:48:22 +1000
+Subject: cifs: use a refcount to protect open/closing the cached file handle
+
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+
+commit 9da6ec7775d2cd76df53fbf4f1f35f6d490204f5 upstream.
+
+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsglob.h  |    1 +
+ fs/cifs/smb2inode.c |    4 +++-
+ fs/cifs/smb2ops.c   |   31 ++++++++++++++++++++++++++-----
+ fs/cifs/smb2proto.h |    1 +
+ 4 files changed, 31 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -913,6 +913,7 @@ cap_unix(struct cifs_ses *ses)
+ struct cached_fid {
+       bool is_valid:1;        /* Do we have a useable root fid */
++      struct kref refcount;
+       struct cifs_fid *fid;
+       struct mutex fid_mutex;
+       struct cifs_tcon *tcon;
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -120,7 +120,9 @@ smb2_open_op_close(const unsigned int xi
+               break;
+       }
+-      if (use_cached_root_handle == false)
++      if (use_cached_root_handle)
++              close_shroot(&tcon->crfid);
++      else
+               rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
+       if (tmprc)
+               rc = tmprc;
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -466,21 +466,36 @@ out:
+       return rc;
+ }
+-void
+-smb2_cached_lease_break(struct work_struct *work)
++static void
++smb2_close_cached_fid(struct kref *ref)
+ {
+-      struct cached_fid *cfid = container_of(work,
+-                              struct cached_fid, lease_break);
+-      mutex_lock(&cfid->fid_mutex);
++      struct cached_fid *cfid = container_of(ref, struct cached_fid,
++                                             refcount);
++
+       if (cfid->is_valid) {
+               cifs_dbg(FYI, "clear cached root file handle\n");
+               SMB2_close(0, cfid->tcon, cfid->fid->persistent_fid,
+                          cfid->fid->volatile_fid);
+               cfid->is_valid = false;
+       }
++}
++
++void close_shroot(struct cached_fid *cfid)
++{
++      mutex_lock(&cfid->fid_mutex);
++      kref_put(&cfid->refcount, smb2_close_cached_fid);
+       mutex_unlock(&cfid->fid_mutex);
+ }
++void
++smb2_cached_lease_break(struct work_struct *work)
++{
++      struct cached_fid *cfid = container_of(work,
++                              struct cached_fid, lease_break);
++
++      close_shroot(cfid);
++}
++
+ /*
+  * Open the directory at the root of a share
+  */
+@@ -495,6 +510,7 @@ int open_shroot(unsigned int xid, struct
+       if (tcon->crfid.is_valid) {
+               cifs_dbg(FYI, "found a cached root file handle\n");
+               memcpy(pfid, tcon->crfid.fid, sizeof(struct cifs_fid));
++              kref_get(&tcon->crfid.refcount);
+               mutex_unlock(&tcon->crfid.fid_mutex);
+               return 0;
+       }
+@@ -511,6 +527,8 @@ int open_shroot(unsigned int xid, struct
+               memcpy(tcon->crfid.fid, pfid, sizeof(struct cifs_fid));
+               tcon->crfid.tcon = tcon;
+               tcon->crfid.is_valid = true;
++              kref_init(&tcon->crfid.refcount);
++              kref_get(&tcon->crfid.refcount);
+       }
+       mutex_unlock(&tcon->crfid.fid_mutex);
+       return rc;
+@@ -552,6 +570,9 @@ smb3_qfs_tcon(const unsigned int xid, st
+                       FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
+       if (no_cached_open)
+               SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
++      else
++              close_shroot(&tcon->crfid);
++
+       return;
+ }
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -68,6 +68,7 @@ extern int smb3_handle_read_data(struct
+ extern int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
+                       struct cifs_fid *pfid);
++extern void close_shroot(struct cached_fid *cfid);
+ extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst,
+                                  struct smb2_file_all_info *src);
+ extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
diff --git a/queue-4.18/hwmon-k10temp-27c-offset-needed-for-threadripper2.patch b/queue-4.18/hwmon-k10temp-27c-offset-needed-for-threadripper2.patch
new file mode 100644 (file)
index 0000000..b3ac3b1
--- /dev/null
@@ -0,0 +1,32 @@
+From 484a84f25ca7817c3662001316ba7d1e06b74ae2 Mon Sep 17 00:00:00 2001
+From: Michael Larabel <michael@phoronix.com>
+Date: Tue, 7 Aug 2018 09:54:54 -0400
+Subject: hwmon: (k10temp) 27C Offset needed for Threadripper2
+
+From: Michael Larabel <michael@phoronix.com>
+
+commit 484a84f25ca7817c3662001316ba7d1e06b74ae2 upstream.
+
+For at least the Threadripper 2950X and Threadripper 2990WX,
+it's confirmed a 27 degree offset is needed.
+
+Signed-off-by: Michael Larabel <michael@phoronix.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/k10temp.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/hwmon/k10temp.c
++++ b/drivers/hwmon/k10temp.c
+@@ -105,6 +105,8 @@ static const struct tctl_offset tctl_off
+       { 0x17, "AMD Ryzen Threadripper 1950", 10000 },
+       { 0x17, "AMD Ryzen Threadripper 1920", 10000 },
+       { 0x17, "AMD Ryzen Threadripper 1910", 10000 },
++      { 0x17, "AMD Ryzen Threadripper 2950X", 27000 },
++      { 0x17, "AMD Ryzen Threadripper 2990WX", 27000 },
+ };
+ static void read_htcreg_pci(struct pci_dev *pdev, u32 *regval)
index 333b0884191bf01a7d1b19bf2a48fb6623cb782a..50558b2ee6086ab5a820dfceb367cefca20cf69a 100644 (file)
@@ -3,3 +3,19 @@ scripts-kernel-doc-escape-all-literal-braces-in-regexes.patch
 scsi-libsas-dynamically-allocate-and-free-ata-host.patch
 xprtrdma-fix-disconnect-regression.patch
 mei-don-t-update-offset-in-write.patch
+cifs-add-missing-support-for-acls-in-smb-3.11.patch
+cifs-fix-uninitialized-ptr-deref-in-smb2-signing.patch
+cifs-add-missing-debug-entries-for-kconfig-options.patch
+cifs-use-a-refcount-to-protect-open-closing-the-cached-file-handle.patch
+cifs-check-kmalloc-before-use.patch
+smb3-enumerating-snapshots-was-leaving-part-of-the-data-off-end.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-use-correct-compare-function-of-dirty_metadata_bytes.patch
+btrfs-don-t-leak-ret-from-do_chunk_alloc.patch
+btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch
+btrfs-fix-btrfs_write_inode-vs-delayed-iput-deadlock.patch
+btrfs-fix-send-failure-when-root-has-deleted-files-still-open.patch
+btrfs-send-fix-incorrect-file-layout-after-hole-punching-beyond-eof.patch
+hwmon-k10temp-27c-offset-needed-for-threadripper2.patch
diff --git a/queue-4.18/smb3-do-not-send-smb3-set_info-if-nothing-changed.patch b/queue-4.18/smb3-do-not-send-smb3-set_info-if-nothing-changed.patch
new file mode 100644 (file)
index 0000000..9ca1c30
--- /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
+@@ -1122,6 +1122,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
+@@ -283,7 +283,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.18/smb3-don-t-request-leases-in-symlink-creation-and-query.patch b/queue-4.18/smb3-don-t-request-leases-in-symlink-creation-and-query.patch
new file mode 100644 (file)
index 0000000..938069d
--- /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
+@@ -396,7 +396,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;
+@@ -459,7 +459,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.18/smb3-enumerating-snapshots-was-leaving-part-of-the-data-off-end.patch b/queue-4.18/smb3-enumerating-snapshots-was-leaving-part-of-the-data-off-end.patch
new file mode 100644 (file)
index 0000000..7b2fd4b
--- /dev/null
@@ -0,0 +1,90 @@
+From e02789a53d71334b067ad72eee5d4e88a0158083 Mon Sep 17 00:00:00 2001
+From: Steve French <stfrench@microsoft.com>
+Date: Thu, 9 Aug 2018 14:33:12 -0500
+Subject: smb3: enumerating snapshots was leaving part of the data off end
+
+From: Steve French <stfrench@microsoft.com>
+
+commit e02789a53d71334b067ad72eee5d4e88a0158083 upstream.
+
+When enumerating snapshots, the last few bytes of the final
+snapshot could be left off since we were miscalculating the
+length returned (leaving off the sizeof struct SRV_SNAPSHOT_ARRAY)
+See MS-SMB2 section 2.2.32.2. In addition fixup the length used
+to allow smaller buffer to be passed in, in order to allow
+returning the size of the whole snapshot array more easily.
+
+Sample userspace output with a kernel patched with this
+(mounted to a Windows volume with two snapshots).
+Before this patch, the second snapshot would be missing a
+few bytes at the end.
+
+~/cifs-2.6# ~/enum-snapshots /mnt/file
+press enter to issue the ioctl to retrieve snapshot information ...
+
+size of snapshot array = 102
+Num snapshots: 2 Num returned: 2 Array Size: 102
+
+Snapshot 0:@GMT-2018.06.30-19.34.17
+Snapshot 1:@GMT-2018.06.30-19.33.37
+
+CC: Stable <stable@vger.kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2ops.c |   34 +++++++++++++++++++++++++++-------
+ 1 file changed, 27 insertions(+), 7 deletions(-)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -1374,6 +1374,13 @@ smb3_set_integrity(const unsigned int xi
+ }
++/* GMT Token is @GMT-YYYY.MM.DD-HH.MM.SS Unicode which is 48 bytes + null */
++#define GMT_TOKEN_SIZE 50
++
++/*
++ * Input buffer contains (empty) struct smb_snapshot array with size filled in
++ * For output see struct SRV_SNAPSHOT_ARRAY in MS-SMB2 section 2.2.32.2
++ */
+ static int
+ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon,
+                  struct cifsFileInfo *cfile, void __user *ioc_buf)
+@@ -1403,14 +1410,27 @@ smb3_enum_snapshots(const unsigned int x
+                       kfree(retbuf);
+                       return rc;
+               }
+-              if (snapshot_in.snapshot_array_size < sizeof(struct smb_snapshot_array)) {
+-                      rc = -ERANGE;
+-                      kfree(retbuf);
+-                      return rc;
+-              }
+-              if (ret_data_len > snapshot_in.snapshot_array_size)
+-                      ret_data_len = snapshot_in.snapshot_array_size;
++              /*
++               * Check for min size, ie not large enough to fit even one GMT
++               * token (snapshot).  On the first ioctl some users may pass in
++               * smaller size (or zero) to simply get the size of the array
++               * so the user space caller can allocate sufficient memory
++               * and retry the ioctl again with larger array size sufficient
++               * to hold all of the snapshot GMT tokens on the second try.
++               */
++              if (snapshot_in.snapshot_array_size < GMT_TOKEN_SIZE)
++                      ret_data_len = sizeof(struct smb_snapshot_array);
++
++              /*
++               * We return struct SRV_SNAPSHOT_ARRAY, followed by
++               * the snapshot array (of 50 byte GMT tokens) each
++               * representing an available previous version of the data
++               */
++              if (ret_data_len > (snapshot_in.snapshot_array_size +
++                                      sizeof(struct smb_snapshot_array)))
++                      ret_data_len = snapshot_in.snapshot_array_size +
++                                      sizeof(struct smb_snapshot_array);
+               if (copy_to_user(ioc_buf, retbuf, ret_data_len))
+                       rc = -EFAULT;
diff --git a/queue-4.18/smb3-fill-in-statfs-fsid-and-correct-namelen.patch b/queue-4.18/smb3-fill-in-statfs-fsid-and-correct-namelen.patch
new file mode 100644 (file)
index 0000000..e0aaae4
--- /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
+@@ -209,14 +209,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
+@@ -567,6 +567,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 */
+       if (no_cached_open)
+               SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -4046,6 +4046,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;
+@@ -4090,6 +4093,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
+@@ -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