]> git.itanic.dy.fi Git - linux-stable/commitdiff
xfs: simplify xfs_attr_sf_findname
authorChristoph Hellwig <hch@lst.de>
Wed, 20 Dec 2023 06:34:58 +0000 (07:34 +0100)
committerChandan Babu R <chandanbabu@kernel.org>
Fri, 29 Dec 2023 08:07:04 +0000 (13:37 +0530)
xfs_attr_sf_findname has the simple job of finding a xfs_attr_sf_entry in
the attr fork, but the convoluted calling convention obfuscates that.

Return the found entry as the return value instead of an pointer
argument, as the -ENOATTR/-EEXIST can be trivally derived from that, and
remove the basep argument, as it is equivalent of the offset of sfe in
the data for if an sfe was found, or an offset of totsize if not was
found.  To simplify the totsize computation add a xfs_attr_sf_endptr
helper that returns the imaginative xfs_attr_sf_entry at the end of
the current attrs.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
fs/xfs/libxfs/xfs_attr.c
fs/xfs/libxfs/xfs_attr_leaf.c
fs/xfs/libxfs/xfs_attr_leaf.h
fs/xfs/libxfs/xfs_attr_sf.h

index 7f822e72dfcd3ec1bd6663b314520a9ab6b6000e..bcf8748cb1a333a5ffbff59302c39ad05f7ee9f2 100644 (file)
@@ -862,8 +862,11 @@ xfs_attr_lookup(
        if (!xfs_inode_hasattr(dp))
                return -ENOATTR;
 
-       if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
-               return xfs_attr_sf_findname(args, NULL, NULL);
+       if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL) {
+               if (xfs_attr_sf_findname(args))
+                       return -EEXIST;
+               return -ENOATTR;
+       }
 
        if (xfs_attr_is_leaf(dp)) {
                error = xfs_attr_leaf_hasname(args, &bp);
index 37474af8ee46337722674f86244b1ab9869959f9..7a623efd23a6a45d0aed3f28ba7e117ae8405eaf 100644 (file)
@@ -698,47 +698,24 @@ xfs_attr_shortform_create(
 }
 
 /*
- * Return -EEXIST if attr is found, or -ENOATTR if not
- * args:  args containing attribute name and namelen
- * sfep:  If not null, pointer will be set to the last attr entry found on
-         -EEXIST.  On -ENOATTR pointer is left at the last entry in the list
- * basep: If not null, pointer is set to the byte offset of the entry in the
- *       list on -EEXIST.  On -ENOATTR, pointer is left at the byte offset of
- *       the last entry in the list
+ * Return the entry if the attr in args is found, or NULL if not.
  */
-int
+struct xfs_attr_sf_entry *
 xfs_attr_sf_findname(
-       struct xfs_da_args       *args,
-       struct xfs_attr_sf_entry **sfep,
-       unsigned int             *basep)
+       struct xfs_da_args              *args)
 {
-       struct xfs_attr_shortform *sf = args->dp->i_af.if_data;
-       struct xfs_attr_sf_entry *sfe;
-       unsigned int            base = sizeof(struct xfs_attr_sf_hdr);
-       int                     size = 0;
-       int                     end;
-       int                     i;
+       struct xfs_attr_shortform       *sf = args->dp->i_af.if_data;
+       struct xfs_attr_sf_entry        *sfe;
 
-       sfe = &sf->list[0];
-       end = sf->hdr.count;
-       for (i = 0; i < end; sfe = xfs_attr_sf_nextentry(sfe),
-                            base += size, i++) {
-               size = xfs_attr_sf_entsize(sfe);
-               if (!xfs_attr_match(args, sfe->namelen, sfe->nameval,
-                                   sfe->flags))
-                       continue;
-               break;
+       for (sfe = &sf->list[0];
+            sfe < xfs_attr_sf_endptr(sf);
+            sfe = xfs_attr_sf_nextentry(sfe)) {
+               if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
+                               sfe->flags))
+                       return sfe;
        }
 
