]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: make attr removal an explicit operation
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 Jul 2024 23:22:43 +0000 (16:22 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:01 +0000 (17:01 -0700)
Source kernel commit: c27411d4c640037d70e2fa5751616e175e52ca5e

Parent pointers match attrs on name+value, unlike everything else which
matches on only the name.  Therefore, we cannot keep using the heuristic
that !value means remove.  Make this an explicit operation code.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
db/attrset.c
libxfs/xfs_attr.c
libxfs/xfs_attr.h

index 736482fea05c608e33be4f02b38302a16cc9ac8a..a59d5473e0327566814f7919e2f12e58bb2b1d8a 100644 (file)
@@ -69,7 +69,7 @@ attr_set_f(
 {
        struct xfs_da_args      args = { };
        char                    *sp;
-       enum xfs_attr_update    op = XFS_ATTRUPDATE_UPSERTR;
+       enum xfs_attr_update    op = XFS_ATTRUPDATE_UPSERT;
        int                     c;
 
        if (cur_typ == NULL) {
@@ -247,7 +247,7 @@ attr_remove_f(
                goto out;
        }
 
-       if (libxfs_attr_set(&args, XFS_ATTRUPDATE_UPSERTR)) {
+       if (libxfs_attr_set(&args, XFS_ATTRUPDATE_REMOVE)) {
                dbprintf(_("failed to remove attr %s from inode %llu\n"),
                        (unsigned char *)args.name,
                        (unsigned long long)iocur_top->ino);
index 9a6787624fb73953502320200627f205ea7ccc16..5249f9be046e50a5ae51fa6d12e7f63c03f37d42 100644 (file)
@@ -914,10 +914,6 @@ xfs_attr_defer_add(
        trace_xfs_attr_defer_add(new->xattri_dela_state, args->dp);
 }
 
-/*
- * Note: If args->value is NULL the attribute will be removed, just like the
- * Linux ->setattr API.
- */
 int
 xfs_attr_set(
        struct xfs_da_args      *args,
@@ -953,7 +949,10 @@ xfs_attr_set(
        args->op_flags = XFS_DA_OP_OKNOENT |
                                        (args->op_flags & XFS_DA_OP_LOGGED);
 
-       if (args->value) {
+       switch (op) {
+       case XFS_ATTRUPDATE_UPSERT:
+       case XFS_ATTRUPDATE_CREATE:
+       case XFS_ATTRUPDATE_REPLACE:
                XFS_STATS_INC(mp, xs_attr_set);
                args->total = xfs_attr_calc_size(args, &local);
 
@@ -973,9 +972,11 @@ xfs_attr_set(
 
                if (!local)
                        rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
-       } else {
+               break;
+       case XFS_ATTRUPDATE_REMOVE:
                XFS_STATS_INC(mp, xs_attr_remove);
                rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
+               break;
        }
 
        /*
@@ -987,7 +988,7 @@ xfs_attr_set(
        if (error)
                return error;
 
-       if (args->value || xfs_inode_hasattr(dp)) {
+       if (op != XFS_ATTRUPDATE_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)
@@ -1000,7 +1001,7 @@ xfs_attr_set(
        error = xfs_attr_lookup(args);
        switch (error) {
        case -EEXIST:
-               if (!args->value) {
+               if (op == XFS_ATTRUPDATE_REMOVE) {
                        /* if no value, we are performing a remove operation */
                        xfs_attr_defer_add(args, XFS_ATTRI_OP_FLAGS_REMOVE);
                        break;
@@ -1013,7 +1014,7 @@ xfs_attr_set(
                break;
        case -ENOATTR:
                /* Can't remove what isn't there. */
-               if (!args->value)
+               if (op == XFS_ATTRUPDATE_REMOVE)
                        goto out_trans_cancel;
 
                /* Pure replace fails if no existing attr to replace. */
index 228360f7c85ce7276ef8de9a20a6bad4b9160406..c8005f52102adc530efbd7308bba9524cb76cb1e 100644 (file)
@@ -546,7 +546,8 @@ int xfs_attr_get_ilocked(struct xfs_da_args *args);
 int xfs_attr_get(struct xfs_da_args *args);
 
 enum xfs_attr_update {
-       XFS_ATTRUPDATE_UPSERTR, /* set/remove value, replace any existing attr */
+       XFS_ATTRUPDATE_REMOVE,  /* remove attr */
+       XFS_ATTRUPDATE_UPSERT,  /* set value, replace any existing attr */
        XFS_ATTRUPDATE_CREATE,  /* set value, fail if attr already exists */
        XFS_ATTRUPDATE_REPLACE, /* set value, fail if attr does not exist */
 };