diff options
author | Josef Bacik <josef@toxicpanda.com> | 2018-09-28 07:17:49 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2018-10-15 11:23:38 -0400 |
commit | 84de76a2fb217dc1b6bc2965cc397d1648aa1404 (patch) | |
tree | 03c0908b3ed542b43d9d57bf0a5a41db70461403 | |
parent | f45c752b65af46bf42963295c332865d95f97fff (diff) |
btrfs: protect space cache inode alloc with GFP_NOFS
If we're allocating a new space cache inode it's likely going to be
under a transaction handle, so we need to use memalloc_nofs_save() in
order to avoid deadlocks, and more importantly lockdep messages that
make xfstests fail.
CC: stable@vger.kernel.org # 4.4+
Reviewed-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r-- | fs/btrfs/free-space-cache.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index ed097ff023e8..a1f379e8ad13 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/math64.h> | 10 | #include <linux/math64.h> |
11 | #include <linux/ratelimit.h> | 11 | #include <linux/ratelimit.h> |
12 | #include <linux/error-injection.h> | 12 | #include <linux/error-injection.h> |
13 | #include <linux/sched/mm.h> | ||
13 | #include "ctree.h" | 14 | #include "ctree.h" |
14 | #include "free-space-cache.h" | 15 | #include "free-space-cache.h" |
15 | #include "transaction.h" | 16 | #include "transaction.h" |
@@ -47,6 +48,7 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root, | |||
47 | struct btrfs_free_space_header *header; | 48 | struct btrfs_free_space_header *header; |
48 | struct extent_buffer *leaf; | 49 | struct extent_buffer *leaf; |
49 | struct inode *inode = NULL; | 50 | struct inode *inode = NULL; |
51 | unsigned nofs_flag; | ||
50 | int ret; | 52 | int ret; |
51 | 53 | ||
52 | key.objectid = BTRFS_FREE_SPACE_OBJECTID; | 54 | key.objectid = BTRFS_FREE_SPACE_OBJECTID; |
@@ -68,7 +70,13 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root, | |||
68 | btrfs_disk_key_to_cpu(&location, &disk_key); | 70 | btrfs_disk_key_to_cpu(&location, &disk_key); |
69 | btrfs_release_path(path); | 71 | btrfs_release_path(path); |
70 | 72 | ||
73 | /* | ||
74 | * We are often under a trans handle at this point, so we need to make | ||
75 | * sure NOFS is set to keep us from deadlocking. | ||
76 | */ | ||
77 | nofs_flag = memalloc_nofs_save(); | ||
71 | inode = btrfs_iget(fs_info->sb, &location, root, NULL); | 78 | inode = btrfs_iget(fs_info->sb, &location, root, NULL); |
79 | memalloc_nofs_restore(nofs_flag); | ||
72 | if (IS_ERR(inode)) | 80 | if (IS_ERR(inode)) |
73 | return inode; | 81 | return inode; |
74 | 82 | ||