| From 657a3193242473ff29a4850de32470a854e78cc5 Mon Sep 17 00:00:00 2001 |
| From: Josef Bacik <josef@toxicpanda.com> |
| Date: Fri, 17 Jan 2020 09:02:20 -0500 |
| Subject: [PATCH] btrfs: don't set path->leave_spinning for truncate |
| |
| commit 52e29e331070cd7d52a64cbf1b0958212a340e28 upstream. |
| |
| The only time we actually leave the path spinning is if we're truncating |
| a small amount and don't actually free an extent, which is not a common |
| occurrence. We have to set the path blocking in order to add the |
| delayed ref anyway, so the first extent we find we set the path to |
| blocking and stay blocking for the duration of the operation. With the |
| upcoming file extent map stuff there will be another case that we have |
| to have the path blocking, so just swap to blocking always. |
| |
| Note: this patch also fixes a warning after 28553fa992cb ("Btrfs: fix |
| race between shrinking truncate and fiemap") got merged that inserts |
| extent locks around truncation so the path must not leave spinning locks |
| after btrfs_search_slot. |
| |
| [70.794783] BUG: sleeping function called from invalid context at mm/slab.h:565 |
| [70.794834] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1141, name: rsync |
| [70.794863] 5 locks held by rsync/1141: |
| [70.794876] #0: ffff888417b9c408 (sb_writers#17){.+.+}, at: mnt_want_write+0x20/0x50 |
| [70.795030] #1: ffff888428de28e8 (&type->i_mutex_dir_key#13/1){+.+.}, at: lock_rename+0xf1/0x100 |
| [70.795051] #2: ffff888417b9c608 (sb_internal#2){.+.+}, at: start_transaction+0x394/0x560 |
| [70.795124] #3: ffff888403081768 (btrfs-fs-01){++++}, at: btrfs_try_tree_write_lock+0x2f/0x160 |
| [70.795203] #4: ffff888403086568 (btrfs-fs-00){++++}, at: btrfs_try_tree_write_lock+0x2f/0x160 |
| [70.795222] CPU: 5 PID: 1141 Comm: rsync Not tainted 5.6.0-rc2-backup+ #2 |
| [70.795362] Call Trace: |
| [70.795374] dump_stack+0x71/0xa0 |
| [70.795445] ___might_sleep.part.96.cold.106+0xa6/0xb6 |
| [70.795459] kmem_cache_alloc+0x1d3/0x290 |
| [70.795471] alloc_extent_state+0x22/0x1c0 |
| [70.795544] __clear_extent_bit+0x3ba/0x580 |
| [70.795557] ? _raw_spin_unlock_irq+0x24/0x30 |
| [70.795569] btrfs_truncate_inode_items+0x339/0xe50 |
| [70.795647] btrfs_evict_inode+0x269/0x540 |
| [70.795659] ? dput.part.38+0x29/0x460 |
| [70.795671] evict+0xcd/0x190 |
| [70.795682] __dentry_kill+0xd6/0x180 |
| [70.795754] dput.part.38+0x2ad/0x460 |
| [70.795765] do_renameat2+0x3cb/0x540 |
| [70.795777] __x64_sys_rename+0x1c/0x20 |
| |
| Reported-by: Dave Jones <davej@codemonkey.org.uk> |
| Fixes: 28553fa992cb ("Btrfs: fix race between shrinking truncate and fiemap") |
| CC: stable@vger.kernel.org # 4.4+ |
| Reviewed-by: Filipe Manana <fdmanana@suse.com> |
| Signed-off-by: Josef Bacik <josef@toxicpanda.com> |
| Reviewed-by: David Sterba <dsterba@suse.com> |
| [ add note ] |
| Signed-off-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c |
| index f48f204b4353..dc92c6f1eb04 100644 |
| --- a/fs/btrfs/inode.c |
| +++ b/fs/btrfs/inode.c |
| @@ -4718,7 +4718,6 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, |
| goto out; |
| } |
| |
| - path->leave_spinning = 1; |
| ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
| if (ret < 0) |
| goto out; |
| @@ -4870,7 +4869,6 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, |
| root == fs_info->tree_root)) { |
| struct btrfs_ref ref = { 0 }; |
| |
| - btrfs_set_path_blocking(path); |
| bytes_deleted += extent_num_bytes; |
| |
| btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, |
| -- |
| 2.7.4 |
| |