Commit e828949e5b42bfd234ee537cdb7c5e3a577958a3

Authored by Ryusuke Konishi
1 parent b004a5eb0b

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>

Showing 5 changed files with 48 additions and 63 deletions Side-by-side Diff

... ... @@ -38,6 +38,19 @@
38 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 55 * nilfs_bmap_lookup_at_level - find a data block or node block
43 56 * @bmap: bmap
44 57  
... ... @@ -66,8 +79,10 @@
66 79  
67 80 down_read(&bmap->b_sem);
68 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 84 goto out;
  85 + }
71 86 if (NILFS_BMAP_USE_VBN(bmap)) {
72 87 ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp,
73 88 &blocknr);
... ... @@ -88,7 +103,8 @@
88 103 down_read(&bmap->b_sem);
89 104 ret = bmap->b_ops->bop_lookup_contig(bmap, key, ptrp, maxblocks);
90 105 up_read(&bmap->b_sem);
91   - return ret;
  106 +
  107 + return nilfs_bmap_convert_error(bmap, __func__, ret);
92 108 }
93 109  
94 110 static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
... ... @@ -144,7 +160,8 @@
144 160 down_write(&bmap->b_sem);
145 161 ret = nilfs_bmap_do_insert(bmap, key, rec);
146 162 up_write(&bmap->b_sem);
147   - return ret;
  163 +
  164 + return nilfs_bmap_convert_error(bmap, __func__, ret);
148 165 }
149 166  
150 167 static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key)
151 168  
... ... @@ -180,9 +197,12 @@
180 197  
181 198 down_read(&bmap->b_sem);
182 199 ret = bmap->b_ops->bop_last_key(bmap, &lastkey);
183   - if (!ret)
184   - *key = lastkey;
185 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 206 return ret;
187 207 }
188 208  
... ... @@ -210,7 +230,8 @@
210 230 down_write(&bmap->b_sem);
211 231 ret = nilfs_bmap_do_delete(bmap, key);
212 232 up_write(&bmap->b_sem);
213   - return ret;
  233 +
  234 + return nilfs_bmap_convert_error(bmap, __func__, ret);
