aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_da_btree.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-04-11 17:30:21 -0400
committerBen Myers <bpm@sgi.com>2013-04-27 13:19:53 -0400
commit24df33b45ecf5ca413ef1530e0aca5506d9be2cc (patch)
treec4f3ca2bfdd25b09706ad3d4ccd4f45fff6710a9 /fs/xfs/xfs_da_btree.c
parent33363feed1614def83d0a6870051f0a7828cd61b (diff)
xfs: add CRC checking to dir2 leaf blocks
This addition follows the same pattern as the dir2 block CRCs. Seeing as both LEAF1 and LEAFN types need to changed at the same time, this is a pretty large amount of change. leaf block headers need to be abstracted away from the on-disk structures (struct xfs_dir3_icleaf_hdr), as do the base leaf entry locations. This header abstract allows the in-core header and leaf entry location to be passed around instead of the leaf block itself. This saves a lot of converting individual variables from on-disk format to host format where they are used, so there's a good chance that the compiler will be able to produce much more optimal code as it's not having to byteswap variables all over the place. 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_da_btree.c')
-rw-r--r--fs/xfs/xfs_da_btree.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 4d7696a02418..2f23b14e3adf 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -139,7 +139,8 @@ xfs_da_node_read_verify(
139 bp->b_ops->verify_read(bp); 139 bp->b_ops->verify_read(bp);
140 return; 140 return;
141 case XFS_DIR2_LEAFN_MAGIC: 141 case XFS_DIR2_LEAFN_MAGIC:
142 bp->b_ops = &xfs_dir2_leafn_buf_ops; 142 case XFS_DIR3_LEAFN_MAGIC:
143 bp->b_ops = &xfs_dir3_leafn_buf_ops;
143 bp->b_ops->verify_read(bp); 144 bp->b_ops->verify_read(bp);
144 return; 145 return;
145 default: 146 default:
@@ -396,11 +397,18 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
396 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - 397 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
397 (char *)oldroot); 398 (char *)oldroot);
398 } else { 399 } else {
399 ASSERT(oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 400 struct xfs_dir3_icleaf_hdr leafhdr;
401 struct xfs_dir2_leaf_entry *ents;
402
400 leaf = (xfs_dir2_leaf_t *)oldroot; 403 leaf = (xfs_dir2_leaf_t *)oldroot;
401 size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - 404 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
402 (char *)leaf); 405 ents = xfs_dir3_leaf_ents_p(leaf);
406
407 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
408 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
409 size = (int)((char *)&ents[leafhdr.count] - (char *)leaf);
403 } 410 }
411 /* XXX: can't just copy CRC headers from one block to another */
404 memcpy(node, oldroot, size); 412 memcpy(node, oldroot, size);
405 xfs_trans_log_buf(tp, bp, 0, size - 1); 413 xfs_trans_log_buf(tp, bp, 0, size - 1);
406 414
@@ -424,7 +432,8 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
424 node->hdr.count = cpu_to_be16(2); 432 node->hdr.count = cpu_to_be16(2);
425 433
426#ifdef DEBUG 434#ifdef DEBUG
427 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)) { 435 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
436 oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
428 ASSERT(blk1->blkno >= mp->m_dirleafblk && 437 ASSERT(blk1->blkno >= mp->m_dirleafblk &&
429 blk1->blkno < mp->m_dirfreeblk); 438 blk1->blkno < mp->m_dirfreeblk);
430 ASSERT(blk2->blkno >= mp->m_dirleafblk && 439 ASSERT(blk2->blkno >= mp->m_dirleafblk &&
@@ -782,6 +791,7 @@ xfs_da_blkinfo_onlychild_validate(struct xfs_da_blkinfo *blkinfo, __u16 level)
782 791
783 if (level == 1) { 792 if (level == 1) {
784 ASSERT(magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 793 ASSERT(magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
794 magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) ||
785 magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 795 magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
786 } else 796 } else
787 ASSERT(magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); 797 ASSERT(magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
@@ -1565,6 +1575,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1565 info = blk->bp->b_addr; 1575 info = blk->bp->b_addr;
1566 ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || 1576 ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) ||
1567 info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 1577 info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1578 info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) ||
1568 info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); 1579 info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1569 blk->magic = be16_to_cpu(info->magic); 1580 blk->magic = be16_to_cpu(info->magic);
1570 if (blk->magic == XFS_DA_NODE_MAGIC) { 1581 if (blk->magic == XFS_DA_NODE_MAGIC) {
@@ -1584,12 +1595,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1584 NULL); 1595 NULL);
1585 break; 1596 break;
1586 case XFS_DIR2_LEAFN_MAGIC: 1597 case XFS_DIR2_LEAFN_MAGIC:
1598 case XFS_DIR3_LEAFN_MAGIC:
1599 blk->magic = XFS_DIR2_LEAFN_MAGIC;
1587 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, 1600 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,
1588 NULL); 1601 NULL);
1589 break; 1602 break;
1590 default: 1603 default:
1591 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || 1604 ASSERT(0);
1592 blk->magic == XFS_DIR2_LEAFN_MAGIC);
1593 break; 1605 break;
1594 } 1606 }
1595 } 1607 }
@@ -1833,10 +1845,16 @@ xfs_da_swap_lastblock(
1833 /* 1845 /*
1834 * Get values from the moved block. 1846 * Get values from the moved block.
1835 */ 1847 */
1836 if (dead_info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)) { 1848 if (dead_info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1849 dead_info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
1850 struct xfs_dir3_icleaf_hdr leafhdr;
1851 struct xfs_dir2_leaf_entry *ents;
1852
1837 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; 1853 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
1854 xfs_dir3_leaf_hdr_from_disk(&leafhdr, dead_leaf2);
1855 ents = xfs_dir3_leaf_ents_p(dead_leaf2);
1838 dead_level = 0; 1856 dead_level = 0;
1839 dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); 1857 dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval);
1840 } else { 1858 } else {
1841 ASSERT(dead_info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); 1859 ASSERT(dead_info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
1842 dead_node = (xfs_da_intnode_t *)dead_info; 1860 dead_node = (xfs_da_intnode_t *)dead_info;
@@ -2281,10 +2299,17 @@ xfs_da_read_buf(
2281 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && 2299 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
2282 (magic != XFS_ATTR_LEAF_MAGIC) && 2300 (magic != XFS_ATTR_LEAF_MAGIC) &&
2283 (magic != XFS_DIR2_LEAF1_MAGIC) && 2301 (magic != XFS_DIR2_LEAF1_MAGIC) &&
2302 (magic != XFS_DIR3_LEAF1_MAGIC) &&
2284 (magic != XFS_DIR2_LEAFN_MAGIC) && 2303 (magic != XFS_DIR2_LEAFN_MAGIC) &&
2304 (magic != XFS_DIR3_LEAFN_MAGIC) &&
2285 (magic1 != XFS_DIR2_BLOCK_MAGIC) && 2305 (magic1 != XFS_DIR2_BLOCK_MAGIC) &&
2306 (magic1 != XFS_DIR3_BLOCK_MAGIC) &&
2286 (magic1 != XFS_DIR2_DATA_MAGIC) && 2307 (magic1 != XFS_DIR2_DATA_MAGIC) &&
2287 (free->hdr.magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC)), 2308 (magic1 != XFS_DIR3_DATA_MAGIC) &&
2309 (free->hdr.magic !=
2310 cpu_to_be32(XFS_DIR2_FREE_MAGIC)) &&
2311 (free->hdr.magic !=
2312 cpu_to_be32(XFS_DIR3_FREE_MAGIC)),
2288 mp, XFS_ERRTAG_DA_READ_BUF, 2313 mp, XFS_ERRTAG_DA_READ_BUF,
2289 XFS_RANDOM_DA_READ_BUF))) { 2314 XFS_RANDOM_DA_READ_BUF))) {
2290 trace_xfs_da_btree_corrupt(bp, _RET_IP_); 2315 trace_xfs_da_btree_corrupt(bp, _RET_IP_);