-       if (sfep != NULL)
-               *sfep = sfe;
-
-       if (basep != NULL)
-               *basep = base;
-
-       if (i == end)
-               return -ENOATTR;
-       return -EEXIST;
+       return NULL;
 }
 
 /*
@@ -755,21 +732,19 @@ xfs_attr_shortform_add(
        struct xfs_ifork                *ifp = &dp->i_af;
        struct xfs_attr_shortform       *sf = ifp->if_data;
        struct xfs_attr_sf_entry        *sfe;
-       int                             offset, size;
+       int                             size;
 
        trace_xfs_attr_sf_add(args);
 
        dp->i_forkoff = forkoff;
 
        ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
-       if (xfs_attr_sf_findname(args, &sfe, NULL) == -EEXIST)
-               ASSERT(0);
+       ASSERT(!xfs_attr_sf_findname(args));
 
-       offset = (char *)sfe - (char *)sf;
        size = xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
        sf = xfs_idata_realloc(dp, size, XFS_ATTR_FORK);
-       sfe = (struct xfs_attr_sf_entry *)((char *)sf + offset);
 
+       sfe = xfs_attr_sf_endptr(sf);
        sfe->namelen = args->namelen;
        sfe->valuelen = args->valuelen;
        sfe->flags = args->attr_filter;
@@ -809,39 +784,38 @@ xfs_attr_sf_removename(
        struct xfs_mount                *mp = dp->i_mount;
        struct xfs_attr_shortform       *sf = dp->i_af.if_data;
        struct xfs_attr_sf_entry        *sfe;
-       int                             size = 0, end, totsize;
-       unsigned int                    base;
-       int                             error;
+       uint16_t                        totsize = be16_to_cpu(sf->hdr.totsize);
+       void                            *next, *end;
+       int                             size = 0;
 
        trace_xfs_attr_sf_remove(args);
 
-       error = xfs_attr_sf_findname(args, &sfe, &base);
-
-       /*
-        * If we are recovering an operation, finding nothing to
-        * remove is not an error - it just means there was nothing
-        * to clean up.
-        */
-       if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
-               return 0;
-       if (error != -EEXIST)
-               return error;
-       size = xfs_attr_sf_entsize(sfe);
+       sfe = xfs_attr_sf_findname(args);
+       if (!sfe) {
+               /*
+                * If we are recovering an operation, finding nothing to remove
+                * is not an error, it just means there was nothing to clean up.
+                */
+               if (args->op_flags & XFS_DA_OP_RECOVERY)
+                       return 0;
+               return -ENOATTR;
+       }
 
        /*
         * Fix up the attribute fork data, covering the hole
         */
-       end = base + size;
-       totsize = be16_to_cpu(sf->hdr.totsize);
-       if (end != totsize)
-               memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
+       size = xfs_attr_sf_entsize(sfe);
+       next = xfs_attr_sf_nextentry(sfe);
+       end = xfs_attr_sf_endptr(sf);
+       if (next < end)
+               memmove(sfe, next, end - next);
        sf->hdr.count--;
-       be16_add_cpu(&sf->hdr.totsize, -size);
+       totsize -= size;
+       sf->hdr.totsize = cpu_to_be16(totsize);
 
        /*
         * Fix up the start offset of the attribute fork
         */
-       totsize -= size;
        if (totsize == sizeof(xfs_attr_sf_hdr_t) && xfs_has_attr2(mp) &&
            (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
            !(args->op_flags & (XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE))) {
index ce6743463c868174f3a7f11563dd9f8a88fda001..56fcd689eedfe7b1778638bf81d0678c8bb935de 100644 (file)
@@ -51,9 +51,7 @@ int   xfs_attr_shortform_lookup(struct xfs_da_args *args);
 int    xfs_attr_shortform_getvalue(struct xfs_da_args *args);
 int    xfs_attr_shortform_to_leaf(struct xfs_da_args *args);
 int    xfs_attr_sf_removename(struct xfs_da_args *args);
-int    xfs_attr_sf_findname(struct xfs_da_args *args,
-                            struct xfs_attr_sf_entry **sfep,
-                            unsigned int *basep);
+struct xfs_attr_sf_entry *xfs_attr_sf_findname(struct xfs_da_args *args);
 int    xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp);
 int    xfs_attr_shortform_bytesfit(struct xfs_inode *dp, int bytes);
 xfs_failaddr_t xfs_attr_shortform_verify(struct xfs_attr_shortform *sfp,
index 37578b369d9b987ede140a949c9768c6b5c747b2..a774d4d87763543a99b28fd82407893c2c229e9e 100644 (file)
@@ -48,4 +48,11 @@ xfs_attr_sf_nextentry(struct xfs_attr_sf_entry *sfep)
        return (void *)sfep + xfs_attr_sf_entsize(sfep);
 }
 
+/* pointer to the space after the last entry, e.g. for adding a new one */
+static inline struct xfs_attr_sf_entry *
+xfs_attr_sf_endptr(struct xfs_attr_shortform *sf)
+{
+       return (void *)sf + be16_to_cpu(sf->hdr.totsize);
+}
+
 #endif /* __XFS_ATTR_SF_H__ */