214 235 }
215 236  
216 237 static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, unsigned long key)
... ... @@ -261,7 +282,8 @@
261 282 down_write(&bmap->b_sem);
262 283 ret = nilfs_bmap_do_truncate(bmap, key);
263 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 @@
300 322 down_write(&bmap->b_sem);
301 323 ret = bmap->b_ops->bop_propagate(bmap, bh);
302 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 @@
344 367 down_write(&bmap->b_sem);
345 368 ret = bmap->b_ops->bop_assign(bmap, bh, blocknr, binfo);
346 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 @@
373 397 down_write(&bmap->b_sem);
374 398 ret = bmap->b_ops->bop_mark(bmap, key, level);
375 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 /**
... ... @@ -149,14 +149,9 @@
149 149 }
150 150  
151 151 err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh);
152   - if (unlikely(err)) {
153   - if (err == -EINVAL)
154   - nilfs_error(sb, __func__, "ifile is broken");
155   - else
156   - nilfs_warning(sb, __func__,
157   - "unable to read inode: %lu",
158   - (unsigned long) ino);
159   - }
  152 + if (unlikely(err))
  153 + nilfs_warning(sb, __func__, "unable to read inode: %lu",
  154 + (unsigned long) ino);
160 155 return err;
161 156 }
162 157  
... ... @@ -96,11 +96,6 @@
96 96 inode->i_ino,
97 97 (unsigned long long)blkoff);
98 98 err = 0;
99   - } else if (err == -EINVAL) {
100   - nilfs_error(inode->i_sb, __func__,
101   - "broken bmap (inode=%lu)\n",
102   - inode->i_ino);
103   - err = -EIO;
104 99 }
105 100 nilfs_transaction_abort(inode->i_sb);
106 101 goto out;
... ... @@ -629,7 +624,7 @@
629 624  
630 625 if (!test_bit(NILFS_I_BMAP, &ii->i_state))
631 626 return;
632   - repeat:
  627 +repeat:
633 628 ret = nilfs_bmap_last_key(ii->i_bmap, &b);
634 629 if (ret == -ENOENT)
635 630 return;
... ... @@ -646,14 +641,10 @@
646 641 nilfs_bmap_truncate(ii->i_bmap, b) == 0))
647 642 goto repeat;
648 643  
649   - failed:
650   - if (ret == -EINVAL)
651   - nilfs_error(ii->vfs_inode.i_sb, __func__,
652   - "bmap is broken (ino=%lu)", ii->vfs_inode.i_ino);
653   - else
654   - nilfs_warning(ii->vfs_inode.i_sb, __func__,
655   - "failed to truncate bmap (ino=%lu, err=%d)",
656   - ii->vfs_inode.i_ino, ret);
  644 +failed:
  645 + nilfs_warning(ii->vfs_inode.i_sb, __func__,
  646 + "failed to truncate bmap (ino=%lu, err=%d)",
  647 + ii->vfs_inode.i_ino, ret);
657 648 }
658 649  
659 650 void nilfs_truncate(struct inode *inode)
... ... @@ -237,8 +237,6 @@
237 237 *
238 238 * %-ENOENT - the specified block does not exist (hole block)
239 239 *
240   - * %-EINVAL - bmap is broken. (the caller should call nilfs_error())
241   - *
242 240 * %-EROFS - Read only filesystem (for create mode)
243 241 */
244 242 int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create,
... ... @@ -273,8 +271,6 @@
273 271 * %-ENOMEM - Insufficient memory available.
274 272 *
275 273 * %-EIO - I/O error
276   - *
277   - * %-EINVAL - bmap is broken. (the caller should call nilfs_error())
278 274 */
279 275 int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)
280 276 {
... ... @@ -350,8 +346,6 @@
350 346 * %-EIO - I/O error
351 347 *
352 348 * %-ENOENT - the specified block does not exist (hole block)
353   - *
354   - * %-EINVAL - bmap is broken. (the caller should call nilfs_error())
355 349 */
356 350 int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block)
357 351 {
... ... @@ -504,17 +504,6 @@
504 504 return err;
505 505 }
506 506  
507   -static int nilfs_handle_bmap_error(int err, const char *fname,
508   - struct inode *inode, struct super_block *sb)
509   -{
510   - if (err == -EINVAL) {
511   - nilfs_error(sb, fname, "broken bmap (inode=%lu)\n",
512   - inode->i_ino);
513   - err = -EIO;
514   - }
515   - return err;
516   -}
517   -
518 507 /*
519 508 * Callback functions that enumerate, mark, and collect dirty blocks
520 509 */
... ... @@ -524,9 +513,8 @@
524 513 int err;
525 514  
526 515 err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
527   - if (unlikely(err < 0))
528   - return nilfs_handle_bmap_error(err, __func__, inode,
529   - sci->sc_super);
  516 + if (err < 0)
  517 + return err;
530 518  
531 519 err = nilfs_segctor_add_file_block(sci, bh, inode,
532 520 sizeof(struct nilfs_binfo_v));
... ... @@ -539,13 +527,7 @@
539 527 struct buffer_head *bh,
540 528 struct inode *inode)
541 529 {
542   - int err;
543   -
544   - err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
545   - if (unlikely(err < 0))
546   - return nilfs_handle_bmap_error(err, __func__, inode,
547   - sci->sc_super);
548   - return 0;
  530 + return nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
549 531 }
550 532  
551 533 static int nilfs_collect_file_bmap(struct nilfs_sc_info *sci,
... ... @@ -588,9 +570,8 @@
588 570 int err;
589 571  
590 572 err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
591   - if (unlikely(err < 0))
592   - return nilfs_handle_bmap_error(err, __func__, inode,
593   - sci->sc_super);
  573 + if (err < 0)
  574 + return err;
594 575  
595 576 err = nilfs_segctor_add_file_block(sci, bh, inode, sizeof(__le64));
596 577 if (!err)
... ... @@ -1563,7 +1544,6 @@
1563 1544 return 0;
1564 1545  
1565 1546 failed_bmap:
1566   - err = nilfs_handle_bmap_error(err, __func__, inode, sci->sc_super);
1567 1547 return err;
1568 1548 }
1569 1549