aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2014-06-06 14:05:03 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2014-06-06 14:18:36 -0400
commit86928f984e8b166fcd0c7c241501bc00f53eb623 (patch)
tree15ac0986725b469160baae2ed0fb1d598a63e996
parent6fa1df533a93161c54c987bbffaadf03563aa78d (diff)
f2fs: avoid not to call remove_dirty_inode
There is an errorneous case during the recovery like below. In recovery_dentry, 1) dir = f2fs_iget(); 2) mark the dir with FI_DELAY_IPUT 3) goto unmap_out After the end of recovery routine, there is no dirty dentries so the dir cannot be released by iput in remove_dirty_dir_inode. This patch fixes such the bug case by handling the iget and iput in the recovery_dentry procedure. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/recovery.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index e950a2f50ac1..a112368a4a86 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -52,20 +52,13 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
52 goto out; 52 goto out;
53 } 53 }
54 54
55 if (is_inode_flag_set(F2FS_I(dir), FI_DIRTY_DIR)) {
56 iput(dir);
57 } else {
58 add_dirty_dir_inode(dir);
59 set_inode_flag(F2FS_I(dir), FI_DELAY_IPUT);
60 }
61
62 name.len = le32_to_cpu(raw_inode->i_namelen); 55 name.len = le32_to_cpu(raw_inode->i_namelen);
63 name.name = raw_inode->i_name; 56 name.name = raw_inode->i_name;
64 57
65 if (unlikely(name.len > F2FS_NAME_LEN)) { 58 if (unlikely(name.len > F2FS_NAME_LEN)) {
66 WARN_ON(1); 59 WARN_ON(1);
67 err = -ENAMETOOLONG; 60 err = -ENAMETOOLONG;
68 goto out; 61 goto out_err;
69 } 62 }
70retry: 63retry:
71 de = f2fs_find_entry(dir, &name, &page); 64 de = f2fs_find_entry(dir, &name, &page);
@@ -90,11 +83,23 @@ retry:
90 goto retry; 83 goto retry;
91 } 84 }
92 err = __f2fs_add_link(dir, &name, inode); 85 err = __f2fs_add_link(dir, &name, inode);
86 if (err)
87 goto out_err;
88
89 if (is_inode_flag_set(F2FS_I(dir), FI_DELAY_IPUT)) {
90 iput(dir);
91 } else {
92 add_dirty_dir_inode(dir);
93 set_inode_flag(F2FS_I(dir), FI_DELAY_IPUT);
94 }
95
93 goto out; 96 goto out;
94 97
95out_unmap_put: 98out_unmap_put:
96 kunmap(page); 99 kunmap(page);
97 f2fs_put_page(page, 0); 100 f2fs_put_page(page, 0);
101out_err:
102 iput(dir);
98out: 103out:
99 f2fs_msg(inode->i_sb, KERN_NOTICE, 104 f2fs_msg(inode->i_sb, KERN_NOTICE,
100 "%s: ino = %x, name = %s, dir = %lx, err = %d", 105 "%s: ino = %x, name = %s, dir = %lx, err = %d",