[PATCH 4/4] f2fs: handle errors during recover_orphan_inodes

2016-09-21 Thread Jaegeuk Kim
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:[]  [] 
f2fs_evict_inode+0x433/0x470 [f2fs]
RSP: 0018:92f8b7fb7c30  EFLAGS: 00010246
RAX: 92fb88a13500 RBX: 92f890566ea0 RCX: fd3c255c
RDX: 0001 RSI: 92fb88a13d90 RDI: 92fb8ee127e8
RBP: 92f8b7fb7c58 R08: 0001 R09: 92fb88a13d58
R10: 5a6a9373 R11: 0001 R12: fffb
R13: 92fb8ee12000 R14: 34ca R15: 92fb8ee12620
FS:  7f1fefd8e880() GS:92fb9560() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 7fc211d34cdb CR3: 00012d43a000 CR4: 001406e0
Stack:
 92f890566ea0 92f890567078 c0b5a0c0 92f890566f28
 92fb888b2000 92f8b7fb7c80 bc27ff55 92f890566ea0
 92fb8bf1 c0b5a0c0 92f8b7fb7cb0 bc28090d
Call Trace:
 [] evict+0xc5/0x1a0
 [] iput+0x1ad/0x2c0
 [] recover_orphan_inodes+0x10c/0x2e0 [f2fs]
 [] f2fs_fill_super+0x884/0x1150 [f2fs]
 [] mount_bdev+0x18c/0x1c0
 [] ? f2fs_commit_super+0x100/0x100 [f2fs]
 [] f2fs_mount+0x15/0x20 [f2fs]
 [] mount_fs+0x39/0x170
 [] vfs_kern_mount+0x6b/0x160
 [] do_mount+0x1cf/0xd00
 [] ? copy_mount_options+0xac/0x170
 [] SyS_mount+0x83/0xd0
 [] entry_SYSCALL_64_fastpath+0x23/0xc1

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/checkpoint.c | 27 +--
 fs/f2fs/super.c  |  1 +
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index cd9fd7b..d1560bb 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)
 {
struct inode *inode;
struct node_info ni;
+   int err = acquire_orphan_inode(sbi);
+
+   if (err) {
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   f2fs_msg(sbi->sb, KERN_WARNING,
+   "%s: orphan failed (ino=%x), run fsck to fix.",
+   __func__, ino);
+   return err;
+   }
+
+   __add_ino_entry(sbi, ino, ORPHAN_INO);
 
inode = f2fs_iget_retry(sbi->sb, ino);
if (IS_ERR(inode)) {
@@ -555,17 +566,13 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, 
nid_t ino)
 
/* ENOMEM was fully retried in f2fs_evict_inode. */
if (ni.blk_addr != NULL_ADDR) {
-   int err = acquire_orphan_inode(sbi);
-
-   if (err) {
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   f2fs_msg(sbi->sb, KERN_WARNING,
-   "%s: orphan failed (ino=%x), run fsck to fix.",
-   __func__, ino);
-   return err;
-   }
-   __add_ino_entry(sbi, ino, ORPHAN_INO);
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   f2fs_msg(sbi->sb, KERN_WARNING,
+   "%s: orphan failed (ino=%x), run fsck to fix.",
+   __func__, ino);
+   return -EIO;
}
+   __remove_ino_entry(sbi, ino, ORPHAN_INO);
return 0;
 }
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 95986a9..e7bb153 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1893,6 +1893,7 @@ free_root_inode:
sb->s_root = NULL;
 free_node_inode:
mutex_lock(>umount_mutex);
+   release_ino_entry(sbi, true);
f2fs_leave_shrinker(sbi);
iput(sbi->node_inode);
mutex_unlock(>umount_mutex);
-- 
2.8.3



[PATCH 4/4] f2fs: handle errors during recover_orphan_inodes

2016-09-21 Thread Jaegeuk Kim
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:[]  [] 
f2fs_evict_inode+0x433/0x470 [f2fs]
RSP: 0018:92f8b7fb7c30  EFLAGS: 00010246
RAX: 92fb88a13500 RBX: 92f890566ea0 RCX: fd3c255c
RDX: 0001 RSI: 92fb88a13d90 RDI: 92fb8ee127e8
RBP: 92f8b7fb7c58 R08: 0001 R09: 92fb88a13d58
R10: 5a6a9373 R11: 0001 R12: fffb
R13: 92fb8ee12000 R14: 34ca R15: 92fb8ee12620
FS:  7f1fefd8e880() GS:92fb9560() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 7fc211d34cdb CR3: 00012d43a000 CR4: 001406e0
Stack:
 92f890566ea0 92f890567078 c0b5a0c0 92f890566f28
 92fb888b2000 92f8b7fb7c80 bc27ff55 92f890566ea0
 92fb8bf1 c0b5a0c0 92f8b7fb7cb0 bc28090d
Call Trace:
 [] evict+0xc5/0x1a0
 [] iput+0x1ad/0x2c0
 [] recover_orphan_inodes+0x10c/0x2e0 [f2fs]
 [] f2fs_fill_super+0x884/0x1150 [f2fs]
 [] mount_bdev+0x18c/0x1c0
 [] ? f2fs_commit_super+0x100/0x100 [f2fs]
 [] f2fs_mount+0x15/0x20 [f2fs]
 [] mount_fs+0x39/0x170
 [] vfs_kern_mount+0x6b/0x160
 [] do_mount+0x1cf/0xd00
 [] ? copy_mount_options+0xac/0x170
 [] SyS_mount+0x83/0xd0
 [] entry_SYSCALL_64_fastpath+0x23/0xc1

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/checkpoint.c | 27 +--
 fs/f2fs/super.c  |  1 +
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index cd9fd7b..d1560bb 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)
 {
struct inode *inode;
struct node_info ni;
+   int err = acquire_orphan_inode(sbi);
+
+   if (err) {
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   f2fs_msg(sbi->sb, KERN_WARNING,
+   "%s: orphan failed (ino=%x), run fsck to fix.",
+   __func__, ino);
+   return err;
+   }
+
+   __add_ino_entry(sbi, ino, ORPHAN_INO);
 
inode = f2fs_iget_retry(sbi->sb, ino);
if (IS_ERR(inode)) {
@@ -555,17 +566,13 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, 
nid_t ino)
 
/* ENOMEM was fully retried in f2fs_evict_inode. */
if (ni.blk_addr != NULL_ADDR) {
-   int err = acquire_orphan_inode(sbi);
-
-   if (err) {
-   set_sbi_flag(sbi, SBI_NEED_FSCK);
-   f2fs_msg(sbi->sb, KERN_WARNING,
-   "%s: orphan failed (ino=%x), run fsck to fix.",
-   __func__, ino);
-   return err;
-   }
-   __add_ino_entry(sbi, ino, ORPHAN_INO);
+   set_sbi_flag(sbi, SBI_NEED_FSCK);
+   f2fs_msg(sbi->sb, KERN_WARNING,
+   "%s: orphan failed (ino=%x), run fsck to fix.",
+   __func__, ino);
+   return -EIO;
}
+   __remove_ino_entry(sbi, ino, ORPHAN_INO);
return 0;
 }
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 95986a9..e7bb153 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1893,6 +1893,7 @@ free_root_inode:
sb->s_root = NULL;
 free_node_inode:
mutex_lock(>umount_mutex);
+   release_ino_entry(sbi, true);
f2fs_leave_shrinker(sbi);
iput(sbi->node_inode);
mutex_unlock(>umount_mutex);
-- 
2.8.3