xfs
[Top] [All Lists]

[PATCH 13/22] libxfs: ensure btree root split sets blkno correctly

To: xfs@xxxxxxxxxxx
Subject: [PATCH 13/22] libxfs: ensure btree root split sets blkno correctly
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Wed, 12 Jun 2013 20:36:25 +1000
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1371033394-26006-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1371033394-26006-1-git-send-email-david@xxxxxxxxxxxxx>
From: Dave Chinner <dchinner@xxxxxxxxxx>

For CRC enabled filesystems, the BMBT is rooted in an inode, so it
passes through a difference code path on root splits to the
freespace and inode btrees. The inode based btree root has a
corruption problem on split - it's the same problem we saw in the
directory/attr code where headers are memcpy()d from one block to
another without updating the self describing metadata.

Simple fix - when copying the header out of the root block, make
sure the block number is updated correctly.

Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
---
 libxfs/xfs_btree.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c
index b11131c..3ac3330 100644
--- a/libxfs/xfs_btree.c
+++ b/libxfs/xfs_btree.c
@@ -2487,7 +2487,17 @@ xfs_btree_new_iroot(
        if (error)
                goto error0;
 
+       /*
+        * we can't just memcpy() the root in for CRC enabled btree blocks.
+        * In that case have to also ensure the blkno remains correct
+        */
        memcpy(cblock, block, xfs_btree_block_len(cur));
+       if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) {
+               if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+                       cblock->bb_u.l.bb_blkno = cpu_to_be64(cbp->b_bn);
+               else
+                       cblock->bb_u.s.bb_blkno = cpu_to_be64(cbp->b_bn);
+       }
 
        be16_add_cpu(&block->bb_level, 1);
        xfs_btree_set_numrecs(block, 1);
-- 
1.7.10.4

<Prev in Thread] Current Thread [Next in Thread>