aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2016-09-21 14:39:42 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2016-09-30 20:34:27 -0400
commitd41065e20484c53d8976742367bb78ac248fb0d5 (patch)
tree94ec3b513f5e82cf6b2b25f45af39d2d18744d2f
parent646e759a4d09062df943eaf61cb8141a91204380 (diff)
f2fs: handle errors during recover_orphan_inodes
This patch fixes to handle EIO during recover_orphan_inode() given the below panic. F2FS-fs : inject IO error in f2fs_read_end_io+0xe6/0x100 [f2fs] ------------[ cut here ]------------ RIP: 0010:[<ffffffffc0b244e3>] [<ffffffffc0b244e3>] f2fs_evict_inode+0x433/0x470 [f2fs] RSP: 0018:ffff92f8b7fb7c30 EFLAGS: 00010246 RAX: ffff92fb88a13500 RBX: ffff92f890566ea0 RCX: 00000000fd3c255c RDX: 0000000000000001 RSI: ffff92fb88a13d90 RDI: ffff92fb8ee127e8 RBP: ffff92f8b7fb7c58 R08: 0000000000000001 R09: ffff92fb88a13d58 R10: 000000005a6a9373 R11: 0000000000000001 R12: 00000000fffffffb R13: ffff92fb8ee12000 R14: 00000000000034ca R15: ffff92fb8ee12620 FS: 00007f1fefd8e880(0000) GS:ffff92fb95600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fc211d34cdb CR3: 000000012d43a000 CR4: 00000000001406e0 Stack: ffff92f890566ea0 ffff92f890567078 ffffffffc0b5a0c0 ffff92f890566f28 ffff92fb888b2000 ffff92f8b7fb7c80 ffffffffbc27ff55 ffff92f890566ea0 ffff92fb8bf10000 ffffffffc0b5a0c0 ffff92f8b7fb7cb0 ffffffffbc28090d Call Trace: [<ffffffffbc27ff55>] evict+0xc5/0x1a0 [<ffffffffbc28090d>] iput+0x1ad/0x2c0 [<ffffffffc0b3304c>] recover_orphan_inodes+0x10c/0x2e0 [f2fs] [<ffffffffc0b2e0f4>] f2fs_fill_super+0x884/0x1150 [f2fs] [<ffffffffbc2644ac>] mount_bdev+0x18c/0x1c0 [<ffffffffc0b2d870>] ? f2fs_commit_super+0x100/0x100 [f2fs] [<ffffffffc0b2a755>] f2fs_mount+0x15/0x20 [f2fs] [<ffffffffbc264e49>] mount_fs+0x39/0x170 [<ffffffffbc28555b>] vfs_kern_mount+0x6b/0x160 [<ffffffffbc2881df>] do_mount+0x1cf/0xd00 [<ffffffffbc287f2c>] ? copy_mount_options+0xac/0x170 [<ffffffffbc289003>] SyS_mount+0x83/0xd0 [<ffffffffbc8ee880>] entry_SYSCALL_64_fastpath+0x23/0xc1 Reviewed-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/checkpoint.c27
-rw-r--r--fs/f2fs/super.c1
2 files changed, 18 insertions, 10 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 64e389285f54..15c0006b12f1 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -535,6 +535,17 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
535{ 535{
536 struct inode *inode; 536 struct inode *inode;
537 struct node_info ni; 537 struct node_info ni;
538 int err = acquire_orphan_inode(sbi);
539
540 if (err) {
541 set_sbi_flag(sbi, SBI_NEED_FSCK);
542 f2fs_msg(sbi->sb, KERN_WARNING,
543 "%s: orphan failed (ino=%x), run fsck to fix.",
544 __func__, ino);
545 return err;
546 }
547
548 __add_ino_entry(sbi, ino, ORPHAN_INO);
538 549
539 inode = f2fs_iget_retry(sbi->sb, ino); 550 inode = f2fs_iget_retry(sbi->sb, ino);
540 if (IS_ERR(inode)) { 551 if (IS_ERR(inode)) {
@@ -555,17 +566,13 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
555 566
556 /* ENOMEM was fully retried in f2fs_evict_inode. */ 567 /* ENOMEM was fully retried in f2fs_evict_inode. */
557 if (ni.blk_addr != NULL_ADDR) { 568 if (ni.blk_addr != NULL_ADDR) {
558 int err = acquire_orphan_inode(sbi); 569 set_sbi_flag(sbi, SBI_NEED_FSCK);
559 570 f2fs_msg(sbi->sb, KERN_WARNING,
560 if (err) { 571 "%s: orphan failed (ino=%x), run fsck to fix.",
561 set_sbi_flag(sbi, SBI_NEED_FSCK); 572 __func__, ino);
562 f2fs_msg(sbi->sb, KERN_WARNING, 573 return -EIO;
563 "%s: orphan failed (ino=%x), run fsck to fix.",
564 __func__, ino);
565 return err;
566 }
567 __add_ino_entry(sbi, ino, ORPHAN_INO);
568 } 574 }
575 __remove_ino_entry(sbi, ino, ORPHAN_INO);
569 return 0; 576 return 0;
570} 577}
571 578
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 95986a9aa615..e7bb153f8104 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1893,6 +1893,7 @@ free_root_inode:
1893 sb->s_root = NULL; 1893 sb->s_root = NULL;
1894free_node_inode: 1894free_node_inode:
1895 mutex_lock(&sbi->umount_mutex); 1895 mutex_lock(&sbi->umount_mutex);
1896 release_ino_entry(sbi, true);
1896 f2fs_leave_shrinker(sbi); 1897 f2fs_leave_shrinker(sbi);
1897 iput(sbi->node_inode); 1898 iput(sbi->node_inode);
1898 mutex_unlock(&sbi->umount_mutex); 1899 mutex_unlock(&sbi->umount_mutex);