4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik josef@toxicpanda.com
commit 84de76a2fb217dc1b6bc2965cc397d1648aa1404 upstream.
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 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/free-space-cache.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -22,6 +22,7 @@ #include <linux/slab.h> #include <linux/math64.h> #include <linux/ratelimit.h> +#include <linux/sched/mm.h> #include "ctree.h" #include "free-space-cache.h" #include "transaction.h" @@ -59,6 +60,7 @@ static struct inode *__lookup_free_space struct btrfs_free_space_header *header; struct extent_buffer *leaf; struct inode *inode = NULL; + unsigned nofs_flag; int ret;
key.objectid = BTRFS_FREE_SPACE_OBJECTID; @@ -80,7 +82,13 @@ static struct inode *__lookup_free_space btrfs_disk_key_to_cpu(&location, &disk_key); btrfs_release_path(path);
+ /* + * We are often under a trans handle at this point, so we need to make + * sure NOFS is set to keep us from deadlocking. + */ + nofs_flag = memalloc_nofs_save(); inode = btrfs_iget(fs_info->sb, &location, root, NULL); + memalloc_nofs_restore(nofs_flag); if (IS_ERR(inode)) return inode; if (is_bad_inode(inode)) {