Skip to content

Commit

Permalink
xfs: recalculate leaf entry pointer after compacting a dir2 block
Browse files Browse the repository at this point in the history
Dave Jones hit this assert when doing a compile on recent git, with
CONFIG_XFS_DEBUG enabled:

XFS: Assertion failed: (char *)dup - (char *)hdr == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)), file: fs/xfs/xfs_dir2_data.c, line: 828

Upon further digging, the tag found by xfs_dir2_data_unused_tag_p(dup)
contained "2" and not the proper offset, and I found that this value was
changed after the memmoves under "Use a stale leaf for our new entry."
in xfs_dir2_block_addname(), i.e.

                        memmove(&blp[mid + 1], &blp[mid],
                                (highstale - mid) * sizeof(*blp));

overwrote it.

What has happened is that the previous call to xfs_dir2_block_compact()
has rearranged things; it changes btp->count as well as the
blp array.  So after we make that call, we must recalculate the
proper pointer to the leaf entries by making another call to
xfs_dir2_block_leaf_p().

Dave provided a metadump image which led to a simple reproducer
(create a particular filename in the affected directory) and this
resolves the testcase as well as the bug on his live system.

Thanks also to dchinner for looking at this one with me.

Signed-off-by: Eric Sandeen <[email protected]>
Tested-by: Dave Jones <[email protected]>
Reviewed-by: Dave Chinner <[email protected]>
Reviewed-by: Mark Tinguely <[email protected]>
Signed-off-by: Ben Myers <[email protected]>
  • Loading branch information
Eric Sandeen authored and Ben Myers committed Jan 16, 2013
1 parent ab7eac2 commit 37f1356
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions fs/xfs/xfs_dir2_block.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,12 @@ xfs_dir2_block_addname(
/*
* If need to compact the leaf entries, do it now.
*/
if (compact)
if (compact) {
xfs_dir2_block_compact(tp, bp, hdr, btp, blp, &needlog,
&lfloghigh, &lfloglow);
else if (btp->stale) {
/* recalculate blp post-compaction */
blp = xfs_dir2_block_leaf_p(btp);
} else if (btp->stale) {
/*
* Set leaf logging boundaries to impossible state.
* For the no-stale case they're set explicitly.
Expand Down

0 comments on commit 37f1356

Please sign in to comment.