]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
libxfs: ensure btree root split sets blkno correctly
authorDave Chinner <dchinner@redhat.com>
Wed, 4 Sep 2013 22:05:09 +0000 (22:05 +0000)
committerRich Johnston <rjohnston@sgi.com>
Mon, 16 Sep 2013 20:14:40 +0000 (15:14 -0500)
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@redhat.com>
Review-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Rich Johnston <rjohnston@sgi.com>
libxfs/xfs_btree.c

index b11131c1e8e6a7bb6d2c047a21b5a075500057c6..3ac333074f2b8f302992b2a92e9af7aec8f872e8 100644 (file)
@@ -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);