@@ -591,7 +591,7 @@ struct xfs_attr_shortform {
591591 uint8_t valuelen ; /* actual length of value (no NULL) */
592592 uint8_t flags ; /* flags bits (see xfs_attr_leaf.h) */
593593 uint8_t nameval []; /* name & value bytes concatenated */
594- } list [1 ]; /* variable sized array */
594+ } list []; /* variable sized array */
595595};
596596
597597typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */
@@ -620,19 +620,29 @@ typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */
620620typedef struct xfs_attr_leaf_name_local {
621621 __be16 valuelen ; /* number of bytes in value */
622622 __u8 namelen ; /* length of name bytes */
623- __u8 nameval [1 ]; /* name/value bytes */
623+ /*
624+ * In Linux 6.5 this flex array was converted from nameval[1] to
625+ * nameval[]. Be very careful here about extra padding at the end;
626+ * see xfs_attr_leaf_entsize_local() for details.
627+ */
628+ __u8 nameval []; /* name/value bytes */
624629} xfs_attr_leaf_name_local_t ;
625630
626631typedef struct xfs_attr_leaf_name_remote {
627632 __be32 valueblk ; /* block number of value bytes */
628633 __be32 valuelen ; /* number of bytes in value */
629634 __u8 namelen ; /* length of name bytes */
630- __u8 name [1 ]; /* name bytes */
635+ /*
636+ * In Linux 6.5 this flex array was converted from name[1] to name[].
637+ * Be very careful here about extra padding at the end; see
638+ * xfs_attr_leaf_entsize_remote() for details.
639+ */
640+ __u8 name []; /* name bytes */
631641} xfs_attr_leaf_name_remote_t ;
632642
633643typedef struct xfs_attr_leafblock {
634644 xfs_attr_leaf_hdr_t hdr ; /* constant-structure header block */
635- xfs_attr_leaf_entry_t entries [1 ]; /* sorted on key, not name */
645+ xfs_attr_leaf_entry_t entries []; /* sorted on key, not name */
636646 /*
637647 * The rest of the block contains the following structures after the
638648 * leaf entries, growing from the bottom up. The variables are never
@@ -664,7 +674,7 @@ struct xfs_attr3_leaf_hdr {
664674
665675struct xfs_attr3_leafblock {
666676 struct xfs_attr3_leaf_hdr hdr ;
667- struct xfs_attr_leaf_entry entries [1 ];
677+ struct xfs_attr_leaf_entry entries [];
668678
669679 /*
670680 * The rest of the block contains the following structures after the
@@ -747,14 +757,61 @@ xfs_attr3_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx)
747757 */
748758static inline int xfs_attr_leaf_entsize_remote (int nlen )
749759{
750- return round_up (sizeof (struct xfs_attr_leaf_name_remote ) - 1 +
751- nlen , XFS_ATTR_LEAF_NAME_ALIGN );
760+ /*
761+ * Prior to Linux 6.5, struct xfs_attr_leaf_name_remote ended with
762+ * name[1], which was used as a flexarray. The layout of this struct
763+ * is 9 bytes of fixed-length fields followed by a __u8 flex array at
764+ * offset 9.
765+ *
766+ * On most architectures, struct xfs_attr_leaf_name_remote had two
767+ * bytes of implicit padding at the end of the struct to make the
768+ * struct length 12. After converting name[1] to name[], there are
769+ * three implicit padding bytes and the struct size remains 12.
770+ * However, there are compiler configurations that do not add implicit
771+ * padding at all (m68k) and have been broken for years.
772+ *
773+ * This entsize computation historically added (the xattr name length)
774+ * to (the padded struct length - 1) and rounded that sum up to the
775+ * nearest multiple of 4 (NAME_ALIGN). IOWs, round_up(11 + nlen, 4).
776+ * This is encoded in the ondisk format, so we cannot change this.
777+ *
778+ * Compute the entsize from offsetof of the flexarray and manually
779+ * adding bytes for the implicit padding.
780+ */
781+ const size_t remotesize =
782+ offsetof(struct xfs_attr_leaf_name_remote , name ) + 2 ;
783+
784+ return round_up (remotesize + nlen , XFS_ATTR_LEAF_NAME_ALIGN );
752785}
753786
754787static inline int xfs_attr_leaf_entsize_local (int nlen , int vlen )
755788{
756- return round_up (sizeof (struct xfs_attr_leaf_name_local ) - 1 +
757- nlen + vlen , XFS_ATTR_LEAF_NAME_ALIGN );
789+ /*
790+ * Prior to Linux 6.5, struct xfs_attr_leaf_name_local ended with
791+ * nameval[1], which was used as a flexarray. The layout of this
792+ * struct is 3 bytes of fixed-length fields followed by a __u8 flex
793+ * array at offset 3.
794+ *
795+ * struct xfs_attr_leaf_name_local had zero bytes of implicit padding
796+ * at the end of the struct to make the struct length 4. On most
797+ * architectures, after converting nameval[1] to nameval[], there is
798+ * one implicit padding byte and the struct size remains 4. However,
799+ * there are compiler configurations that do not add implicit padding
800+ * at all (m68k) and would break.
801+ *
802+ * This entsize computation historically added (the xattr name and
803+ * value length) to (the padded struct length - 1) and rounded that sum
804+ * up to the nearest multiple of 4 (NAME_ALIGN). IOWs, the formula is
805+ * round_up(3 + nlen + vlen, 4). This is encoded in the ondisk format,
806+ * so we cannot change this.
807+ *
808+ * Compute the entsize from offsetof of the flexarray and manually
809+ * adding bytes for the implicit padding.
810+ */
811+ const size_t localsize =
812+ offsetof(struct xfs_attr_leaf_name_local , nameval );
813+
814+ return round_up (localsize + nlen + vlen , XFS_ATTR_LEAF_NAME_ALIGN );
758815}
759816
760817static inline int xfs_attr_leaf_entsize_local_max (int bsize )
0 commit comments