diff options
| -rw-r--r-- | fs/nilfs2/btree.c | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index b2e3ff347620..ecdbae19a766 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c | |||
| @@ -31,6 +31,8 @@ | |||
| 31 | #include "alloc.h" | 31 | #include "alloc.h" |
| 32 | #include "dat.h" | 32 | #include "dat.h" |
| 33 | 33 | ||
| 34 | static void __nilfs_btree_init(struct nilfs_bmap *bmap); | ||
| 35 | |||
| 34 | static struct nilfs_btree_path *nilfs_btree_alloc_path(void) | 36 | static struct nilfs_btree_path *nilfs_btree_alloc_path(void) |
| 35 | { | 37 | { |
| 36 | struct nilfs_btree_path *path; | 38 | struct nilfs_btree_path *path; |
| @@ -368,6 +370,34 @@ static int nilfs_btree_node_broken(const struct nilfs_btree_node *node, | |||
| 368 | return ret; | 370 | return ret; |
| 369 | } | 371 | } |
| 370 | 372 | ||
| 373 | /** | ||
| 374 | * nilfs_btree_root_broken - verify consistency of btree root node | ||
| 375 | * @node: btree root node to be examined | ||
| 376 | * @ino: inode number | ||
| 377 | * | ||
| 378 | * Return Value: If node is broken, 1 is returned. Otherwise, 0 is returned. | ||
| 379 | */ | ||
| 380 | static int nilfs_btree_root_broken(const struct nilfs_btree_node *node, | ||
| 381 | unsigned long ino) | ||
| 382 | { | ||
| 383 | int level, flags, nchildren; | ||
| 384 | int ret = 0; | ||
| 385 | |||
| 386 | level = nilfs_btree_node_get_level(node); | ||
| 387 | flags = nilfs_btree_node_get_flags(node); | ||
| 388 | nchildren = nilfs_btree_node_get_nchildren(node); | ||
| 389 | |||
| 390 | if (unlikely(level < NILFS_BTREE_LEVEL_NODE_MIN || | ||
| 391 | level > NILFS_BTREE_LEVEL_MAX || | ||
| 392 | nchildren < 0 || | ||
| 393 | nchildren > NILFS_BTREE_ROOT_NCHILDREN_MAX)) { | ||
| 394 | pr_crit("NILFS: bad btree root (inode number=%lu): level = %d, flags = 0x%x, nchildren = %d\n", | ||
| 395 | ino, level, flags, nchildren); | ||
| 396 | ret = 1; | ||
| 397 | } | ||
| 398 | return ret; | ||
| 399 | } | ||
| 400 | |||
| 371 | int nilfs_btree_broken_node_block(struct buffer_head *bh) | 401 | int nilfs_btree_broken_node_block(struct buffer_head *bh) |
| 372 | { | 402 | { |
| 373 | int ret; | 403 | int ret; |
| @@ -1713,7 +1743,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *btree, | |||
| 1713 | 1743 | ||
| 1714 | /* convert and insert */ | 1744 | /* convert and insert */ |
| 1715 | dat = NILFS_BMAP_USE_VBN(btree) ? nilfs_bmap_get_dat(btree) : NULL; | 1745 | dat = NILFS_BMAP_USE_VBN(btree) ? nilfs_bmap_get_dat(btree) : NULL; |
| 1716 | nilfs_btree_init(btree); | 1746 | __nilfs_btree_init(btree); |
| 1717 | if (nreq != NULL) { | 1747 | if (nreq != NULL) { |
| 1718 | nilfs_bmap_commit_alloc_ptr(btree, dreq, dat); | 1748 | nilfs_bmap_commit_alloc_ptr(btree, dreq, dat); |
| 1719 | nilfs_bmap_commit_alloc_ptr(btree, nreq, dat); | 1749 | nilfs_bmap_commit_alloc_ptr(btree, nreq, dat); |
| @@ -2294,12 +2324,23 @@ static const struct nilfs_bmap_operations nilfs_btree_ops_gc = { | |||
| 2294 | .bop_gather_data = NULL, | 2324 | .bop_gather_data = NULL, |
| 2295 | }; | 2325 | }; |
| 2296 | 2326 | ||
| 2297 | int nilfs_btree_init(struct nilfs_bmap *bmap) | 2327 | static void __nilfs_btree_init(struct nilfs_bmap *bmap) |
| 2298 | { | 2328 | { |
| 2299 | bmap->b_ops = &nilfs_btree_ops; | 2329 | bmap->b_ops = &nilfs_btree_ops; |
| 2300 | bmap->b_nchildren_per_block = | 2330 | bmap->b_nchildren_per_block = |
| 2301 | NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(bmap)); | 2331 | NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(bmap)); |
| 2302 | return 0; | 2332 | } |
| 2333 | |||
| 2334 | int nilfs_btree_init(struct nilfs_bmap *bmap) | ||
| 2335 | { | ||
| 2336 | int ret = 0; | ||
| 2337 | |||
| 2338 | __nilfs_btree_init(bmap); | ||
| 2339 | |||
| 2340 | if (nilfs_btree_root_broken(nilfs_btree_get_root(bmap), | ||
| 2341 | bmap->b_inode->i_ino)) | ||
| 2342 | ret = -EIO; | ||
| 2343 | return ret; | ||
| 2303 | } | 2344 | } |
| 2304 | 2345 | ||
| 2305 | void nilfs_btree_init_gc(struct nilfs_bmap *bmap) | 2346 | void nilfs_btree_init_gc(struct nilfs_bmap *bmap) |
