aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2')
-rw-r--r--fs/nilfs2/btree.c50
-rw-r--r--fs/nilfs2/btree.h2
-rw-r--r--fs/nilfs2/gcinode.c9
3 files changed, 56 insertions, 5 deletions
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index 386356707f90..6c9ec566d000 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -71,17 +71,24 @@ static int nilfs_btree_get_block(const struct nilfs_btree *btree, __u64 ptr,
71{ 71{
72 struct address_space *btnc = 72 struct address_space *btnc =
73 &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache; 73 &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
74 struct buffer_head *bh;
74 int err; 75 int err;
75 76
76 err = nilfs_btnode_submit_block(btnc, ptr, 0, bhp); 77 err = nilfs_btnode_submit_block(btnc, ptr, 0, bhp);
77 if (err) 78 if (err)
78 return err == -EEXIST ? 0 : err; 79 return err == -EEXIST ? 0 : err;
79 80
80 wait_on_buffer(*bhp); 81 bh = *bhp;
81 if (!buffer_uptodate(*bhp)) { 82 wait_on_buffer(bh);
82 brelse(*bhp); 83 if (!buffer_uptodate(bh)) {
84 brelse(bh);
83 return -EIO; 85 return -EIO;
84 } 86 }
87 if (nilfs_btree_broken_node_block(bh)) {
88 clear_buffer_uptodate(bh);
89 brelse(bh);
90 return -EINVAL;
91 }
85 return 0; 92 return 0;
86} 93}
87 94
@@ -382,6 +389,43 @@ static int nilfs_btree_node_lookup(const struct nilfs_btree_node *node,
382 return s == 0; 389 return s == 0;
383} 390}
384 391
392/**
393 * nilfs_btree_node_broken - verify consistency of btree node
394 * @node: btree node block to be examined
395 * @size: node size (in bytes)
396 * @blocknr: block number
397 *
398 * Return Value: If node is broken, 1 is returned. Otherwise, 0 is returned.
399 */
400static int nilfs_btree_node_broken(const struct nilfs_btree_node *node,
401 size_t size, sector_t blocknr)
402{
403 int level, flags, nchildren;
404 int ret = 0;
405
406 level = nilfs_btree_node_get_level(node);
407 flags = nilfs_btree_node_get_flags(node);
408 nchildren = nilfs_btree_node_get_nchildren(node);
409
410 if (unlikely(level < NILFS_BTREE_LEVEL_NODE_MIN ||
411 level >= NILFS_BTREE_LEVEL_MAX ||
412 (flags & NILFS_BTREE_NODE_ROOT) ||
413 nchildren < 0 ||
414 nchildren > NILFS_BTREE_NODE_NCHILDREN_MAX(size))) {
415 printk(KERN_CRIT "NILFS: bad btree node (blocknr=%llu): "
416 "level = %d, flags = 0x%x, nchildren = %d\n",
417 (unsigned long long)blocknr, level, flags, nchildren);
418 ret = 1;
419 }
420 return ret;
421}
422
423int nilfs_btree_broken_node_block(struct buffer_head *bh)
424{
425 return nilfs_btree_node_broken((struct nilfs_btree_node *)bh->b_data,
426 bh->b_size, bh->b_blocknr);
427}
428
385static inline struct nilfs_btree_node * 429static inline struct nilfs_btree_node *
386nilfs_btree_get_root(const struct nilfs_btree *btree) 430nilfs_btree_get_root(const struct nilfs_btree *btree)
387{ 431{
diff --git a/fs/nilfs2/btree.h b/fs/nilfs2/btree.h
index 43c8c5b541fd..980e1e8ec53a 100644
--- a/fs/nilfs2/btree.h
+++ b/fs/nilfs2/btree.h
@@ -80,4 +80,6 @@ int nilfs_btree_convert_and_insert(struct nilfs_bmap *, __u64, __u64,
80 const __u64 *, const __u64 *, int); 80 const __u64 *, const __u64 *, int);
81void nilfs_btree_init_gc(struct nilfs_bmap *); 81void nilfs_btree_init_gc(struct nilfs_bmap *);
82 82
83int nilfs_btree_broken_node_block(struct buffer_head *bh);
84
83#endif /* _NILFS_BTREE_H */ 85#endif /* _NILFS_BTREE_H */
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
index 145f03cd7d3e..edb53fcb7f83 100644
--- a/fs/nilfs2/gcinode.c
+++ b/fs/nilfs2/gcinode.c
@@ -164,10 +164,15 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh)
164 if (buffer_dirty(bh)) 164 if (buffer_dirty(bh))
165 return -EEXIST; 165 return -EEXIST;
166 166
167 if (buffer_nilfs_node(bh)) 167 if (buffer_nilfs_node(bh)) {
168 if (nilfs_btree_broken_node_block(bh)) {
169 clear_buffer_uptodate(bh);
170 return -EIO;
171 }
168 nilfs_btnode_mark_dirty(bh); 172 nilfs_btnode_mark_dirty(bh);
169 else 173 } else {
170 nilfs_mdt_mark_buffer_dirty(bh); 174 nilfs_mdt_mark_buffer_dirty(bh);
175 }
171 return 0; 176 return 0;
172} 177}
173 178