summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_leaf.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-04-03 16:11:21 +1100
committerBen Myers <bpm@sgi.com>2013-04-27 11:58:16 -0500
commitcbc8adf89724b961c08b823d8bfb6dadbfa8733d (patch)
tree31a43d0f0445c69b446f3091ab9666d5934c115d /fs/xfs/xfs_dir2_leaf.c
parentf5f3d9b0161633e8943520e83df634ad540b3b7f (diff)
downloadblackbird-op-linux-cbc8adf89724b961c08b823d8bfb6dadbfa8733d.tar.gz
blackbird-op-linux-cbc8adf89724b961c08b823d8bfb6dadbfa8733d.zip
xfs: add CRC checking to dir2 free blocks
This addition follows the same pattern as the dir2 block CRCs, but with a few differences. The main difference is that the free block header is different between the v2 and v3 formats, so an "in-core" free block header has been added and _todisk/_from_disk functions used to abstract the differences in structure format from the code. This is similar to the on-disk superblock versus the in-core superblock setup. The in-core strucutre is populated when the buffer is read from disk, all the in memory checks and modifications are done on the in-core version of the structure which is written back to the buffer before the buffer is logged. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_dir2_leaf.c')
-rw-r--r--fs/xfs/xfs_dir2_leaf.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index ef163f06fd16..979735b0c76d 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -1881,6 +1881,7 @@ xfs_dir2_node_to_leaf(
xfs_mount_t *mp; /* filesystem mount point */
int rval; /* successful free trim? */
xfs_trans_t *tp; /* transaction pointer */
+ struct xfs_dir3_icfree_hdr freehdr;
/*
* There's more than a leaf level in the btree, so there must
@@ -1938,15 +1939,15 @@ xfs_dir2_node_to_leaf(
if (error)
return error;
free = fbp->b_addr;
- ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
- ASSERT(!free->hdr.firstdb);
+ xfs_dir3_free_hdr_from_disk(&freehdr, free);
+
+ ASSERT(!freehdr.firstdb);
/*
* Now see if the leafn and free data will fit in a leaf1.
* If not, release the buffer and give up.
*/
- if (xfs_dir2_leaf_size(&leaf->hdr, be32_to_cpu(free->hdr.nvalid)) >
- mp->m_dirblksize) {
+ if (xfs_dir2_leaf_size(&leaf->hdr, freehdr.nvalid) > mp->m_dirblksize) {
xfs_trans_brelse(tp, fbp);
return 0;
}
@@ -1967,12 +1968,12 @@ xfs_dir2_node_to_leaf(
* Set up the leaf tail from the freespace block.
*/
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
- ltp->bestcount = free->hdr.nvalid;
+ ltp->bestcount = cpu_to_be32(freehdr.nvalid);
/*
* Set up the leaf bests table.
*/
- memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests,
- be32_to_cpu(ltp->bestcount) * sizeof(xfs_dir2_data_off_t));
+ memcpy(xfs_dir2_leaf_bests_p(ltp), xfs_dir3_free_bests_p(mp, free),
+ freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
xfs_dir2_leaf_log_tail(tp, lbp);
xfs_dir2_leaf_check(dp, lbp);
OpenPOWER on IntegriCloud