aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-04-03 01:11:29 -0400
committerBen Myers <bpm@sgi.com>2013-04-27 14:01:06 -0400
commitd75afeb3d302019527331520a2632b6614425b40 (patch)
tree181dec415cdae00398086764a6229d115114354d
parentd2e448d5fdebdcda93ed171339a3d864f65c227e (diff)
xfs: add buffer types to directory and attribute buffers
Add buffer types to the buffer log items so that log recovery can validate the buffers and calculate CRCs correctly after the buffers are recovered. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
-rw-r--r--fs/xfs/xfs_attr_leaf.c9
-rw-r--r--fs/xfs/xfs_attr_remote.h2
-rw-r--r--fs/xfs/xfs_buf_item.h18
-rw-r--r--fs/xfs/xfs_da_btree.c46
-rw-r--r--fs/xfs/xfs_da_btree.h2
-rw-r--r--fs/xfs/xfs_dir2_block.c12
-rw-r--r--fs/xfs/xfs_dir2_data.c8
-rw-r--r--fs/xfs/xfs_dir2_leaf.c26
-rw-r--r--fs/xfs/xfs_dir2_node.c15
-rw-r--r--fs/xfs/xfs_dir2_priv.h2
-rw-r--r--fs/xfs/xfs_log_recover.c254
-rw-r--r--fs/xfs/xfs_trans.h2
-rw-r--r--fs/xfs/xfs_trans_buf.c17
13 files changed, 323 insertions, 90 deletions
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 287c8089b705..92cda03d1c01 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -271,8 +271,13 @@ xfs_attr3_leaf_read(
271 xfs_daddr_t mappedbno, 271 xfs_daddr_t mappedbno,
272 struct xfs_buf **bpp) 272 struct xfs_buf **bpp)
273{ 273{
274 return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp, 274 int err;
275
276 err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
275 XFS_ATTR_FORK, &xfs_attr3_leaf_buf_ops); 277 XFS_ATTR_FORK, &xfs_attr3_leaf_buf_ops);
278 if (!err && tp)
279 xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_ATTR_LEAF_BUF);
280 return err;
276} 281}
277 282
278/*======================================================================== 283/*========================================================================
@@ -1078,6 +1083,7 @@ xfs_attr3_leaf_to_node(
1078 goto out; 1083 goto out;
1079 1084
1080 /* copy leaf to new buffer, update identifiers */ 1085 /* copy leaf to new buffer, update identifiers */
1086 xfs_trans_buf_set_type(args->trans, bp2, XFS_BLF_ATTR_LEAF_BUF);
1081 bp2->b_ops = bp1->b_ops; 1087 bp2->b_ops = bp1->b_ops;
1082 memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(mp)); 1088 memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(mp));
1083 if (xfs_sb_version_hascrc(&mp->m_sb)) { 1089 if (xfs_sb_version_hascrc(&mp->m_sb)) {
@@ -1140,6 +1146,7 @@ xfs_attr3_leaf_create(
1140 if (error) 1146 if (error)
1141 return error; 1147 return error;
1142 bp->b_ops = &xfs_attr3_leaf_buf_ops; 1148 bp->b_ops = &xfs_attr3_leaf_buf_ops;
1149 xfs_trans_buf_set_type(args->trans, bp, XFS_BLF_ATTR_LEAF_BUF);
1143 leaf = bp->b_addr; 1150 leaf = bp->b_addr;
1144 memset(leaf, 0, XFS_LBSIZE(mp)); 1151 memset(leaf, 0, XFS_LBSIZE(mp));
1145 1152
diff --git a/fs/xfs/xfs_attr_remote.h b/fs/xfs/xfs_attr_remote.h
index 0ca8d9a1fa03..c7cca60a062a 100644
--- a/fs/xfs/xfs_attr_remote.h
+++ b/fs/xfs/xfs_attr_remote.h
@@ -37,6 +37,8 @@ struct xfs_attr3_rmt_hdr {
37 ((bufsize) - (xfs_sb_version_hascrc(&(mp)->m_sb) ? \ 37 ((bufsize) - (xfs_sb_version_hascrc(&(mp)->m_sb) ? \
38 sizeof(struct xfs_attr3_rmt_hdr) : 0)) 38 sizeof(struct xfs_attr3_rmt_hdr) : 0))
39 39
40extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops;
41
40int xfs_attr_rmtval_get(struct xfs_da_args *args); 42int xfs_attr_rmtval_get(struct xfs_da_args *args);
41int xfs_attr_rmtval_set(struct xfs_da_args *args); 43int xfs_attr_rmtval_set(struct xfs_da_args *args);
42int xfs_attr_rmtval_remove(struct xfs_da_args *args); 44int xfs_attr_rmtval_remove(struct xfs_da_args *args);
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h
index 09cab4ed1065..640adcfa4143 100644
--- a/fs/xfs/xfs_buf_item.h
+++ b/fs/xfs/xfs_buf_item.h
@@ -50,6 +50,14 @@ extern kmem_zone_t *xfs_buf_item_zone;
50#define XFS_BLF_AGI_BUF (1<<8) 50#define XFS_BLF_AGI_BUF (1<<8)
51#define XFS_BLF_DINO_BUF (1<<9) 51#define XFS_BLF_DINO_BUF (1<<9)
52#define XFS_BLF_SYMLINK_BUF (1<<10) 52#define XFS_BLF_SYMLINK_BUF (1<<10)
53#define XFS_BLF_DIR_BLOCK_BUF (1<<11)
54#define XFS_BLF_DIR_DATA_BUF (1<<12)
55#define XFS_BLF_DIR_FREE_BUF (1<<13)
56#define XFS_BLF_DIR_LEAF1_BUF (1<<14)
57#define XFS_BLF_DIR_LEAFN_BUF (1<<15)
58#define XFS_BLF_DA_NODE_BUF (1<<16)
59#define XFS_BLF_ATTR_LEAF_BUF (1<<17)
60#define XFS_BLF_ATTR_RMT_BUF (1<<18)
53 61
54#define XFS_BLF_TYPE_MASK \ 62#define XFS_BLF_TYPE_MASK \
55 (XFS_BLF_UDQUOT_BUF | \ 63 (XFS_BLF_UDQUOT_BUF | \
@@ -60,7 +68,15 @@ extern kmem_zone_t *xfs_buf_item_zone;
60 XFS_BLF_AGFL_BUF | \ 68 XFS_BLF_AGFL_BUF | \
61 XFS_BLF_AGI_BUF | \ 69 XFS_BLF_AGI_BUF | \
62 XFS_BLF_DINO_BUF | \ 70 XFS_BLF_DINO_BUF | \
63 XFS_BLF_SYMLINK_BUF) 71 XFS_BLF_SYMLINK_BUF | \
72 XFS_BLF_DIR_BLOCK_BUF | \
73 XFS_BLF_DIR_DATA_BUF | \
74 XFS_BLF_DIR_FREE_BUF | \
75 XFS_BLF_DIR_LEAF1_BUF | \
76 XFS_BLF_DIR_LEAFN_BUF | \
77 XFS_BLF_DA_NODE_BUF | \
78 XFS_BLF_ATTR_LEAF_BUF | \
79 XFS_BLF_ATTR_RMT_BUF)
64 80
65#define XFS_BLF_CHUNK 128 81#define XFS_BLF_CHUNK 128
66#define XFS_BLF_SHIFT 7 82#define XFS_BLF_SHIFT 7
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 779ecdcdbe02..5aebd9bd44d1 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -292,7 +292,6 @@ const struct xfs_buf_ops xfs_da3_node_buf_ops = {
292 .verify_write = xfs_da3_node_write_verify, 292 .verify_write = xfs_da3_node_write_verify,
293}; 293};
294 294
295
296int 295int
297xfs_da3_node_read( 296xfs_da3_node_read(
298 struct xfs_trans *tp, 297 struct xfs_trans *tp,
@@ -302,8 +301,35 @@ xfs_da3_node_read(
302 struct xfs_buf **bpp, 301 struct xfs_buf **bpp,
303 int which_fork) 302 int which_fork)
304{ 303{
305 return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp, 304 int err;
305
306 err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
306 which_fork, &xfs_da3_node_buf_ops); 307 which_fork, &xfs_da3_node_buf_ops);
308 if (!err && tp) {
309 struct xfs_da_blkinfo *info = (*bpp)->b_addr;
310 int type;
311
312 switch (be16_to_cpu(info->magic)) {
313 case XFS_DA3_NODE_MAGIC:
314 case XFS_DA_NODE_MAGIC:
315 type = XFS_BLF_DA_NODE_BUF;
316 break;
317 case XFS_ATTR_LEAF_MAGIC:
318 case XFS_ATTR3_LEAF_MAGIC:
319 type = XFS_BLF_ATTR_LEAF_BUF;
320 break;
321 case XFS_DIR2_LEAFN_MAGIC:
322 case XFS_DIR3_LEAFN_MAGIC:
323 type = XFS_BLF_DIR_LEAFN_BUF;
324 break;
325 default:
326 type = 0;
327 ASSERT(0);
328 break;
329 }
330 xfs_trans_buf_set_type(tp, *bpp, type);
331 }
332 return err;
307} 333}
308 334
309/*======================================================================== 335/*========================================================================
@@ -334,6 +360,8 @@ xfs_da3_node_create(
334 error = xfs_da_get_buf(tp, args->dp, blkno, -1, &bp, whichfork); 360 error = xfs_da_get_buf(tp, args->dp, blkno, -1, &bp, whichfork);
335 if (error) 361 if (error)
336 return(error); 362 return(error);
363 bp->b_ops = &xfs_da3_node_buf_ops;
364 xfs_trans_buf_set_type(tp, bp, XFS_BLF_DA_NODE_BUF);
337 node = bp->b_addr; 365 node = bp->b_addr;
338 366
339 if (xfs_sb_version_hascrc(&mp->m_sb)) { 367 if (xfs_sb_version_hascrc(&mp->m_sb)) {
@@ -352,7 +380,6 @@ xfs_da3_node_create(
352 xfs_trans_log_buf(tp, bp, 380 xfs_trans_log_buf(tp, bp,
353 XFS_DA_LOGRANGE(node, &node->hdr, xfs_da3_node_hdr_size(node))); 381 XFS_DA_LOGRANGE(node, &node->hdr, xfs_da3_node_hdr_size(node)));
354 382
355 bp->b_ops = &xfs_da3_node_buf_ops;
356 *bpp = bp; 383 *bpp = bp;
357 return(0); 384 return(0);
358} 385}
@@ -565,6 +592,12 @@ xfs_da3_root_split(
565 btree = xfs_da3_node_tree_p(oldroot); 592 btree = xfs_da3_node_tree_p(oldroot);
566 size = (int)((char *)&btree[nodehdr.count] - (char *)oldroot); 593 size = (int)((char *)&btree[nodehdr.count] - (char *)oldroot);
567 level = nodehdr.level; 594 level = nodehdr.level;
595
596 /*
597 * we are about to copy oldroot to bp, so set up the type
598 * of bp while we know exactly what it will be.
599 */
600 xfs_trans_buf_set_type(tp, bp, XFS_BLF_DA_NODE_BUF);
568 } else { 601 } else {
569 struct xfs_dir3_icleaf_hdr leafhdr; 602 struct xfs_dir3_icleaf_hdr leafhdr;
570 struct xfs_dir2_leaf_entry *ents; 603 struct xfs_dir2_leaf_entry *ents;
@@ -577,6 +610,12 @@ xfs_da3_root_split(
577 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); 610 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
578 size = (int)((char *)&ents[leafhdr.count] - (char *)leaf); 611 size = (int)((char *)&ents[leafhdr.count] - (char *)leaf);
579 level = 0; 612 level = 0;
613
614 /*
615 * we are about to copy oldroot to bp, so set up the type
616 * of bp while we know exactly what it will be.
617 */
618 xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_LEAFN_BUF);
580 } 619 }
581 620
582 /* 621 /*
@@ -1092,6 +1131,7 @@ xfs_da3_root_join(
1092 */ 1131 */
1093 memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize); 1132 memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize);
1094 root_blk->bp->b_ops = bp->b_ops; 1133 root_blk->bp->b_ops = bp->b_ops;
1134 xfs_trans_buf_copy_type(root_blk->bp, bp);
1095 if (oldroothdr.magic == XFS_DA3_NODE_MAGIC) { 1135 if (oldroothdr.magic == XFS_DA3_NODE_MAGIC) {
1096 struct xfs_da3_blkinfo *da3 = root_blk->bp->b_addr; 1136 struct xfs_da3_blkinfo *da3 = root_blk->bp->b_addr;
1097 da3->blkno = cpu_to_be64(root_blk->bp->b_bn); 1137 da3->blkno = cpu_to_be64(root_blk->bp->b_bn);
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 0e8182c5210b..6fb3371c63cf 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -301,6 +301,8 @@ int xfs_da3_node_read(struct xfs_trans *tp, struct xfs_inode *dp,
301 xfs_dablk_t bno, xfs_daddr_t mappedbno, 301 xfs_dablk_t bno, xfs_daddr_t mappedbno,
302 struct xfs_buf **bpp, int which_fork); 302 struct xfs_buf **bpp, int which_fork);
303 303
304extern const struct xfs_buf_ops xfs_da3_node_buf_ops;
305
304/* 306/*
305 * Utility routines. 307 * Utility routines.
306 */ 308 */
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index d2e445f92ffb..58816ecdbba5 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -132,20 +132,26 @@ xfs_dir3_block_read(
132 struct xfs_buf **bpp) 132 struct xfs_buf **bpp)
133{ 133{
134 struct xfs_mount *mp = dp->i_mount; 134 struct xfs_mount *mp = dp->i_mount;
135 int err;
135 136
136 return xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp, 137 err = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp,
137 XFS_DATA_FORK, &xfs_dir3_block_buf_ops); 138 XFS_DATA_FORK, &xfs_dir3_block_buf_ops);
139 if (!err && tp)
140 xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_DIR_BLOCK_BUF);
141 return err;
138} 142}
139 143
140static void 144static void
141xfs_dir3_block_init( 145xfs_dir3_block_init(
142 struct xfs_mount *mp, 146 struct xfs_mount *mp,
147 struct xfs_trans *tp,
143 struct xfs_buf *bp, 148 struct xfs_buf *bp,
144 struct xfs_inode *dp) 149 struct xfs_inode *dp)
145{ 150{
146 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; 151 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
147 152
148 bp->b_ops = &xfs_dir3_block_buf_ops; 153 bp->b_ops = &xfs_dir3_block_buf_ops;
154 xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_BLOCK_BUF);
149 155
150 if (xfs_sb_version_hascrc(&mp->m_sb)) { 156 if (xfs_sb_version_hascrc(&mp->m_sb)) {
151 memset(hdr3, 0, sizeof(*hdr3)); 157 memset(hdr3, 0, sizeof(*hdr3));
@@ -1080,7 +1086,7 @@ xfs_dir2_leaf_to_block(
1080 /* 1086 /*
1081 * Start converting it to block form. 1087 * Start converting it to block form.
1082 */ 1088 */
1083 xfs_dir3_block_init(mp, dbp, dp); 1089 xfs_dir3_block_init(mp, tp, dbp, dp);
1084 1090
1085 needlog = 1; 1091 needlog = 1;
1086 needscan = 0; 1092 needscan = 0;
@@ -1209,7 +1215,7 @@ xfs_dir2_sf_to_block(
1209 kmem_free(sfp); 1215 kmem_free(sfp);
1210 return error; 1216 return error;
1211 } 1217 }
1212 xfs_dir3_block_init(mp, bp, dp); 1218 xfs_dir3_block_init(mp, tp, bp, dp);
1213 hdr = bp->b_addr; 1219 hdr = bp->b_addr;
1214 1220
1215 /* 1221 /*
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index 78320df3743f..5e0c711f9af3 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -301,8 +301,13 @@ xfs_dir3_data_read(
301 xfs_daddr_t mapped_bno, 301 xfs_daddr_t mapped_bno,
302 struct xfs_buf **bpp) 302 struct xfs_buf **bpp)
303{ 303{
304 return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, 304 int err;
305
306 err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
305 XFS_DATA_FORK, &xfs_dir3_data_buf_ops); 307 XFS_DATA_FORK, &xfs_dir3_data_buf_ops);
308 if (!err && tp)
309 xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_DIR_DATA_BUF);
310 return err;
306} 311}
307 312
308int 313int
@@ -571,6 +576,7 @@ xfs_dir3_data_init(
571 if (error) 576 if (error)
572 return error; 577 return error;
573 bp->b_ops = &xfs_dir3_data_buf_ops; 578 bp->b_ops = &xfs_dir3_data_buf_ops;
579 xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_DATA_BUF);
574 580
575 /* 581 /*
576 * Initialize the header. 582 * Initialize the header.
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 7352e41d2aaa..84f4c9cfe95a 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -279,7 +279,7 @@ xfs_dir3_leafn_write_verify(
279 __write_verify(bp, XFS_DIR2_LEAFN_MAGIC); 279 __write_verify(bp, XFS_DIR2_LEAFN_MAGIC);
280} 280}
281 281
282static const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = { 282const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = {
283 .verify_read = xfs_dir3_leaf1_read_verify, 283 .verify_read = xfs_dir3_leaf1_read_verify,
284 .verify_write = xfs_dir3_leaf1_write_verify, 284 .verify_write = xfs_dir3_leaf1_write_verify,
285}; 285};
@@ -297,8 +297,13 @@ xfs_dir3_leaf_read(
297 xfs_daddr_t mappedbno, 297 xfs_daddr_t mappedbno,
298 struct xfs_buf **bpp) 298 struct xfs_buf **bpp)
299{ 299{
300 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 300 int err;
301
302 err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
301 XFS_DATA_FORK, &xfs_dir3_leaf1_buf_ops); 303 XFS_DATA_FORK, &xfs_dir3_leaf1_buf_ops);
304 if (!err && tp)
305 xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_DIR_LEAF1_BUF);
306 return err;
302} 307}
303 308
304int 309int
@@ -309,8 +314,13 @@ xfs_dir3_leafn_read(
309 xfs_daddr_t mappedbno, 314 xfs_daddr_t mappedbno,
310 struct xfs_buf **bpp) 315 struct xfs_buf **bpp)
311{ 316{
312 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 317 int err;
318
319 err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
313 XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops); 320 XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops);
321 if (!err && tp)
322 xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_DIR_LEAFN_BUF);
323 return err;
314} 324}
315 325
316/* 326/*
@@ -319,6 +329,7 @@ xfs_dir3_leafn_read(
319static void 329static void
320xfs_dir3_leaf_init( 330xfs_dir3_leaf_init(
321 struct xfs_mount *mp, 331 struct xfs_mount *mp,
332 struct xfs_trans *tp,
322 struct xfs_buf *bp, 333 struct xfs_buf *bp,
323 xfs_ino_t owner, 334 xfs_ino_t owner,
324 __uint16_t type) 335 __uint16_t type)
@@ -353,8 +364,11 @@ xfs_dir3_leaf_init(
353 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 364 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
354 ltp->bestcount = 0; 365 ltp->bestcount = 0;
355 bp->b_ops = &xfs_dir3_leaf1_buf_ops; 366 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
356 } else 367 xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_LEAF1_BUF);
368 } else {
357 bp->b_ops = &xfs_dir3_leafn_buf_ops; 369 bp->b_ops = &xfs_dir3_leafn_buf_ops;
370 xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_LEAFN_BUF);
371 }
358} 372}
359 373
360int 374int
@@ -379,7 +393,7 @@ xfs_dir3_leaf_get_buf(
379 if (error) 393 if (error)
380 return error; 394 return error;
381 395
382 xfs_dir3_leaf_init(mp, bp, dp->i_ino, magic); 396 xfs_dir3_leaf_init(mp, tp, bp, dp->i_ino, magic);
383 xfs_dir3_leaf_log_header(tp, bp); 397 xfs_dir3_leaf_log_header(tp, bp);
384 if (magic == XFS_DIR2_LEAF1_MAGIC) 398 if (magic == XFS_DIR2_LEAF1_MAGIC)
385 xfs_dir3_leaf_log_tail(tp, bp); 399 xfs_dir3_leaf_log_tail(tp, bp);
@@ -474,6 +488,7 @@ xfs_dir2_block_to_leaf(
474 * Fix up the block header, make it a data block. 488 * Fix up the block header, make it a data block.
475 */ 489 */
476 dbp->b_ops = &xfs_dir3_data_buf_ops; 490 dbp->b_ops = &xfs_dir3_data_buf_ops;
491 xfs_trans_buf_set_type(tp, dbp, XFS_BLF_DIR_DATA_BUF);
477 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) 492 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))
478 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 493 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
479 else 494 else
@@ -2182,6 +2197,7 @@ xfs_dir2_node_to_leaf(
2182 xfs_dir3_leaf_compact(args, &leafhdr, lbp); 2197 xfs_dir3_leaf_compact(args, &leafhdr, lbp);
2183 2198
2184 lbp->b_ops = &xfs_dir3_leaf1_buf_ops; 2199 lbp->b_ops = &xfs_dir3_leaf1_buf_ops;
2200 xfs_trans_buf_set_type(tp, lbp, XFS_BLF_DIR_LEAF1_BUF);
2185 leafhdr.magic = (leafhdr.magic == XFS_DIR2_LEAFN_MAGIC) 2201 leafhdr.magic = (leafhdr.magic == XFS_DIR2_LEAFN_MAGIC)
2186 ? XFS_DIR2_LEAF1_MAGIC 2202 ? XFS_DIR2_LEAF1_MAGIC
2187 : XFS_DIR3_LEAF1_MAGIC; 2203 : XFS_DIR3_LEAF1_MAGIC;
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index 122449b33f5e..1806a22d5593 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -147,7 +147,7 @@ xfs_dir3_free_write_verify(
147 xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_FREE_CRC_OFF); 147 xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_FREE_CRC_OFF);
148} 148}
149 149
150static const struct xfs_buf_ops xfs_dir3_free_buf_ops = { 150const struct xfs_buf_ops xfs_dir3_free_buf_ops = {
151 .verify_read = xfs_dir3_free_read_verify, 151 .verify_read = xfs_dir3_free_read_verify,
152 .verify_write = xfs_dir3_free_write_verify, 152 .verify_write = xfs_dir3_free_write_verify,
153}; 153};
@@ -161,8 +161,15 @@ __xfs_dir3_free_read(
161 xfs_daddr_t mappedbno, 161 xfs_daddr_t mappedbno,
162 struct xfs_buf **bpp) 162 struct xfs_buf **bpp)
163{ 163{
164 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 164 int err;
165
166 err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
165 XFS_DATA_FORK, &xfs_dir3_free_buf_ops); 167 XFS_DATA_FORK, &xfs_dir3_free_buf_ops);
168
169 /* try read returns without an error or *bpp if it lands in a hole */
170 if (!err && tp && *bpp)
171 xfs_trans_buf_set_type(tp, *bpp, XFS_BLF_DIR_FREE_BUF);
172 return err;
166} 173}
167 174
168int 175int
@@ -249,6 +256,7 @@ xfs_dir3_free_get_buf(
249 if (error) 256 if (error)
250 return error; 257 return error;
251 258
259 xfs_trans_buf_set_type(tp, bp, XFS_BLF_DIR_FREE_BUF);
252 bp->b_ops = &xfs_dir3_free_buf_ops; 260 bp->b_ops = &xfs_dir3_free_buf_ops;
253 261
254 /* 262 /*
@@ -396,6 +404,7 @@ xfs_dir2_leaf_to_node(
396 else 404 else
397 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); 405 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
398 lbp->b_ops = &xfs_dir3_leafn_buf_ops; 406 lbp->b_ops = &xfs_dir3_leafn_buf_ops;
407 xfs_trans_buf_set_type(tp, lbp, XFS_BLF_DIR_LEAFN_BUF);
399 xfs_dir3_leaf_log_header(tp, lbp); 408 xfs_dir3_leaf_log_header(tp, lbp);
400 xfs_dir3_leaf_check(mp, lbp); 409 xfs_dir3_leaf_check(mp, lbp);
401 return 0; 410 return 0;
@@ -811,6 +820,7 @@ xfs_dir2_leafn_lookup_for_entry(
811 (char *)curbp->b_addr); 820 (char *)curbp->b_addr);
812 state->extrablk.magic = XFS_DIR2_DATA_MAGIC; 821 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
813 curbp->b_ops = &xfs_dir3_data_buf_ops; 822 curbp->b_ops = &xfs_dir3_data_buf_ops;
823 xfs_trans_buf_set_type(tp, curbp, XFS_BLF_DIR_DATA_BUF);
814 if (cmp == XFS_CMP_EXACT) 824 if (cmp == XFS_CMP_EXACT)
815 return XFS_ERROR(EEXIST); 825 return XFS_ERROR(EEXIST);
816 } 826 }
@@ -825,6 +835,7 @@ xfs_dir2_leafn_lookup_for_entry(
825 state->extrablk.blkno = curdb; 835 state->extrablk.blkno = curdb;
826 state->extrablk.magic = XFS_DIR2_DATA_MAGIC; 836 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
827 curbp->b_ops = &xfs_dir3_data_buf_ops; 837 curbp->b_ops = &xfs_dir3_data_buf_ops;
838 xfs_trans_buf_set_type(tp, curbp, XFS_BLF_DIR_DATA_BUF);
828 } else { 839 } else {
829 /* If the curbp is not the CI match block, drop it */ 840 /* If the curbp is not the CI match block, drop it */
830 if (state->extrablk.bp != curbp) 841 if (state->extrablk.bp != curbp)
diff --git a/fs/xfs/xfs_dir2_priv.h b/fs/xfs/xfs_dir2_priv.h
index 932565d6ef2a..7cf573c88aad 100644
--- a/fs/xfs/xfs_dir2_priv.h
+++ b/fs/xfs/xfs_dir2_priv.h
@@ -49,6 +49,7 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
49#endif 49#endif
50 50
51extern const struct xfs_buf_ops xfs_dir3_data_buf_ops; 51extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
52extern const struct xfs_buf_ops xfs_dir3_free_buf_ops;
52 53
53extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); 54extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
54extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp, 55extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp,
@@ -77,6 +78,7 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp,
77 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp); 78 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
78 79
79/* xfs_dir2_leaf.c */ 80/* xfs_dir2_leaf.c */
81extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
80extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops; 82extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops;
81 83
82extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp, 84extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index d1292fd1112a..00727bc4a9b0 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -45,7 +45,14 @@
45#include "xfs_cksum.h" 45#include "xfs_cksum.h"
46#include "xfs_trace.h" 46#include "xfs_trace.h"
47#include "xfs_icache.h" 47#include "xfs_icache.h"
48
49/* Need all the magic numbers and buffer ops structures from these headers */
48#include "xfs_symlink.h" 50#include "xfs_symlink.h"
51#include "xfs_da_btree.h"
52#include "xfs_dir2_format.h"
53#include "xfs_dir2_priv.h"
54#include "xfs_attr_leaf.h"
55#include "xfs_attr_remote.h"
49 56
50STATIC int 57STATIC int
51xlog_find_zeroed( 58xlog_find_zeroed(
@@ -1860,81 +1867,30 @@ xlog_recover_do_inode_buffer(
1860} 1867}
1861 1868
1862/* 1869/*
1863 * Perform a 'normal' buffer recovery. Each logged region of the 1870 * Validate the recovered buffer is of the correct type and attach the
1864 * buffer should be copied over the corresponding region in the 1871 * appropriate buffer operations to them for writeback. Magic numbers are in a
1865 * given buffer. The bitmap in the buf log format structure indicates 1872 * few places:
1866 * where to place the logged data. 1873 * the first 16 bits of the buffer (inode buffer, dquot buffer),
1874 * the first 32 bits of the buffer (most blocks),
1875 * inside a struct xfs_da_blkinfo at the start of the buffer.
1867 */ 1876 */
1868STATIC void 1877static void
1869xlog_recover_do_reg_buffer( 1878xlog_recovery_validate_buf_type(
1870 struct xfs_mount *mp, 1879 struct xfs_mount *mp,
1871 xlog_recover_item_t *item,
1872 struct xfs_buf *bp, 1880 struct xfs_buf *bp,
1873 xfs_buf_log_format_t *buf_f) 1881 xfs_buf_log_format_t *buf_f)
1874{ 1882{
1875 int i; 1883 struct xfs_da_blkinfo *info = bp->b_addr;
1876 int bit; 1884 __uint32_t magic32;
1877 int nbits; 1885 __uint16_t magic16;
1878 int error; 1886 __uint16_t magicda;
1879 1887
1880 trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f); 1888 magic32 = be32_to_cpu(*(__be32 *)bp->b_addr);
1881 1889 magic16 = be16_to_cpu(*(__be16*)bp->b_addr);
1882 bit = 0; 1890 magicda = be16_to_cpu(info->magic);
1883 i = 1; /* 0 is the buf format structure */
1884 while (1) {
1885 bit = xfs_next_bit(buf_f->blf_data_map,
1886 buf_f->blf_map_size, bit);
1887 if (bit == -1)
1888 break;
1889 nbits = xfs_contig_bits(buf_f->blf_data_map,
1890 buf_f->blf_map_size, bit);
1891 ASSERT(nbits > 0);
1892 ASSERT(item->ri_buf[i].i_addr != NULL);
1893 ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
1894 ASSERT(BBTOB(bp->b_io_length) >=
1895 ((uint)bit << XFS_BLF_SHIFT) + (nbits << XFS_BLF_SHIFT));
1896
1897 /*
1898 * Do a sanity check if this is a dquot buffer. Just checking
1899 * the first dquot in the buffer should do. XXXThis is
1900 * probably a good thing to do for other buf types also.
1901 */
1902 error = 0;
1903 if (buf_f->blf_flags &
1904 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
1905 if (item->ri_buf[i].i_addr == NULL) {
1906 xfs_alert(mp,
1907 "XFS: NULL dquot in %s.", __func__);
1908 goto next;
1909 }
1910 if (item->ri_buf[i].i_len < sizeof(xfs_disk_dquot_t)) {
1911 xfs_alert(mp,
1912 "XFS: dquot too small (%d) in %s.",
1913 item->ri_buf[i].i_len, __func__);
1914 goto next;
1915 }
1916 error = xfs_qm_dqcheck(mp, item->ri_buf[i].i_addr,
1917 -1, 0, XFS_QMOPT_DOWARN,
1918 "dquot_buf_recover");
1919 if (error)
1920 goto next;
1921 }
1922
1923 memcpy(xfs_buf_offset(bp,
1924 (uint)bit << XFS_BLF_SHIFT), /* dest */
1925 item->ri_buf[i].i_addr, /* source */
1926 nbits<<XFS_BLF_SHIFT); /* length */
1927 next:
1928 i++;
1929 bit += nbits;
1930 }
1931
1932 /* Shouldn't be any more regions */
1933 ASSERT(i == item->ri_total);
1934
1935 switch (buf_f->blf_flags & XFS_BLF_TYPE_MASK) { 1891 switch (buf_f->blf_flags & XFS_BLF_TYPE_MASK) {
1936 case XFS_BLF_BTREE_BUF: 1892 case XFS_BLF_BTREE_BUF:
1937 switch (be32_to_cpu(*(__be32 *)bp->b_addr)) { 1893 switch (magic32) {
1938 case XFS_ABTB_CRC_MAGIC: 1894 case XFS_ABTB_CRC_MAGIC:
1939 case XFS_ABTC_CRC_MAGIC: 1895 case XFS_ABTC_CRC_MAGIC:
1940 case XFS_ABTB_MAGIC: 1896 case XFS_ABTB_MAGIC:
@@ -1956,7 +1912,7 @@ xlog_recover_do_reg_buffer(
1956 } 1912 }
1957 break; 1913 break;
1958 case XFS_BLF_AGF_BUF: 1914 case XFS_BLF_AGF_BUF:
1959 if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_AGF_MAGIC)) { 1915 if (magic32 != XFS_AGF_MAGIC) {
1960 xfs_warn(mp, "Bad AGF block magic!"); 1916 xfs_warn(mp, "Bad AGF block magic!");
1961 ASSERT(0); 1917 ASSERT(0);
1962 break; 1918 break;
@@ -1966,7 +1922,7 @@ xlog_recover_do_reg_buffer(
1966 case XFS_BLF_AGFL_BUF: 1922 case XFS_BLF_AGFL_BUF:
1967 if (!xfs_sb_version_hascrc(&mp->m_sb)) 1923 if (!xfs_sb_version_hascrc(&mp->m_sb))
1968 break; 1924 break;
1969 if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_AGFL_MAGIC)) { 1925 if (magic32 != XFS_AGFL_MAGIC) {
1970 xfs_warn(mp, "Bad AGFL block magic!"); 1926 xfs_warn(mp, "Bad AGFL block magic!");
1971 ASSERT(0); 1927 ASSERT(0);
1972 break; 1928 break;
@@ -1974,7 +1930,7 @@ xlog_recover_do_reg_buffer(
1974 bp->b_ops = &xfs_agfl_buf_ops; 1930 bp->b_ops = &xfs_agfl_buf_ops;
1975 break; 1931 break;
1976 case XFS_BLF_AGI_BUF: 1932 case XFS_BLF_AGI_BUF:
1977 if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_AGI_MAGIC)) { 1933 if (magic32 != XFS_AGI_MAGIC) {
1978 xfs_warn(mp, "Bad AGI block magic!"); 1934 xfs_warn(mp, "Bad AGI block magic!");
1979 ASSERT(0); 1935 ASSERT(0);
1980 break; 1936 break;
@@ -1984,7 +1940,7 @@ xlog_recover_do_reg_buffer(
1984 case XFS_BLF_UDQUOT_BUF: 1940 case XFS_BLF_UDQUOT_BUF:
1985 case XFS_BLF_PDQUOT_BUF: 1941 case XFS_BLF_PDQUOT_BUF:
1986 case XFS_BLF_GDQUOT_BUF: 1942 case XFS_BLF_GDQUOT_BUF:
1987 if (*(__be16 *)bp->b_addr != cpu_to_be16(XFS_DQUOT_MAGIC)) { 1943 if (magic16 != XFS_DQUOT_MAGIC) {
1988 xfs_warn(mp, "Bad DQUOT block magic!"); 1944 xfs_warn(mp, "Bad DQUOT block magic!");
1989 ASSERT(0); 1945 ASSERT(0);
1990 break; 1946 break;
@@ -1996,7 +1952,7 @@ xlog_recover_do_reg_buffer(
1996 * we get here with inode allocation buffers, not buffers that 1952 * we get here with inode allocation buffers, not buffers that
1997 * track unlinked list changes. 1953 * track unlinked list changes.
1998 */ 1954 */
1999 if (*(__be16 *)bp->b_addr != cpu_to_be16(XFS_DINODE_MAGIC)) { 1955 if (magic16 != XFS_DINODE_MAGIC) {
2000 xfs_warn(mp, "Bad INODE block magic!"); 1956 xfs_warn(mp, "Bad INODE block magic!");
2001 ASSERT(0); 1957 ASSERT(0);
2002 break; 1958 break;
@@ -2004,19 +1960,169 @@ xlog_recover_do_reg_buffer(
2004 bp->b_ops = &xfs_inode_buf_ops; 1960 bp->b_ops = &xfs_inode_buf_ops;
2005 break; 1961 break;
2006 case XFS_BLF_SYMLINK_BUF: 1962 case XFS_BLF_SYMLINK_BUF:
2007 if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_SYMLINK_MAGIC)) { 1963 if (magic32 != XFS_SYMLINK_MAGIC) {
2008 xfs_warn(mp, "Bad symlink block magic!"); 1964 xfs_warn(mp, "Bad symlink block magic!");
2009 ASSERT(0); 1965 ASSERT(0);
2010 break; 1966 break;
2011 } 1967 }
2012 bp->b_ops = &xfs_symlink_buf_ops; 1968 bp->b_ops = &xfs_symlink_buf_ops;
2013 break; 1969 break;
1970 case XFS_BLF_DIR_BLOCK_BUF:
1971 if (magic32 != XFS_DIR2_BLOCK_MAGIC &&
1972 magic32 != XFS_DIR3_BLOCK_MAGIC) {
1973 xfs_warn(mp, "Bad dir block magic!");
1974 ASSERT(0);
1975 break;
1976 }
1977 bp->b_ops = &xfs_dir3_block_buf_ops;
1978 break;
1979 case XFS_BLF_DIR_DATA_BUF:
1980 if (magic32 != XFS_DIR2_DATA_MAGIC &&
1981 magic32 != XFS_DIR3_DATA_MAGIC) {
1982 xfs_warn(mp, "Bad dir data magic!");
1983 ASSERT(0);
1984 break;
1985 }
1986 bp->b_ops = &xfs_dir3_data_buf_ops;
1987 break;
1988 case XFS_BLF_DIR_FREE_BUF:
1989 if (magic32 != XFS_DIR2_FREE_MAGIC &&
1990 magic32 != XFS_DIR3_FREE_MAGIC) {
1991 xfs_warn(mp, "Bad dir3 free magic!");
1992 ASSERT(0);
1993 break;
1994 }
1995 bp->b_ops = &xfs_dir3_free_buf_ops;
1996 break;
1997 case XFS_BLF_DIR_LEAF1_BUF:
1998 if (magicda != XFS_DIR2_LEAF1_MAGIC &&
1999 magicda != XFS_DIR3_LEAF1_MAGIC) {
2000 xfs_warn(mp, "Bad dir leaf1 magic!");
2001 ASSERT(0);
2002 break;
2003 }
2004 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
2005 break;
2006 case XFS_BLF_DIR_LEAFN_BUF:
2007 if (magicda != XFS_DIR2_LEAFN_MAGIC &&
2008 magicda != XFS_DIR3_LEAFN_MAGIC) {
2009 xfs_warn(mp, "Bad dir leafn magic!");
2010 ASSERT(0);
2011 break;
2012 }
2013 bp->b_ops = &xfs_dir3_leafn_buf_ops;
2014 break;
2015 case XFS_BLF_DA_NODE_BUF:
2016 if (magicda != XFS_DA_NODE_MAGIC &&
2017 magicda != XFS_DA3_NODE_MAGIC) {
2018 xfs_warn(mp, "Bad da node magic!");
2019 ASSERT(0);
2020 break;
2021 }
2022 bp->b_ops = &xfs_da3_node_buf_ops;
2023 break;
2024 case XFS_BLF_ATTR_LEAF_BUF:
2025 if (magicda != XFS_ATTR_LEAF_MAGIC &&
2026 magicda != XFS_ATTR3_LEAF_MAGIC) {
2027 xfs_warn(mp, "Bad attr leaf magic!");
2028 ASSERT(0);
2029 break;
2030 }
2031 bp->b_ops = &xfs_attr3_leaf_buf_ops;
2032 break;
2033 case XFS_BLF_ATTR_RMT_BUF:
2034 if (!xfs_sb_version_hascrc(&mp->m_sb))
2035 break;
2036 if (magicda != XFS_ATTR3_RMT_MAGIC) {
2037 xfs_warn(mp, "Bad attr remote magic!");
2038 ASSERT(0);
2039 break;
2040 }
2041 bp->b_ops = &xfs_attr3_rmt_buf_ops;
2042 break;
2014 default: 2043 default:
2015 break; 2044 break;
2016 } 2045 }
2017} 2046}
2018 2047
2019/* 2048/*
2049 * Perform a 'normal' buffer recovery. Each logged region of the
2050 * buffer should be copied over the corresponding region in the
2051 * given buffer. The bitmap in the buf log format structure indicates
2052 * where to place the logged data.
2053 */
2054STATIC void
2055xlog_recover_do_reg_buffer(
2056 struct xfs_mount *mp,
2057 xlog_recover_item_t *item,
2058 struct xfs_buf *bp,
2059 xfs_buf_log_format_t *buf_f)
2060{
2061 int i;
2062 int bit;
2063 int nbits;
2064 int error;
2065
2066 trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f);
2067
2068 bit = 0;
2069 i = 1; /* 0 is the buf format structure */
2070 while (1) {
2071 bit = xfs_next_bit(buf_f->blf_data_map,
2072 buf_f->blf_map_size, bit);
2073 if (bit == -1)
2074 break;
2075 nbits = xfs_contig_bits(buf_f->blf_data_map,
2076 buf_f->blf_map_size, bit);
2077 ASSERT(nbits > 0);
2078 ASSERT(item->ri_buf[i].i_addr != NULL);
2079 ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
2080 ASSERT(BBTOB(bp->b_io_length) >=
2081 ((uint)bit << XFS_BLF_SHIFT) + (nbits << XFS_BLF_SHIFT));
2082
2083 /*
2084 * Do a sanity check if this is a dquot buffer. Just checking
2085 * the first dquot in the buffer should do. XXXThis is
2086 * probably a good thing to do for other buf types also.
2087 */
2088 error = 0;
2089 if (buf_f->blf_flags &
2090 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
2091 if (item->ri_buf[i].i_addr == NULL) {
2092 xfs_alert(mp,
2093 "XFS: NULL dquot in %s.", __func__);
2094 goto next;
2095 }
2096 if (item->ri_buf[i].i_len < sizeof(xfs_disk_dquot_t)) {
2097 xfs_alert(mp,
2098 "XFS: dquot too small (%d) in %s.",
2099 item->ri_buf[i].i_len, __func__);
2100 goto next;
2101 }
2102 error = xfs_qm_dqcheck(mp, item->ri_buf[i].i_addr,
2103 -1, 0, XFS_QMOPT_DOWARN,
2104 "dquot_buf_recover");
2105 if (error)
2106 goto next;
2107 }
2108
2109 memcpy(xfs_buf_offset(bp,
2110 (uint)bit << XFS_BLF_SHIFT), /* dest */
2111 item->ri_buf[i].i_addr, /* source */
2112 nbits<<XFS_BLF_SHIFT); /* length */
2113 next:
2114 i++;
2115 bit += nbits;
2116 }
2117
2118 /* Shouldn't be any more regions */
2119 ASSERT(i == item->ri_total);
2120
2121 xlog_recovery_validate_buf_type(mp, bp, buf_f);
2122
2123}
2124
2125/*
2020 * Do some primitive error checking on ondisk dquot data structures. 2126 * Do some primitive error checking on ondisk dquot data structures.
2021 */ 2127 */
2022int 2128int
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 1b04fe59c603..fa78a3f87c6e 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -507,6 +507,8 @@ void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
507void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); 507void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
508void xfs_trans_buf_set_type(struct xfs_trans *, struct xfs_buf *, 508void xfs_trans_buf_set_type(struct xfs_trans *, struct xfs_buf *,
509 uint); 509 uint);
510void xfs_trans_buf_copy_type(struct xfs_buf *dst_bp,
511 struct xfs_buf *src_bp);
510void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); 512void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int);
511void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint); 513void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint);
512void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); 514void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 8a0f6af51206..40871bf607f0 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -768,6 +768,9 @@ xfs_trans_buf_set_type(
768{ 768{
769 struct xfs_buf_log_item *bip = bp->b_fspriv; 769 struct xfs_buf_log_item *bip = bp->b_fspriv;
770 770
771 if (!tp)
772 return;
773
771 ASSERT(bp->b_transp == tp); 774 ASSERT(bp->b_transp == tp);
772 ASSERT(bip != NULL); 775 ASSERT(bip != NULL);
773 ASSERT(atomic_read(&bip->bli_refcount) > 0); 776 ASSERT(atomic_read(&bip->bli_refcount) > 0);
@@ -777,6 +780,20 @@ xfs_trans_buf_set_type(
777 bip->__bli_format.blf_flags |= type; 780 bip->__bli_format.blf_flags |= type;
778} 781}
779 782
783void
784xfs_trans_buf_copy_type(
785 struct xfs_buf *dst_bp,
786 struct xfs_buf *src_bp)
787{
788 struct xfs_buf_log_item *sbip = src_bp->b_fspriv;
789 struct xfs_buf_log_item *dbip = dst_bp->b_fspriv;
790 uint type;
791
792 type = sbip->__bli_format.blf_flags & XFS_BLF_TYPE_MASK;
793 dbip->__bli_format.blf_flags &= ~XFS_BLF_TYPE_MASK;
794 dbip->__bli_format.blf_flags |= type;
795}
796
780/* 797/*
781 * Similar to xfs_trans_inode_buf(), this marks the buffer as a cluster of 798 * Similar to xfs_trans_inode_buf(), this marks the buffer as a cluster of
782 * dquots. However, unlike in inode buffer recovery, dquot buffers get 799 * dquots. However, unlike in inode buffer recovery, dquot buffers get