diff options
author | Filipe Manana <fdmanana@suse.com> | 2018-12-10 12:53:35 -0500 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2018-12-17 08:51:49 -0500 |
commit | 827aa18e7b903c5ff3b3cd8fec328a99b1dbd411 (patch) | |
tree | 0681add9c902a36a0442cc5c542c1fe230ba74bb /fs/btrfs/xattr.c | |
parent | 0568e82dbe2510fc1fa664f58e5c997d3f1e649e (diff) |
Btrfs: use nofs context when initializing security xattrs to avoid deadlock
When initializing the security xattrs, we are holding a transaction handle
therefore we need to use a GFP_NOFS context in order to avoid a deadlock
with reclaim in case it's triggered.
Fixes: 39a27ec1004e8 ("btrfs: use GFP_KERNEL for xattr and acl allocations")
Reviewed-by: Nikolay Borisov <nborisov@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>
Diffstat (limited to 'fs/btrfs/xattr.c')
-rw-r--r-- | fs/btrfs/xattr.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index ea78c3d6dcfc..f141b45ce349 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/security.h> | 11 | #include <linux/security.h> |
12 | #include <linux/posix_acl_xattr.h> | 12 | #include <linux/posix_acl_xattr.h> |
13 | #include <linux/iversion.h> | 13 | #include <linux/iversion.h> |
14 | #include <linux/sched/mm.h> | ||
14 | #include "ctree.h" | 15 | #include "ctree.h" |
15 | #include "btrfs_inode.h" | 16 | #include "btrfs_inode.h" |
16 | #include "transaction.h" | 17 | #include "transaction.h" |
@@ -422,9 +423,15 @@ static int btrfs_initxattrs(struct inode *inode, | |||
422 | { | 423 | { |
423 | const struct xattr *xattr; | 424 | const struct xattr *xattr; |
424 | struct btrfs_trans_handle *trans = fs_info; | 425 | struct btrfs_trans_handle *trans = fs_info; |
426 | unsigned int nofs_flag; | ||
425 | char *name; | 427 | char *name; |
426 | int err = 0; | 428 | int err = 0; |
427 | 429 | ||
430 | /* | ||
431 | * We're holding a transaction handle, so use a NOFS memory allocation | ||
432 | * context to avoid deadlock if reclaim happens. | ||
433 | */ | ||
434 | nofs_flag = memalloc_nofs_save(); | ||
428 | for (xattr = xattr_array; xattr->name != NULL; xattr++) { | 435 | for (xattr = xattr_array; xattr->name != NULL; xattr++) { |
429 | name = kmalloc(XATTR_SECURITY_PREFIX_LEN + | 436 | name = kmalloc(XATTR_SECURITY_PREFIX_LEN + |
430 | strlen(xattr->name) + 1, GFP_KERNEL); | 437 | strlen(xattr->name) + 1, GFP_KERNEL); |
@@ -440,6 +447,7 @@ static int btrfs_initxattrs(struct inode *inode, | |||
440 | if (err < 0) | 447 | if (err < 0) |
441 | break; | 448 | break; |
442 | } | 449 | } |
450 | memalloc_nofs_restore(nofs_flag); | ||
443 | return err; | 451 | return err; |
444 | } | 452 | } |
445 | 453 | ||