diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_attr_leaf.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_attr_remote.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_buf_item.h | 18 | ||||
-rw-r--r-- | fs/xfs/xfs_da_btree.c | 46 | ||||
-rw-r--r-- | fs/xfs/xfs_da_btree.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_block.c | 12 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_data.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 26 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_node.c | 15 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_priv.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 254 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_buf.c | 17 |
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 | ||
40 | extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops; | ||
41 | |||
40 | int xfs_attr_rmtval_get(struct xfs_da_args *args); | 42 | int xfs_attr_rmtval_get(struct xfs_da_args *args); |
41 | int xfs_attr_rmtval_set(struct xfs_da_args *args); | 43 | int xfs_attr_rmtval_set(struct xfs_da_args *args); |
42 | int xfs_attr_rmtval_remove(struct xfs_da_args *args); | 44 | int 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 | |||
296 | int | 295 | int |
297 | xfs_da3_node_read( | 296 | xfs_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 | ||
304 | extern 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 | ||
140 | static void | 144 | static void |
141 | xfs_dir3_block_init( | 145 | xfs_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 | ||
308 | int | 313 | int |
@@ -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 | ||
282 | static const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = { | 282 | const 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 | ||
304 | int | 309 | int |
@@ -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( | |||
319 | static void | 329 | static void |
320 | xfs_dir3_leaf_init( | 330 | xfs_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 | ||
360 | int | 374 | int |
@@ -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 | ||
150 | static const struct xfs_buf_ops xfs_dir3_free_buf_ops = { | 150 | const 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 | ||
168 | int | 175 | int |
@@ -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 | ||
51 | extern const struct xfs_buf_ops xfs_dir3_data_buf_ops; | 51 | extern const struct xfs_buf_ops xfs_dir3_data_buf_ops; |
52 | extern const struct xfs_buf_ops xfs_dir3_free_buf_ops; | ||
52 | 53 | ||
53 | extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); | 54 | extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); |
54 | extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp, | 55 | extern 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 */ |
81 | extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops; | ||
80 | extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops; | 82 | extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops; |
81 | 83 | ||
82 | extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp, | 84 | extern 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 | ||
50 | STATIC int | 57 | STATIC int |
51 | xlog_find_zeroed( | 58 | xlog_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 | */ |
1868 | STATIC void | 1877 | static void |
1869 | xlog_recover_do_reg_buffer( | 1878 | xlog_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 | */ | ||
2054 | STATIC void | ||
2055 | xlog_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 | */ |
2022 | int | 2128 | int |
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); | |||
507 | void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); | 507 | void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); |
508 | void xfs_trans_buf_set_type(struct xfs_trans *, struct xfs_buf *, | 508 | void xfs_trans_buf_set_type(struct xfs_trans *, struct xfs_buf *, |
509 | uint); | 509 | uint); |
510 | void xfs_trans_buf_copy_type(struct xfs_buf *dst_bp, | ||
511 | struct xfs_buf *src_bp); | ||
510 | void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); | 512 | void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); |
511 | void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint); | 513 | void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint); |
512 | void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); | 514 | void 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 | ||
783 | void | ||
784 | xfs_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 |