aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_block.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_dir2_block.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_dir2_block.c')
-rw-r--r--fs/xfs/xfs_dir2_block.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 7ec87c20cbd2..d2e445f92ffb 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -1013,6 +1013,8 @@ xfs_dir2_leaf_to_block(
1013 __be16 *tagp; /* end of entry (tag) */ 1013 __be16 *tagp; /* end of entry (tag) */
1014 int to; /* block/leaf to index */ 1014 int to; /* block/leaf to index */
1015 xfs_trans_t *tp; /* transaction pointer */ 1015 xfs_trans_t *tp; /* transaction pointer */
1016 struct xfs_dir2_leaf_entry *ents;
1017 struct xfs_dir3_icleaf_hdr leafhdr;
1016 1018
1017 trace_xfs_dir2_leaf_to_block(args); 1019 trace_xfs_dir2_leaf_to_block(args);
1018 1020
@@ -1020,8 +1022,12 @@ xfs_dir2_leaf_to_block(
1020 tp = args->trans; 1022 tp = args->trans;
1021 mp = dp->i_mount; 1023 mp = dp->i_mount;
1022 leaf = lbp->b_addr; 1024 leaf = lbp->b_addr;
1023 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); 1025 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
1026 ents = xfs_dir3_leaf_ents_p(leaf);
1024 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1027 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1028
1029 ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC ||
1030 leafhdr.magic == XFS_DIR3_LEAF1_MAGIC);
1025 /* 1031 /*
1026 * If there are data blocks other than the first one, take this 1032 * If there are data blocks other than the first one, take this
1027 * opportunity to remove trailing empty data blocks that may have 1033 * opportunity to remove trailing empty data blocks that may have
@@ -1058,7 +1064,7 @@ xfs_dir2_leaf_to_block(
1058 * Size of the "leaf" area in the block. 1064 * Size of the "leaf" area in the block.
1059 */ 1065 */
1060 size = (uint)sizeof(xfs_dir2_block_tail_t) + 1066 size = (uint)sizeof(xfs_dir2_block_tail_t) +
1061 (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); 1067 (uint)sizeof(*lep) * (leafhdr.count - leafhdr.stale);
1062 /* 1068 /*
1063 * Look at the last data entry. 1069 * Look at the last data entry.
1064 */ 1070 */
@@ -1087,18 +1093,17 @@ xfs_dir2_leaf_to_block(
1087 * Initialize the block tail. 1093 * Initialize the block tail.
1088 */ 1094 */
1089 btp = xfs_dir2_block_tail_p(mp, hdr); 1095 btp = xfs_dir2_block_tail_p(mp, hdr);
1090 btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); 1096 btp->count = cpu_to_be32(leafhdr.count - leafhdr.stale);
1091 btp->stale = 0; 1097 btp->stale = 0;
1092 xfs_dir2_block_log_tail(tp, dbp); 1098 xfs_dir2_block_log_tail(tp, dbp);
1093 /* 1099 /*
1094 * Initialize the block leaf area. We compact out stale entries. 1100 * Initialize the block leaf area. We compact out stale entries.
1095 */ 1101 */
1096 lep = xfs_dir2_block_leaf_p(btp); 1102 lep = xfs_dir2_block_leaf_p(btp);
1097 for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { 1103 for (from = to = 0; from < leafhdr.count; from++) {
1098 if (leaf->ents[from].address == 1104 if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
1099 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
1100 continue; 1105 continue;
1101 lep[to++] = leaf->ents[from]; 1106 lep[to++] = ents[from];
1102 } 1107 }
1103 ASSERT(to == be32_to_cpu(btp->count)); 1108 ASSERT(to == be32_to_cpu(btp->count));
1104 xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1); 1109 xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1);