]> git.itanic.dy.fi Git - linux-stable/commitdiff
xfs: remove struct xfs_attr_shortform
authorChristoph Hellwig <hch@lst.de>
Wed, 20 Dec 2023 06:35:01 +0000 (07:35 +0100)
committerChandan Babu R <chandanbabu@kernel.org>
Fri, 29 Dec 2023 08:07:05 +0000 (13:37 +0530)
sparse complains about struct xfs_attr_shortform because it embeds a
structure with a variable sized array in a variable sized array.

Given that xfs_attr_shortform is not a very useful structure, and the
dir2 equivalent has been removed a long time ago, remove it as well.

Provide a xfs_attr_sf_firstentry helper that returns the first
xfs_attr_sf_entry behind a xfs_attr_sf_hdr to replace the structure
dereference.

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
fs/xfs/libxfs/xfs_da_format.h
fs/xfs/libxfs/xfs_inode_fork.c
fs/xfs/libxfs/xfs_ondisk.h
fs/xfs/scrub/attr.c
fs/xfs/scrub/inode_repair.c
fs/xfs/xfs_attr_list.c

index e8b4317da830ba4e96436cbb3d40521eec8fdc88..ec4061db7ffccd3a5d93b8f75ac0e19a486c6357 100644 (file)
@@ -1052,9 +1052,9 @@ xfs_attr_set(
 
 static inline int xfs_attr_sf_totsize(struct xfs_inode *dp)
 {
-       struct xfs_attr_shortform *sf = dp->i_af.if_data;
+       struct xfs_attr_sf_hdr *sf = dp->i_af.if_data;
 
-       return be16_to_cpu(sf->hdr.totsize);
+       return be16_to_cpu(sf->totsize);
 }
 
 /*
index 82e1830334160b9087c84832f7113dae971bb6ab..e1281ab413c8320b5c0aa1ee64725e07f2b69a52 100644 (file)
@@ -704,10 +704,10 @@ struct xfs_attr_sf_entry *
 xfs_attr_sf_findname(
        struct xfs_da_args              *args)
 {
-       struct xfs_attr_shortform       *sf = args->dp->i_af.if_data;
+       struct xfs_attr_sf_hdr          *sf = args->dp->i_af.if_data;
        struct xfs_attr_sf_entry        *sfe;
 
-       for (sfe = &sf->list[0];
+       for (sfe = xfs_attr_sf_firstentry(sf);
             sfe < xfs_attr_sf_endptr(sf);
             sfe = xfs_attr_sf_nextentry(sfe)) {
                if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
@@ -730,7 +730,7 @@ xfs_attr_shortform_add(
        struct xfs_inode                *dp = args->dp;
        struct xfs_mount                *mp = dp->i_mount;
        struct xfs_ifork                *ifp = &dp->i_af;
-       struct xfs_attr_shortform       *sf = ifp->if_data;
+       struct xfs_attr_sf_hdr          *sf = ifp->if_data;
        struct xfs_attr_sf_entry        *sfe;
        int                             size;
 
@@ -750,8 +750,8 @@ xfs_attr_shortform_add(
        sfe->flags = args->attr_filter;
        memcpy(sfe->nameval, args->name, args->namelen);
        memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
-       sf->hdr.count++;
-       be16_add_cpu(&sf->hdr.totsize, size);
+       sf->count++;
+       be16_add_cpu(&sf->totsize, size);
        xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
 
        xfs_sbversion_add_attr2(mp, args->trans);
@@ -782,9 +782,9 @@ xfs_attr_sf_removename(
 {
        struct xfs_inode                *dp = args->dp;
        struct xfs_mount                *mp = dp->i_mount;
-       struct xfs_attr_shortform       *sf = dp->i_af.if_data;
+       struct xfs_attr_sf_hdr          *sf = dp->i_af.if_data;
        struct xfs_attr_sf_entry        *sfe;
-       uint16_t                        totsize = be16_to_cpu(sf->hdr.totsize);
+       uint16_t                        totsize = be16_to_cpu(sf->totsize);
        void                            *next, *end;
        int                             size = 0;
 
@@ -809,9 +809,9 @@ xfs_attr_sf_removename(
        end = xfs_attr_sf_endptr(sf);
        if (next < end)
                memmove(sfe, next, end - next);
-       sf->hdr.count--;
+       sf->count--;
        totsize -= size;
-       sf->hdr.totsize = cpu_to_be16(totsize);
+       sf->totsize = cpu_to_be16(totsize);
 
        /*
         * Fix up the start offset of the attribute fork
@@ -868,21 +868,21 @@ xfs_attr_shortform_to_leaf(
 {
        struct xfs_inode                *dp = args->dp;
        struct xfs_ifork                *ifp = &dp->i_af;
-       struct xfs_attr_shortform       *sf = ifp->if_data;
+       struct xfs_attr_sf_hdr          *sf = ifp->if_data;
        struct xfs_attr_sf_entry        *sfe;
+       int                             size = be16_to_cpu(sf->totsize);
        struct xfs_da_args              nargs;
        char                            *tmpbuffer;
-       int                             error, i, size;
+       int                             error, i;
        xfs_dablk_t                     blkno;
        struct xfs_buf                  *bp;
 
        trace_xfs_attr_sf_to_leaf(args);
 
-       size = be16_to_cpu(sf->hdr.totsize);
        tmpbuffer = kmem_alloc(size, 0);
        ASSERT(tmpbuffer != NULL);
        memcpy(tmpbuffer, ifp->if_data, size);
-       sf = (struct xfs_attr_shortform *)tmpbuffer;
+       sf = (struct xfs_attr_sf_hdr *)tmpbuffer;
 
        xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
        xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK);
@@ -905,8 +905,8 @@ xfs_attr_shortform_to_leaf(
        nargs.trans = args->trans;
        nargs.op_flags = XFS_DA_OP_OKNOENT;
 
-       sfe = &sf->list[0];
-       for (i = 0; i < sf->hdr.count; i++) {
+       sfe = xfs_attr_sf_firstentry(sf);
+       for (i = 0; i < sf->count; i++) {
                nargs.name = sfe->nameval;
                nargs.namelen = sfe->namelen;
                nargs.value = &sfe->nameval[nargs.namelen];
@@ -973,10 +973,10 @@ xfs_attr_shortform_allfit(
 /* Verify the consistency of a raw inline attribute fork. */
 xfs_failaddr_t
 xfs_attr_shortform_verify(
-       struct xfs_attr_shortform       *sfp,
+       struct xfs_attr_sf_hdr          *sfp,
        size_t                          size)
 {
-       struct xfs_attr_sf_entry        *sfep;
+       struct xfs_attr_sf_entry        *sfep = xfs_attr_sf_firstentry(sfp);
        struct xfs_attr_sf_entry        *next_sfep;
        char                            *endp;
        int                             i;
@@ -990,8 +990,7 @@ xfs_attr_shortform_verify(
        endp = (char *)sfp + size;
 
        /* Check all reported entries */
-       sfep = &sfp->list[0];
-       for (i = 0; i < sfp->hdr.count; i++) {
+       for (i = 0; i < sfp->count; i++) {
                /*
                 * struct xfs_attr_sf_entry has a variable length.
                 * Check the fixed-offset parts of the structure are
index 35e668ae744fb14bef8d39a6e051b0b4c014762f..9b9948639c0fb34f20c503eb9e0d6ed3e17817e4 100644 (file)
@@ -53,7 +53,7 @@ int   xfs_attr_sf_removename(struct xfs_da_args *args);
 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,
+xfs_failaddr_t xfs_attr_shortform_verify(struct xfs_attr_sf_hdr *sfp,
                size_t size);
 void   xfs_attr_fork_remove(struct xfs_inode *ip, struct xfs_trans *tp);
 
index a774d4d87763543a99b28fd82407893c2c229e9e..9abf7de95465f5aad5c92d9e780221bbc19f7e42 100644 (file)
@@ -41,7 +41,14 @@ static inline int xfs_attr_sf_entsize(struct xfs_attr_sf_entry *sfep)
        return struct_size(sfep, nameval, sfep->namelen + sfep->valuelen);
 }
 
-/* next entry in struct */
+/* first entry in the SF attr fork */
+static inline struct xfs_attr_sf_entry *
+xfs_attr_sf_firstentry(struct xfs_attr_sf_hdr *hdr)
+{
+       return (struct xfs_attr_sf_entry *)(hdr + 1);
+}
+
+/* next entry after sfep */
 static inline struct xfs_attr_sf_entry *
 xfs_attr_sf_nextentry(struct xfs_attr_sf_entry *sfep)
 {
@@ -50,9 +57,9 @@ xfs_attr_sf_nextentry(struct xfs_attr_sf_entry *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)
+xfs_attr_sf_endptr(struct xfs_attr_sf_hdr *sf)
 {
-       return (void *)sf + be16_to_cpu(sf->hdr.totsize);
+       return (void *)sf + be16_to_cpu(sf->totsize);
 }
 
 #endif /* __XFS_ATTR_SF_H__ */
index f9015f88eca70679e6a5e915f43eddaf0cb6a299..24f9d1461f9a6f72442da9acbed5ed7251d908c0 100644 (file)
@@ -578,20 +578,25 @@ xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
 #define XFS_ATTR_LEAF_MAPSIZE  3       /* how many freespace slots */
 
 /*
- * Entries are packed toward the top as tight as possible.
- */
-struct xfs_attr_shortform {
-       struct xfs_attr_sf_hdr {        /* constant-structure header block */
-               __be16  totsize;        /* total bytes in shortform list */
-               __u8    count;  /* count of active entries */
-               __u8    padding;
-       } hdr;
-       struct xfs_attr_sf_entry {
-               uint8_t namelen;        /* actual length of name (no NULL) */
-               uint8_t valuelen;       /* actual length of value (no NULL) */
-               uint8_t flags;  /* flags bits (see xfs_attr_leaf.h) */
-               uint8_t nameval[];      /* name & value bytes concatenated */
-       } list[];                       /* variable sized array */
+ * Attribute storage when stored inside the inode.
+ *
+ * Small attribute lists are packed as tightly as possible so as to fit into the
+ * literal area of the inode.
+ *
+ * These "shortform" attribute forks consist of a single xfs_attr_sf_hdr header
+ * followed by zero or more xfs_attr_sf_entry structures.
+ */
+struct xfs_attr_sf_hdr {       /* constant-structure header block */
+       __be16  totsize;        /* total bytes in shortform list */
+       __u8    count;          /* count of active entries */
+       __u8    padding;
+};
+
+struct xfs_attr_sf_entry {
+       __u8    namelen;        /* actual length of name (no NULL) */
+       __u8    valuelen;       /* actual length of value (no NULL) */
+       __u8    flags;          /* flags bits (XFS_ATTR_*) */
+       __u8    nameval[];      /* name & value bytes concatenated */
 };
 
 typedef struct xfs_attr_leaf_map {     /* RLE map of free bytes */
index d8405a8d3c14f929a4cd1cb416bf469484fc917d..f4569e18a8d0ea538b62491c64cd979e011fd446 100644 (file)
@@ -279,10 +279,9 @@ static uint16_t
 xfs_dfork_attr_shortform_size(
        struct xfs_dinode               *dip)
 {
-       struct xfs_attr_shortform       *atp =
-               (struct xfs_attr_shortform *)XFS_DFORK_APTR(dip);
+       struct xfs_attr_sf_hdr          *sf = XFS_DFORK_APTR(dip);
 
-       return be16_to_cpu(atp->hdr.totsize);
+       return be16_to_cpu(sf->totsize);
 }
 
 void
index d9c988c5ad692eb87a3a2767c0da4ca3d1192c6d..81885a6a028ed71ae3ae1b8f8e7fa2df9b51ca8a 100644 (file)
@@ -93,13 +93,13 @@ xfs_check_ondisk_structs(void)
        XFS_CHECK_OFFSET(xfs_attr_leaf_name_remote_t, namelen,  8);
        XFS_CHECK_OFFSET(xfs_attr_leaf_name_remote_t, name,     9);
        XFS_CHECK_STRUCT_SIZE(xfs_attr_leafblock_t,             32);
-       XFS_CHECK_STRUCT_SIZE(struct xfs_attr_shortform,        4);
-       XFS_CHECK_OFFSET(struct xfs_attr_shortform, hdr.totsize, 0);
-       XFS_CHECK_OFFSET(struct xfs_attr_shortform, hdr.count,   2);
-       XFS_CHECK_OFFSET(struct xfs_attr_shortform, list[0].namelen,    4);
-       XFS_CHECK_OFFSET(struct xfs_attr_shortform, list[0].valuelen,   5);
-       XFS_CHECK_OFFSET(struct xfs_attr_shortform, list[0].flags,      6);
-       XFS_CHECK_OFFSET(struct xfs_attr_shortform, list[0].nameval,    7);
+       XFS_CHECK_STRUCT_SIZE(struct xfs_attr_sf_hdr,           4);
+       XFS_CHECK_OFFSET(struct xfs_attr_sf_hdr, totsize,       0);
+       XFS_CHECK_OFFSET(struct xfs_attr_sf_hdr, count,         2);
+       XFS_CHECK_OFFSET(struct xfs_attr_sf_entry, namelen,     0);
+       XFS_CHECK_OFFSET(struct xfs_attr_sf_entry, valuelen,    1);
+       XFS_CHECK_OFFSET(struct xfs_attr_sf_entry, flags,       2);
+       XFS_CHECK_OFFSET(struct xfs_attr_sf_entry, nameval,     3);
        XFS_CHECK_STRUCT_SIZE(xfs_da_blkinfo_t,                 12);
        XFS_CHECK_STRUCT_SIZE(xfs_da_intnode_t,                 16);
        XFS_CHECK_STRUCT_SIZE(xfs_da_node_entry_t,              8);
index bac6fb2f01d88061b13fd4b3492116da1e468eda..83c7feb387147aae768af77b7e02c19e060e73ea 100644 (file)
@@ -528,23 +528,22 @@ xchk_xattr_check_sf(
 {
        struct xchk_xattr_buf           *ab = sc->buf;
        struct xfs_ifork                *ifp = &sc->ip->i_af;
-       struct xfs_attr_shortform       *sf = ifp->if_data;
-       struct xfs_attr_sf_entry        *sfe;
+       struct xfs_attr_sf_hdr          *sf = ifp->if_data;
+       struct xfs_attr_sf_entry        *sfe = xfs_attr_sf_firstentry(sf);
        struct xfs_attr_sf_entry        *next;
        unsigned char                   *end = ifp->if_data + ifp->if_bytes;
        int                             i;
        int                             error = 0;
 
        bitmap_zero(ab->usedmap, ifp->if_bytes);
-       xchk_xattr_set_map(sc, ab->usedmap, 0, sizeof(sf->hdr));
+       xchk_xattr_set_map(sc, ab->usedmap, 0, sizeof(*sf));
 
-       sfe = &sf->list[0];
        if ((unsigned char *)sfe > end) {
                xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0);
                return 0;
        }
 
-       for (i = 0; i < sf->hdr.count; i++) {
+       for (i = 0; i < sf->count; i++) {
                unsigned char           *name = sfe->nameval;
                unsigned char           *value = &sfe->nameval[sfe->namelen];
 
index 66949cc3d7cc9e20eadc58866eb613fb8a97359c..0ca62d59f84ad1089146ffc67581a1225de7e5ae 100644 (file)
@@ -760,7 +760,7 @@ xrep_dinode_check_afork(
        struct xfs_scrub                *sc,
        struct xfs_dinode               *dip)
 {
-       struct xfs_attr_shortform       *afork_ptr;
+       struct xfs_attr_sf_hdr          *afork_ptr;
        size_t                          attr_size;
        unsigned int                    afork_size;
 
@@ -778,7 +778,7 @@ xrep_dinode_check_afork(
                        return true;
 
                /* xattr structure cannot be larger than the fork */
-               attr_size = be16_to_cpu(afork_ptr->hdr.totsize);
+               attr_size = be16_to_cpu(afork_ptr->totsize);
                if (attr_size > afork_size)
                        return true;
 
index 8700b00e154c989bb45cb7392303567b796fa6fc..e368ad671e261e42159351316fc77cd5596742e4 100644 (file)
@@ -56,13 +56,13 @@ xfs_attr_shortform_list(
        struct xfs_attrlist_cursor_kern *cursor = &context->cursor;
        struct xfs_inode                *dp = context->dp;
        struct xfs_attr_sf_sort         *sbuf, *sbp;
-       struct xfs_attr_shortform       *sf = dp->i_af.if_data;
+       struct xfs_attr_sf_hdr          *sf = dp->i_af.if_data;
        struct xfs_attr_sf_entry        *sfe;
        int                             sbsize, nsbuf, count, i;
        int                             error = 0;
 
        ASSERT(sf != NULL);
-       if (!sf->hdr.count)
+       if (!sf->count)
                return 0;
 
        trace_xfs_attr_list_sf(context);
@@ -78,8 +78,8 @@ xfs_attr_shortform_list(
         */
        if (context->bufsize == 0 ||
            (XFS_ISRESET_CURSOR(cursor) &&
-            (dp->i_af.if_bytes + sf->hdr.count * 16) < context->bufsize)) {
-               for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
+            (dp->i_af.if_bytes + sf->count * 16) < context->bufsize)) {
+               for (i = 0, sfe = xfs_attr_sf_firstentry(sf); i < sf->count; i++) {
                        if (XFS_IS_CORRUPT(context->dp->i_mount,
                                           !xfs_attr_namecheck(sfe->nameval,
                                                               sfe->namelen)))
@@ -108,7 +108,7 @@ xfs_attr_shortform_list(
        /*
         * It didn't all fit, so we have to sort everything on hashval.
         */
-       sbsize = sf->hdr.count * sizeof(*sbuf);
+       sbsize = sf->count * sizeof(*sbuf);
        sbp = sbuf = kmem_alloc(sbsize, KM_NOFS);
 
        /*
@@ -116,7 +116,7 @@ xfs_attr_shortform_list(
         * the relevant info from only those that match into a buffer.
         */
        nsbuf = 0;
-       for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
+       for (i = 0, sfe = xfs_attr_sf_firstentry(sf); i < sf->count; i++) {
                if (unlikely(
                    ((char *)sfe < (char *)sf) ||
                    ((char *)sfe >= ((char *)sf + dp->i_af.if_bytes)))) {