xfs: pass the attr value to put_listent when possible
authorAllison Henderson <allison.henderson@oracle.com>
Mon, 22 Apr 2024 16:47:53 +0000 (09:47 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 23 Apr 2024 14:47:00 +0000 (07:47 -0700)
Pass the attr value to put_listent when we have local xattrs or
shortform xattrs.  This will enable the GETPARENTS ioctl to use
xfs_attr_list as its backend.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_attr.h
fs/xfs/libxfs/xfs_attr_sf.h
fs/xfs/xfs_attr_list.c
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_xattr.c

index d0ed7ea58ab0f14be997dda3882e94112691150f..d12583dd7eecbea312b4bf9ed57385469a628b12 100644 (file)
@@ -47,8 +47,9 @@ struct xfs_attrlist_cursor_kern {
 
 
 /* void; state communicated via *context */
-typedef void (*put_listent_func_t)(struct xfs_attr_list_context *, int,
-                             unsigned char *, int, int);
+typedef void (*put_listent_func_t)(struct xfs_attr_list_context *context,
+               int flags, unsigned char *name, int namelen, void *value,
+               int valuelen);
 
 struct xfs_attr_list_context {
        struct xfs_trans        *tp;
index bc44222230248678d2729b5dfc2f03242bb3c97a..73bdc0e5568251d1c95f7ef6db96ecaf2c54831b 100644 (file)
@@ -16,6 +16,7 @@ typedef struct xfs_attr_sf_sort {
        uint8_t         flags;          /* flags bits (see xfs_attr_leaf.h) */
        xfs_dahash_t    hash;           /* this entry's hash value */
        unsigned char   *name;          /* name value, pointer into buffer */
+       void            *value;
 } xfs_attr_sf_sort_t;
 
 #define XFS_ATTR_SF_ENTSIZE_MAX                        /* max space for name&value */ \
index 9bc4b5322539a96df758186176b14d5d99959b7c..5c947e5ce8b8811d659c9b964f0d2e74fc2bf7c1 100644 (file)
@@ -92,6 +92,7 @@ xfs_attr_shortform_list(
                                             sfe->flags,
                                             sfe->nameval,
                                             (int)sfe->namelen,
+                                            &sfe->nameval[sfe->namelen],
                                             (int)sfe->valuelen);
                        /*
                         * Either search callback finished early or
@@ -138,6 +139,7 @@ xfs_attr_shortform_list(
                sbp->name = sfe->nameval;
                sbp->namelen = sfe->namelen;
                /* These are bytes, and both on-disk, don't endian-flip */
+               sbp->value = &sfe->nameval[sfe->namelen],
                sbp->valuelen = sfe->valuelen;
                sbp->flags = sfe->flags;
                sbp->hash = xfs_attr_hashval(dp->i_mount, sfe->flags,
@@ -192,6 +194,7 @@ xfs_attr_shortform_list(
                                     sbp->flags,
                                     sbp->name,
                                     sbp->namelen,
+                                    sbp->value,
                                     sbp->valuelen);
                if (context->seen_enough)
                        break;
@@ -479,6 +482,7 @@ xfs_attr3_leaf_list_int(
         */
        for (; i < ichdr.count; entry++, i++) {
                char *name;
+               void *value;
                int namelen, valuelen;
 
                if (be32_to_cpu(entry->hashval) != cursor->hashval) {
@@ -496,6 +500,7 @@ xfs_attr3_leaf_list_int(
                        name_loc = xfs_attr3_leaf_name_local(leaf, i);
                        name = name_loc->nameval;
                        namelen = name_loc->namelen;
+                       value = &name_loc->nameval[name_loc->namelen];
                        valuelen = be16_to_cpu(name_loc->valuelen);
                } else {
                        xfs_attr_leaf_name_remote_t *name_rmt;
@@ -503,6 +508,7 @@ xfs_attr3_leaf_list_int(
                        name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
                        name = name_rmt->name;
                        namelen = name_rmt->namelen;
+                       value = NULL;
                        valuelen = be32_to_cpu(name_rmt->valuelen);
                }
 
@@ -513,7 +519,7 @@ xfs_attr3_leaf_list_int(
                        return -EFSCORRUPTED;
                }
                context->put_listent(context, entry->flags,
-                                             name, namelen, valuelen);
+                                             name, namelen, value, valuelen);
                if (context->seen_enough)
                        break;
                cursor->offset++;
index e30f9f40f086d91a1fa091e69c10d04bfb48a283..7a2a5cf06a5cbaf562d6ccf3f389ca6a4aaeebc1 100644 (file)
@@ -310,6 +310,7 @@ xfs_ioc_attr_put_listent(
        int                     flags,
        unsigned char           *name,
        int                     namelen,
+       void                    *value,
        int                     valuelen)
 {
        struct xfs_attrlist     *alist = context->buffer;
index 1e82d11d980f27d2e260314499d8af2319054c31..b43f7081b0f468d9819ff6db5f496479350ef542 100644 (file)
@@ -222,6 +222,7 @@ xfs_xattr_put_listent(
        int             flags,
        unsigned char   *name,
        int             namelen,
+       void            *value,
        int             valuelen)
 {
        char *prefix;