From: Darrick J. Wong <djwong@xxxxxxxxxx> In the next patch we're going to add the ability to look up local/sf xattrs based on the attr name and value matching. As a result, we need callers of xfs_attr_set to declare explicitly that they want to remove an xattr. Passing in NULL value will no longer suffice. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_attr.c | 9 +++++---- fs/xfs/libxfs/xfs_parent.c | 1 + fs/xfs/xfs_xattr.c | 5 +++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 3065dd622102..756d93526075 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -977,6 +977,7 @@ xfs_attr_set( struct xfs_inode *dp = args->dp; struct xfs_mount *mp = dp->i_mount; struct xfs_trans_res tres; + bool is_remove = args->op_flags & XFS_DA_OP_REMOVE; bool rsvd; int error, local; int rmt_blks = 0; @@ -1004,7 +1005,7 @@ xfs_attr_set( args->op_flags = XFS_DA_OP_OKNOENT | (args->op_flags & XFS_DA_OP_LOGGED); - if (args->value) { + if (!is_remove) { XFS_STATS_INC(mp, xs_attr_set); args->total = xfs_attr_calc_size(args, &local); @@ -1038,7 +1039,7 @@ xfs_attr_set( if (error) return error; - if (args->value || xfs_inode_hasattr(dp)) { + if (!is_remove || xfs_inode_hasattr(dp)) { error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK, XFS_IEXT_ATTR_MANIP_CNT(rmt_blks)); if (error == -EFBIG) @@ -1052,7 +1053,7 @@ xfs_attr_set( switch (error) { case -EEXIST: /* if no value, we are performing a remove operation */ - if (!args->value) { + if (is_remove) { error = xfs_attr_defer_remove(args); break; } @@ -1064,7 +1065,7 @@ xfs_attr_set( break; case -ENOATTR: /* Can't remove what isn't there. */ - if (!args->value) + if (is_remove) goto out_trans_cancel; /* Pure replace fails if no existing attr to replace. */ diff --git a/fs/xfs/libxfs/xfs_parent.c b/fs/xfs/libxfs/xfs_parent.c index f7fecee93894..387f3c65287f 100644 --- a/fs/xfs/libxfs/xfs_parent.c +++ b/fs/xfs/libxfs/xfs_parent.c @@ -460,6 +460,7 @@ xfs_parent_unset( scr->args.geo = ip->i_mount->m_attr_geo; scr->args.name = (const unsigned char *)&scr->rec; scr->args.namelen = reclen; + scr->args.op_flags = XFS_DA_OP_REMOVE; scr->args.whichfork = XFS_ATTR_FORK; return xfs_attr_set(&scr->args); diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 85edd7e05fde..8f8aa13bf7eb 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -103,6 +103,11 @@ xfs_attr_change( use_logging = true; } + if (args->value) + args->op_flags &= ~XFS_DA_OP_REMOVE; + else + args->op_flags |= XFS_DA_OP_REMOVE; + error = xfs_attr_set(args); if (use_logging)