diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-11-19 01:26:20 -0500 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2011-01-10 00:05:45 -0500 |
commit | e828949e5b42bfd234ee537cdb7c5e3a577958a3 (patch) | |
tree | c2e259a3020acdb943669fb01e5a7dc5598a6fe9 /fs/nilfs2/bmap.c | |
parent | b004a5eb0babec7ef91558f73315ef49e5a1f285 (diff) |
nilfs2: call nilfs_error inside bmap routines
Some functions using nilfs bmap routines can wrongly return invalid
argument error (i.e. -EINVAL) that bmap returns as an internal code
for btree corruption.
This fixes the issue by catching and converting the internal EINVAL to
EIO and calling nilfs_error function inside bmap routines.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/bmap.c')
-rw-r--r-- | fs/nilfs2/bmap.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index 8b782b062ba..4b7aeb34cc7 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c | |||
@@ -38,6 +38,19 @@ struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap) | |||
38 | return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode)); | 38 | return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode)); |
39 | } | 39 | } |
40 | 40 | ||
41 | static int nilfs_bmap_convert_error(struct nilfs_bmap *bmap, | ||
42 | const char *fname, int err) | ||
43 | { | ||
44 | struct inode *inode = bmap->b_inode; | ||
45 | |||
46 | if (err == -EINVAL) { | ||
47 | nilfs_error(inode->i_sb, fname, | ||
48 | "broken bmap (inode number=%lu)\n", inode->i_ino); | ||
49 | err = -EIO; | ||
50 | } | ||
51 | return err; | ||
52 | } | ||
53 | |||
41 | /** | 54 | /** |
42 | * nilfs_bmap_lookup_at_level - find a data block or node block | 55 | * nilfs_bmap_lookup_at_level - find a data block or node block |
43 | * @bmap: bmap | 56 | * @bmap: bmap |
@@ -66,8 +79,10 @@ int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level, | |||
66 | 79 | ||
67 | down_read(&bmap->b_sem); | 80 | down_read(&bmap->b_sem); |
68 | ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp); | 81 | ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp); |
69 | if (ret < 0) | 82 | if (ret < 0) { |
83 | ret = nilfs_bmap_convert_error(bmap, __func__, ret); | ||
70 | goto out; | 84 | goto out; |
85 | } | ||
71 | if (NILFS_BMAP_USE_VBN(bmap)) { | 86 | if (NILFS_BMAP_USE_VBN(bmap)) { |
72 | ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp, | 87 | ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp, |
73 | &blocknr); | 88 | &blocknr); |
@@ -88,7 +103,8 @@ int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp, | |||
88 | down_read(&bmap->b_sem); | 103 | down_read(&bmap->b_sem); |
89 | ret = bmap->b_ops->bop_lookup_contig(bmap, key, ptrp, maxblocks); | 104 | ret = bmap->b_ops->bop_lookup_contig(bmap, key, ptrp, maxblocks); |
90 | up_read(&bmap->b_sem); | 105 | up_read(&bmap->b_sem); |
91 | return ret; | 106 | |
107 | return nilfs_bmap_convert_error(bmap, __func__, ret); | ||
92 | } | 108 | } |
93 | 109 | ||
94 | static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) | 110 | static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) |
@@ -144,7 +160,8 @@ int nilfs_bmap_insert(struct nilfs_bmap *bmap, | |||
144 | down_write(&bmap->b_sem); | 160 | down_write(&bmap->b_sem); |
145 | ret = nilfs_bmap_do_insert(bmap, key, rec); | 161 | ret = nilfs_bmap_do_insert(bmap, key, rec); |
146 | up_write(&bmap->b_sem); | 162 | up_write(&bmap->b_sem); |
147 | return ret; | 163 | |
164 | return nilfs_bmap_convert_error(bmap, __func__, ret); | ||
148 | } | 165 | } |
149 | 166 | ||
150 | static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key) | 167 | static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key) |
@@ -180,9 +197,12 @@ int nilfs_bmap_last_key(struct nilfs_bmap *bmap, unsigned long *key) | |||
180 | 197 | ||
181 | down_read(&bmap->b_sem); | 198 | down_read(&bmap->b_sem); |
182 | ret = bmap->b_ops->bop_last_key(bmap, &lastkey); | 199 | ret = bmap->b_ops->bop_last_key(bmap, &lastkey); |
183 | if (!ret) | ||
184 | *key = lastkey; | ||
185 | up_read(&bmap->b_sem); | 200 | up_read(&bmap->b_sem); |
201 | |||
202 | if (ret < 0) | ||
203 | ret = nilfs_bmap_convert_error(bmap, __func__, ret); | ||
204 | else | ||
205 | *key = lastkey; | ||
186 | return ret; | 206 | return ret; |
187 | } | 207 | } |
188 | 208 | ||
@@ -210,7 +230,8 @@ int nilfs_bmap_delete(struct nilfs_bmap *bmap, unsigned long key) | |||
210 | down_write(&bmap->b_sem); | 230 | down_write(&bmap->b_sem); |
211 | ret = nilfs_bmap_do_delete(bmap, key); | 231 | ret = nilfs_bmap_do_delete(bmap, key); |
212 | up_write(&bmap->b_sem); | 232 | up_write(&bmap->b_sem); |
213 | return ret; | 233 | |
234 | return nilfs_bmap_convert_error(bmap, __func__, ret); | ||
214 | } | 235 | } |
215 | 236 | ||
216 | static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, unsigned long key) | 237 | static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, unsigned long key) |
@@ -261,7 +282,8 @@ int nilfs_bmap_truncate(struct nilfs_bmap *bmap, unsigned long key) | |||
261 | down_write(&bmap->b_sem); | 282 | down_write(&bmap->b_sem); |
262 | ret = nilfs_bmap_do_truncate(bmap, key); | 283 | ret = nilfs_bmap_do_truncate(bmap, key); |
263 | up_write(&bmap->b_sem); | 284 | up_write(&bmap->b_sem); |
264 | return ret; | 285 | |
286 | return nilfs_bmap_convert_error(bmap, __func__, ret); | ||
265 | } | 287 | } |
266 | 288 | ||
267 | /** | 289 | /** |
@@ -300,7 +322,8 @@ int nilfs_bmap_propagate(struct nilfs_bmap *bmap, struct buffer_head *bh) | |||
300 | down_write(&bmap->b_sem); | 322 | down_write(&bmap->b_sem); |
301 | ret = bmap->b_ops->bop_propagate(bmap, bh); | 323 | ret = bmap->b_ops->bop_propagate(bmap, bh); |
302 | up_write(&bmap->b_sem); | 324 | up_write(&bmap->b_sem); |
303 | return ret; | 325 | |
326 | return nilfs_bmap_convert_error(bmap, __func__, ret); | ||
304 | } | 327 | } |
305 | 328 | ||
306 | /** | 329 | /** |
@@ -344,7 +367,8 @@ int nilfs_bmap_assign(struct nilfs_bmap *bmap, | |||
344 | down_write(&bmap->b_sem); | 367 | down_write(&bmap->b_sem); |
345 | ret = bmap->b_ops->bop_assign(bmap, bh, blocknr, binfo); | 368 | ret = bmap->b_ops->bop_assign(bmap, bh, blocknr, binfo); |
346 | up_write(&bmap->b_sem); | 369 | up_write(&bmap->b_sem); |
347 | return ret; | 370 | |
371 | return nilfs_bmap_convert_error(bmap, __func__, ret); | ||
348 | } | 372 | } |
349 | 373 | ||
350 | /** | 374 | /** |
@@ -373,7 +397,8 @@ int nilfs_bmap_mark(struct nilfs_bmap *bmap, __u64 key, int level) | |||
373 | down_write(&bmap->b_sem); | 397 | down_write(&bmap->b_sem); |
374 | ret = bmap->b_ops->bop_mark(bmap, key, level); | 398 | ret = bmap->b_ops->bop_mark(bmap, key, level); |
375 | up_write(&bmap->b_sem); | 399 | up_write(&bmap->b_sem); |
376 | return ret; | 400 | |
401 | return nilfs_bmap_convert_error(bmap, __func__, ret); | ||
377 | } | 402 | } |
378 | 403 | ||
379 | /** | 404 | /** |