Re: [PATCH] (and bad attr2 bug) - pack xfs_sb_t for 64-bit arches

Eric Sandeen
2006-11-21T04:03:17Z

Eric Sandeen wrote:

> Eric Sandeen wrote:
>
>> ugh. it's broken on x86 too, so it's not just the alignment/padding,
>>
>> although that should be fixed for cross-arch mounts.
>>
>> -Eric
>>
>>
> here's a testcase to corrupt it FWIW.
>
>
Ok, with expert collaboration from Russell, Barry, Tim,
Nathan, David, et al, how about this:

For btree dirs, we need a different calculation for the space
used in di_u, to set the minimum threshold for the fork offset...

This fixes my testcase, but as Tim points out -now- we need to compact
the btree ptrs, if we return (and use) an offset < current forkoff...

whee....

-Eric

Index: linux-2.6.18/fs/xfs.orig/xfs_attr_leaf.c
===================================================================
--- linux-2.6.18.orig/fs/xfs.orig/xfs_attr_leaf.c
+++ linux-2.6.18/fs/xfs.orig/xfs_attr_leaf.c
@@ -116,6 +116,7 @@ xfs_attr_shortform_bytesfit(xfs_inode_t
int minforkoff; /* lower limit on valid forkoff locations */
int maxforkoff; /* upper limit on valid forkoff locations */
xfs_mount_t *mp = dp->i_mount;
+ int dsize = 0;

offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */

@@ -134,8 +135,21 @@ xfs_attr_shortform_bytesfit(xfs_inode_t
return 0;
}

+ switch (dp->i_d.di_format) {
+ case XFS_DINODE_FMT_LOCAL:
+ case XFS_DINODE_FMT_EXTENTS:
+ dsize = dp->i_df.if_bytes;
+ break;
+ case XFS_DINODE_FMT_BTREE:
+ dsize = XFS_BMDR_SPACE_CALC(
+ XFS_BMAP_BROOT_NUMRECS(dp->i_df.if_broot));
+ break;
+ default:
+ /* should bail, unknown format, .... */
+ }
+
/* data fork btree root can have at least this many key/ptr pairs */
- minforkoff = MAX(dp->i_df.if_bytes, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
+ minforkoff = MAX(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
minforkoff = roundup(minforkoff, 8) >> 3;

/* attr fork btree root can have at least this many key/ptr pairs */