]>
Commit | Line | Data |
---|---|---|
63c89e6b GKH |
1 | From 7b38460dc8e4eafba06c78f8e37099d3b34d473c Mon Sep 17 00:00:00 2001 |
2 | From: "Darrick J. Wong" <darrick.wong@oracle.com> | |
3 | Date: Tue, 17 Apr 2018 19:10:15 -0700 | |
4 | Subject: xfs: don't fail when converting shortform attr to long form during ATTR_REPLACE | |
5 | ||
6 | From: Darrick J. Wong <darrick.wong@oracle.com> | |
7 | ||
8 | commit 7b38460dc8e4eafba06c78f8e37099d3b34d473c upstream. | |
9 | ||
10 | Kanda Motohiro reported that expanding a tiny xattr into a large xattr | |
11 | fails on XFS because we remove the tiny xattr from a shortform fork and | |
12 | then try to re-add it after converting the fork to extents format having | |
13 | not removed the ATTR_REPLACE flag. This fails because the attr is no | |
14 | longer present, causing a fs shutdown. | |
15 | ||
16 | This is derived from the patch in his bug report, but we really | |
17 | shouldn't ignore a nonzero retval from the remove call. | |
18 | ||
19 | Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199119 | |
20 | Reported-by: kanda.motohiro@gmail.com | |
21 | Reviewed-by: Dave Chinner <dchinner@redhat.com> | |
22 | Reviewed-by: Christoph Hellwig <hch@lst.de> | |
23 | Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> | |
24 | Cc: Ben Hutchings <ben.hutchings@codethink.co.uk> | |
25 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
26 | ||
27 | --- | |
28 | fs/xfs/libxfs/xfs_attr.c | 9 ++++++++- | |
29 | 1 file changed, 8 insertions(+), 1 deletion(-) | |
30 | ||
31 | --- a/fs/xfs/libxfs/xfs_attr.c | |
32 | +++ b/fs/xfs/libxfs/xfs_attr.c | |
33 | @@ -528,7 +528,14 @@ xfs_attr_shortform_addname(xfs_da_args_t | |
34 | if (args->flags & ATTR_CREATE) | |
35 | return retval; | |
36 | retval = xfs_attr_shortform_remove(args); | |
37 | - ASSERT(retval == 0); | |
38 | + if (retval) | |
39 | + return retval; | |
40 | + /* | |
41 | + * Since we have removed the old attr, clear ATTR_REPLACE so | |
42 | + * that the leaf format add routine won't trip over the attr | |
43 | + * not being around. | |
44 | + */ | |
45 | + args->flags &= ~ATTR_REPLACE; | |
46 | } | |
47 | ||
48 | if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX || |