add patch report-delalloc-reserve-as-non-free-in-statfs-for-project-quota
[ext4-patch-queue.git] / use-XATTR_CREATE-in-ext4_initxattrs
blob75d127f9d4594ee538029386be682415c5b5f625
1 ext4: use XATTR_CREATE in ext4_initxattrs()
3 From: Eryu Guan <guaneryu@gmail.com>
5 I hit ENOSPC error when creating new file in a newly created ext4
6 with ea_inode feature enabled, if selinux is enabled and ext4 is
7 mounted without any selinux context. e.g.
9   mkfs -t ext4 -O ea_inode -F /dev/sda5
10   mount /dev/sda5 /mnt/ext4
11   touch /mnt/ext4/testfile  # got ENOSPC here
13 It turns out that we run out of journal credits in
14 ext4_xattr_set_handle() when creating new selinux label for the
15 newly created inode.
17 This is because that in __ext4_new_inode() we use
18 __ext4_xattr_set_credits() to calculate the reserved credits for new
19 xattr, with the 'is_create' argument being true, which implies less
20 credits in the ea_inode case. But we calculate the required credits
21 in ext4_xattr_set_handle() with 'is_create' being false, which means
22 we need more credits if ea_inode feature is enabled. So we don't
23 have enough credits and error out with ENOSPC.
25 Fix it by simply calling ext4_xattr_set_handle() with XATTR_CREATE
26 flag in ext4_initxattrs(), so we end up with requiring less credits
27 than reserved. The semantic of XATTR_CREATE is "Perform a pure
28 create, which fails if the named attribute exists already." (from
29 setxattr(2)), which is fine in this case, because we only call
30 ext4_initxattrs() on newly created inode.
32 Fixes: af65207c76ce ("ext4: fix __ext4_new_inode() journal credits calculation")
33 Cc: Tahsin Erdogan <tahsin@google.com>
34 Signed-off-by: Eryu Guan <guaneryu@gmail.com>
35 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
36 ---
37  fs/ext4/xattr_security.c | 2 +-
38  1 file changed, 1 insertion(+), 1 deletion(-)
40 diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
41 index 629001b28632..197a9d8a15ef 100644
42 --- a/fs/ext4/xattr_security.c
43 +++ b/fs/ext4/xattr_security.c
44 @@ -43,7 +43,7 @@ ext4_initxattrs(struct inode *inode, const struct xattr *xattr_array,
45                 err = ext4_xattr_set_handle(handle, inode,
46                                             EXT4_XATTR_INDEX_SECURITY,
47                                             xattr->name, xattr->value,
48 -                                           xattr->value_len, 0);
49 +                                           xattr->value_len, XATTR_CREATE);
50                 if (err < 0)
51                         break;
52         }
53 -- 
54 2.14.3