From d0a69608bcb557171e71c2ca22835b7c36c5a84c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 29 Aug 2018 09:54:32 -0700 Subject: [PATCH] 4.18-stable patches 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 --- ...s-don-t-leak-ret-from-do_chunk_alloc.patch | 35 +++ ...write_inode-vs-delayed-iput-deadlock.patch | 112 +++++++ ...er-fsync-due-to-hard-link-recreation.patch | 141 +++++++++ ...en-root-has-deleted-files-still-open.patch | 275 ++++++++++++++++++ ...ayout-after-hole-punching-beyond-eof.patch | 95 ++++++ ...are-function-of-dirty_metadata_bytes.patch | 50 ++++ ...ng-debug-entries-for-kconfig-options.patch | 84 ++++++ ...missing-support-for-acls-in-smb-3.11.patch | 36 +++ .../cifs-check-kmalloc-before-use.patch | 38 +++ ...nitialized-ptr-deref-in-smb2-signing.patch | 55 ++++ ...-open-closing-the-cached-file-handle.patch | 126 ++++++++ ...-27c-offset-needed-for-threadripper2.patch | 32 ++ queue-4.18/series | 16 + ...end-smb3-set_info-if-nothing-changed.patch | 53 ++++ ...leases-in-symlink-creation-and-query.patch | 42 +++ ...was-leaving-part-of-the-data-off-end.patch | 90 ++++++ ...l-in-statfs-fsid-and-correct-namelen.patch | 112 +++++++ 17 files changed, 1392 insertions(+) create mode 100644 queue-4.18/btrfs-don-t-leak-ret-from-do_chunk_alloc.patch create mode 100644 queue-4.18/btrfs-fix-btrfs_write_inode-vs-delayed-iput-deadlock.patch create mode 100644 queue-4.18/btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch create mode 100644 queue-4.18/btrfs-fix-send-failure-when-root-has-deleted-files-still-open.patch create mode 100644 queue-4.18/btrfs-send-fix-incorrect-file-layout-after-hole-punching-beyond-eof.patch create mode 100644 queue-4.18/btrfs-use-correct-compare-function-of-dirty_metadata_bytes.patch create mode 100644 queue-4.18/cifs-add-missing-debug-entries-for-kconfig-options.patch create mode 100644 queue-4.18/cifs-add-missing-support-for-acls-in-smb-3.11.patch create mode 100644 queue-4.18/cifs-check-kmalloc-before-use.patch create mode 100644 queue-4.18/cifs-fix-uninitialized-ptr-deref-in-smb2-signing.patch create mode 100644 queue-4.18/cifs-use-a-refcount-to-protect-open-closing-the-cached-file-handle.patch create mode 100644 queue-4.18/hwmon-k10temp-27c-offset-needed-for-threadripper2.patch create mode 100644 queue-4.18/smb3-do-not-send-smb3-set_info-if-nothing-changed.patch create mode 100644 queue-4.18/smb3-don-t-request-leases-in-symlink-creation-and-query.patch create mode 100644 queue-4.18/smb3-enumerating-snapshots-was-leaving-part-of-the-data-off-end.patch create mode 100644 queue-4.18/smb3-fill-in-statfs-fsid-and-correct-namelen.patch 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 index 00000000000..f7940ee21c8 --- /dev/null +++ b/queue-4.18/btrfs-don-t-leak-ret-from-do_chunk_alloc.patch @@ -0,0 +1,35 @@ +From 4559b0a71749c442d34f7cfb9e72c9e58db83948 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Thu, 19 Jul 2018 10:49:51 -0400 +Subject: btrfs: don't leak ret from do_chunk_alloc + +From: Josef Bacik + +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 +Reviewed-by: Nikolay Borisov +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..00ce2d76eb2 --- /dev/null +++ b/queue-4.18/btrfs-fix-btrfs_write_inode-vs-delayed-iput-deadlock.patch @@ -0,0 +1,112 @@ +From 3c4276936f6fbe52884b4ea4e6cc120b890a0f9f Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Fri, 20 Jul 2018 11:46:10 -0700 +Subject: Btrfs: fix btrfs_write_inode vs delayed iput deadlock + +From: Josef Bacik + +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 +[Omar: new commit message] +Signed-off-by: Omar Sandoval +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f72e351144e --- /dev/null +++ b/queue-4.18/btrfs-fix-mount-failure-after-fsync-due-to-hard-link-recreation.patch @@ -0,0 +1,141 @@ +From 0d836392cadd5535f4184d46d901a82eb276ed62 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Fri, 20 Jul 2018 10:59:06 +0100 +Subject: Btrfs: fix mount failure after fsync due to hard link recreation + +From: Filipe Manana + +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 + + + + $ 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 +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..11a09f31a4d --- /dev/null +++ b/queue-4.18/btrfs-fix-send-failure-when-root-has-deleted-files-still-open.patch @@ -0,0 +1,275 @@ +From 46b2f4590aab71d31088a265c86026b1e96c9de4 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Tue, 24 Jul 2018 11:54:04 +0100 +Subject: Btrfs: fix send failure when root has deleted files still open + +From: Filipe Manana + +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 + + $ 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 +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..46b4a6d04ba --- /dev/null +++ b/queue-4.18/btrfs-send-fix-incorrect-file-layout-after-hole-punching-beyond-eof.patch @@ -0,0 +1,95 @@ +From 22d3151c2c4cb517a309154d1e828a28106508c7 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Mon, 30 Jul 2018 12:39:58 +0100 +Subject: Btrfs: send, fix incorrect file layout after hole punching beyond eof + +From: Filipe Manana + +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 +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..44cb566fcc7 --- /dev/null +++ b/queue-4.18/btrfs-use-correct-compare-function-of-dirty_metadata_bytes.patch @@ -0,0 +1,50 @@ +From d814a49198eafa6163698bdd93961302f3a877a4 Mon Sep 17 00:00:00 2001 +From: Ethan Lien +Date: Mon, 2 Jul 2018 15:44:58 +0800 +Subject: btrfs: use correct compare function of dirty_metadata_bytes + +From: Ethan Lien + +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 +Reviewed-by: Nikolay Borisov +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7f0dcf69663 --- /dev/null +++ b/queue-4.18/cifs-add-missing-debug-entries-for-kconfig-options.patch @@ -0,0 +1,84 @@ +From 950132afd59385caf6e2b84e5235d069fa10681d Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Thu, 28 Jun 2018 18:46:40 -0500 +Subject: cifs: add missing debug entries for kconfig options + +From: Steve French + +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 +Reviewed-by: Ronnie Sahlberg +Reviewed-by: Pavel Shilovsky +Reviewed-by: Paulo Alcantara +CC: Stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2dd6d9973b5 --- /dev/null +++ b/queue-4.18/cifs-add-missing-support-for-acls-in-smb-3.11.patch @@ -0,0 +1,36 @@ +From c1777df1a5d541cda918ff0450c8adcc8b69c2fd Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Fri, 10 Aug 2018 11:03:55 +1000 +Subject: cifs: add missing support for ACLs in SMB 3.11 + +From: Ronnie Sahlberg + +commit c1777df1a5d541cda918ff0450c8adcc8b69c2fd upstream. + +We were missing the methods for get_acl and friends for the 3.11 +dialect. + +Signed-off-by: Ronnie Sahlberg +Signed-off-by: Steve French +CC: Stable +Reviewed-by: Pavel Shilovsky +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0a3d8e1f248 --- /dev/null +++ b/queue-4.18/cifs-check-kmalloc-before-use.patch @@ -0,0 +1,38 @@ +From 126c97f4d0d1b5b956e8b0740c81a2b2a2ae548c Mon Sep 17 00:00:00 2001 +From: Nicholas Mc Guire +Date: Thu, 23 Aug 2018 12:24:02 +0200 +Subject: cifs: check kmalloc before use + +From: Nicholas Mc Guire + +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 +Fixes: b8da344b74c8 ("cifs: dynamic allocation of ntlmssp blob") +Signed-off-by: Steve French +Reviewed-by: Pavel Shilovsky +cc: Stable ` +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..25137f5cb9f --- /dev/null +++ b/queue-4.18/cifs-fix-uninitialized-ptr-deref-in-smb2-signing.patch @@ -0,0 +1,55 @@ +From a5c62f4833c2c8e6e0f35367b99b717b78f5c029 Mon Sep 17 00:00:00 2001 +From: Aurelien Aptel +Date: Thu, 2 Aug 2018 16:39:52 +0200 +Subject: CIFS: fix uninitialized ptr deref in smb2 signing + +From: Aurelien Aptel + +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 +Reviewed-by: Paulo Alcantara +Reported-by: Xiaoli Feng +Signed-off-by: Steve French +CC: Stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d2690123cfc --- /dev/null +++ b/queue-4.18/cifs-use-a-refcount-to-protect-open-closing-the-cached-file-handle.patch @@ -0,0 +1,126 @@ +From 9da6ec7775d2cd76df53fbf4f1f35f6d490204f5 Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +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 + +commit 9da6ec7775d2cd76df53fbf4f1f35f6d490204f5 upstream. + +Signed-off-by: Ronnie Sahlberg +Signed-off-by: Steve French +Reviewed-by: Pavel Shilovsky +Cc: +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b3ac3b12530 --- /dev/null +++ b/queue-4.18/hwmon-k10temp-27c-offset-needed-for-threadripper2.patch @@ -0,0 +1,32 @@ +From 484a84f25ca7817c3662001316ba7d1e06b74ae2 Mon Sep 17 00:00:00 2001 +From: Michael Larabel +Date: Tue, 7 Aug 2018 09:54:54 -0400 +Subject: hwmon: (k10temp) 27C Offset needed for Threadripper2 + +From: Michael Larabel + +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 +Cc: stable@vger.kernel.org +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-4.18/series b/queue-4.18/series index 333b0884191..50558b2ee60 100644 --- a/queue-4.18/series +++ b/queue-4.18/series @@ -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 index 00000000000..9ca1c308605 --- /dev/null +++ b/queue-4.18/smb3-do-not-send-smb3-set_info-if-nothing-changed.patch @@ -0,0 +1,53 @@ +From fd09b7d3b352105f08b8e02f7afecf7e816380ef Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Thu, 2 Aug 2018 20:28:18 -0500 +Subject: smb3: Do not send SMB3 SET_INFO if nothing changed + +From: Steve French + +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 +CC: Stable # 4.9.x+ +Reported-by: Stefan Metzmacher +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..938069d6890 --- /dev/null +++ b/queue-4.18/smb3-don-t-request-leases-in-symlink-creation-and-query.patch @@ -0,0 +1,42 @@ +From 22783155f4bf956c346a81624ec9258930a6fe06 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Fri, 27 Jul 2018 22:01:49 -0500 +Subject: smb3: don't request leases in symlink creation and query + +From: Steve French + +commit 22783155f4bf956c346a81624ec9258930a6fe06 upstream. + +Fixes problem pointed out by Pavel in discussions about commit +729c0c9dd55204f0c9a823ac8a7bfa83d36c7e78 + +Signed-off-by: Pavel Shilovsky +Signed-off-by: Steve French +Reviewed-by: Ronnie Sahlberg +CC: Stable # 3.18.x+ +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7b2fd4b8775 --- /dev/null +++ b/queue-4.18/smb3-enumerating-snapshots-was-leaving-part-of-the-data-off-end.patch @@ -0,0 +1,90 @@ +From e02789a53d71334b067ad72eee5d4e88a0158083 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Thu, 9 Aug 2018 14:33:12 -0500 +Subject: smb3: enumerating snapshots was leaving part of the data off end + +From: Steve French + +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 +Signed-off-by: Steve French +Reviewed-by: Pavel Shilovsky +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e0aaae49511 --- /dev/null +++ b/queue-4.18/smb3-fill-in-statfs-fsid-and-correct-namelen.patch @@ -0,0 +1,112 @@ +From 21ba3845b59c733a79ed4fe1c4f3732e7ece9df7 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Sun, 24 Jun 2018 23:18:52 -0500 +Subject: smb3: fill in statfs fsid and correct namelen + +From: Steve French + +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 +CC: Stable +Reviewed-by: Aurelien Aptel +Signed-off-by: Greg Kroah-Hartman + +--- + 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 -- 2.47.3