diff mbox series

[7/8] xfs: remove struct xfs_attr_shortform

Message ID 20231219120817.923421-8-hch@lst.de (mailing list archive)
State Superseded
Headers show
Series [1/8] xfs: make if_data a void pointer | expand

Commit Message

Christoph Hellwig Dec. 19, 2023, 12:08 p.m. UTC
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>
---
 fs/xfs/libxfs/xfs_attr.c       |  4 ++--
 fs/xfs/libxfs/xfs_attr_leaf.c  | 37 +++++++++++++++++-----------------
 fs/xfs/libxfs/xfs_attr_leaf.h  |  2 +-
 fs/xfs/libxfs/xfs_attr_sf.h    | 13 +++++++++---
 fs/xfs/libxfs/xfs_da_format.h  | 33 +++++++++++++++++-------------
 fs/xfs/libxfs/xfs_inode_fork.c |  5 ++---
 fs/xfs/libxfs/xfs_ondisk.h     | 14 ++++++-------
 fs/xfs/scrub/attr.c            |  9 ++++-----
 fs/xfs/scrub/inode_repair.c    |  4 ++--
 fs/xfs/xfs_attr_list.c         | 12 +++++------
 10 files changed, 71 insertions(+), 62 deletions(-)

Comments

Darrick J. Wong Dec. 19, 2023, 5:35 p.m. UTC | #1
On Tue, Dec 19, 2023 at 01:08:16PM +0100, Christoph Hellwig wrote:
> 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>

Looks good to me,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/libxfs/xfs_attr.c       |  4 ++--
>  fs/xfs/libxfs/xfs_attr_leaf.c  | 37 +++++++++++++++++-----------------
>  fs/xfs/libxfs/xfs_attr_leaf.h  |  2 +-
>  fs/xfs/libxfs/xfs_attr_sf.h    | 13 +++++++++---
>  fs/xfs/libxfs/xfs_da_format.h  | 33 +++++++++++++++++-------------
>  fs/xfs/libxfs/xfs_inode_fork.c |  5 ++---
>  fs/xfs/libxfs/xfs_ondisk.h     | 14 ++++++-------
>  fs/xfs/scrub/attr.c            |  9 ++++-----
>  fs/xfs/scrub/inode_repair.c    |  4 ++--
>  fs/xfs/xfs_attr_list.c         | 12 +++++------
>  10 files changed, 71 insertions(+), 62 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index d6173888ed0d56..846555de1cfccb 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -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);
>  }
>  
>  /*
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index 82e1830334160b..e1281ab413c832 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -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
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h
> index 35e668ae744fb1..9b9948639c0fb3 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.h
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.h
> @@ -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);
>  
> diff --git a/fs/xfs/libxfs/xfs_attr_sf.h b/fs/xfs/libxfs/xfs_attr_sf.h
> index a774d4d8776354..9abf7de95465f5 100644
> --- a/fs/xfs/libxfs/xfs_attr_sf.h
> +++ b/fs/xfs/libxfs/xfs_attr_sf.h
> @@ -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__ */
> diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h
> index f9015f88eca706..24f9d1461f9a6f 100644
> --- a/fs/xfs/libxfs/xfs_da_format.h
> +++ b/fs/xfs/libxfs/xfs_da_format.h
> @@ -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 */
> diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
> index d8405a8d3c14f9..f4569e18a8d0ea 100644
> --- a/fs/xfs/libxfs/xfs_inode_fork.c
> +++ b/fs/xfs/libxfs/xfs_inode_fork.c
> @@ -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
> diff --git a/fs/xfs/libxfs/xfs_ondisk.h b/fs/xfs/libxfs/xfs_ondisk.h
> index d9c988c5ad692e..81885a6a028ed7 100644
> --- a/fs/xfs/libxfs/xfs_ondisk.h
> +++ b/fs/xfs/libxfs/xfs_ondisk.h
> @@ -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);
> diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
> index bac6fb2f01d880..83c7feb387147a 100644
> --- a/fs/xfs/scrub/attr.c
> +++ b/fs/xfs/scrub/attr.c
> @@ -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];
>  
> diff --git a/fs/xfs/scrub/inode_repair.c b/fs/xfs/scrub/inode_repair.c
> index 66949cc3d7cc9e..0ca62d59f84ad1 100644
> --- a/fs/xfs/scrub/inode_repair.c
> +++ b/fs/xfs/scrub/inode_repair.c
> @@ -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;
>  
> diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
> index 8700b00e154c98..e368ad671e261e 100644
> --- a/fs/xfs/xfs_attr_list.c
> +++ b/fs/xfs/xfs_attr_list.c
> @@ -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)))) {
> -- 
> 2.39.2
> 
>
diff mbox series

Patch

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index d6173888ed0d56..846555de1cfccb 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -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);
 }
 
 /*
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 82e1830334160b..e1281ab413c832 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -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
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h
index 35e668ae744fb1..9b9948639c0fb3 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.h
+++ b/fs/xfs/libxfs/xfs_attr_leaf.h
@@ -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);
 
diff --git a/fs/xfs/libxfs/xfs_attr_sf.h b/fs/xfs/libxfs/xfs_attr_sf.h
index a774d4d8776354..9abf7de95465f5 100644
--- a/fs/xfs/libxfs/xfs_attr_sf.h
+++ b/fs/xfs/libxfs/xfs_attr_sf.h
@@ -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__ */
diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h
index f9015f88eca706..24f9d1461f9a6f 100644
--- a/fs/xfs/libxfs/xfs_da_format.h
+++ b/fs/xfs/libxfs/xfs_da_format.h
@@ -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 */
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index d8405a8d3c14f9..f4569e18a8d0ea 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -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
diff --git a/fs/xfs/libxfs/xfs_ondisk.h b/fs/xfs/libxfs/xfs_ondisk.h
index d9c988c5ad692e..81885a6a028ed7 100644
--- a/fs/xfs/libxfs/xfs_ondisk.h
+++ b/fs/xfs/libxfs/xfs_ondisk.h
@@ -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);
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index bac6fb2f01d880..83c7feb387147a 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -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];
 
diff --git a/fs/xfs/scrub/inode_repair.c b/fs/xfs/scrub/inode_repair.c
index 66949cc3d7cc9e..0ca62d59f84ad1 100644
--- a/fs/xfs/scrub/inode_repair.c
+++ b/fs/xfs/scrub/inode_repair.c
@@ -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;
 
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index 8700b00e154c98..e368ad671e261e 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -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)))) {