diff options
-rw-r--r-- | fs/f2fs/data.c | 7 | ||||
-rw-r--r-- | fs/f2fs/namei.c | 6 | ||||
-rw-r--r-- | fs/f2fs/super.c | 15 |
3 files changed, 26 insertions, 2 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 2db9380f5dda..61b44542417c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -577,6 +577,7 @@ static int f2fs_write_data_pages(struct address_space *mapping, | |||
577 | { | 577 | { |
578 | struct inode *inode = mapping->host; | 578 | struct inode *inode = mapping->host; |
579 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | 579 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
580 | bool locked = false; | ||
580 | int ret; | 581 | int ret; |
581 | long excess_nrtw = 0, desired_nrtw; | 582 | long excess_nrtw = 0, desired_nrtw; |
582 | 583 | ||
@@ -590,10 +591,12 @@ static int f2fs_write_data_pages(struct address_space *mapping, | |||
590 | wbc->nr_to_write = desired_nrtw; | 591 | wbc->nr_to_write = desired_nrtw; |
591 | } | 592 | } |
592 | 593 | ||
593 | if (!S_ISDIR(inode->i_mode)) | 594 | if (!S_ISDIR(inode->i_mode)) { |
594 | mutex_lock(&sbi->writepages); | 595 | mutex_lock(&sbi->writepages); |
596 | locked = true; | ||
597 | } | ||
595 | ret = write_cache_pages(mapping, wbc, __f2fs_writepage, mapping); | 598 | ret = write_cache_pages(mapping, wbc, __f2fs_writepage, mapping); |
596 | if (!S_ISDIR(inode->i_mode)) | 599 | if (locked) |
597 | mutex_unlock(&sbi->writepages); | 600 | mutex_unlock(&sbi->writepages); |
598 | f2fs_submit_bio(sbi, DATA, (wbc->sync_mode == WB_SYNC_ALL)); | 601 | f2fs_submit_bio(sbi, DATA, (wbc->sync_mode == WB_SYNC_ALL)); |
599 | 602 | ||
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 4aa26e53c935..47abc9722b17 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -72,6 +72,7 @@ out: | |||
72 | unlock_new_inode(inode); | 72 | unlock_new_inode(inode); |
73 | fail: | 73 | fail: |
74 | trace_f2fs_new_inode(inode, err); | 74 | trace_f2fs_new_inode(inode, err); |
75 | make_bad_inode(inode); | ||
75 | iput(inode); | 76 | iput(inode); |
76 | if (nid_free) | 77 | if (nid_free) |
77 | alloc_nid_failed(sbi, ino); | 78 | alloc_nid_failed(sbi, ino); |
@@ -155,6 +156,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
155 | out: | 156 | out: |
156 | clear_nlink(inode); | 157 | clear_nlink(inode); |
157 | unlock_new_inode(inode); | 158 | unlock_new_inode(inode); |
159 | make_bad_inode(inode); | ||
158 | iput(inode); | 160 | iput(inode); |
159 | alloc_nid_failed(sbi, ino); | 161 | alloc_nid_failed(sbi, ino); |
160 | return err; | 162 | return err; |
@@ -190,6 +192,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, | |||
190 | return 0; | 192 | return 0; |
191 | out: | 193 | out: |
192 | clear_inode_flag(F2FS_I(inode), FI_INC_LINK); | 194 | clear_inode_flag(F2FS_I(inode), FI_INC_LINK); |
195 | make_bad_inode(inode); | ||
193 | iput(inode); | 196 | iput(inode); |
194 | return err; | 197 | return err; |
195 | } | 198 | } |
@@ -295,6 +298,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | |||
295 | out: | 298 | out: |
296 | clear_nlink(inode); | 299 | clear_nlink(inode); |
297 | unlock_new_inode(inode); | 300 | unlock_new_inode(inode); |
301 | make_bad_inode(inode); | ||
298 | iput(inode); | 302 | iput(inode); |
299 | alloc_nid_failed(sbi, inode->i_ino); | 303 | alloc_nid_failed(sbi, inode->i_ino); |
300 | return err; | 304 | return err; |
@@ -335,6 +339,7 @@ out_fail: | |||
335 | clear_inode_flag(F2FS_I(inode), FI_INC_LINK); | 339 | clear_inode_flag(F2FS_I(inode), FI_INC_LINK); |
336 | clear_nlink(inode); | 340 | clear_nlink(inode); |
337 | unlock_new_inode(inode); | 341 | unlock_new_inode(inode); |
342 | make_bad_inode(inode); | ||
338 | iput(inode); | 343 | iput(inode); |
339 | alloc_nid_failed(sbi, inode->i_ino); | 344 | alloc_nid_failed(sbi, inode->i_ino); |
340 | return err; | 345 | return err; |
@@ -382,6 +387,7 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, | |||
382 | out: | 387 | out: |
383 | clear_nlink(inode); | 388 | clear_nlink(inode); |
384 | unlock_new_inode(inode); | 389 | unlock_new_inode(inode); |
390 | make_bad_inode(inode); | ||
385 | iput(inode); | 391 | iput(inode); |
386 | alloc_nid_failed(sbi, inode->i_ino); | 392 | alloc_nid_failed(sbi, inode->i_ino); |
387 | return err; | 393 | return err; |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 5835aaf2fe2e..cd0e89a1ff8f 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -98,6 +98,20 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) | |||
98 | return &fi->vfs_inode; | 98 | return &fi->vfs_inode; |
99 | } | 99 | } |
100 | 100 | ||
101 | static int f2fs_drop_inode(struct inode *inode) | ||
102 | { | ||
103 | /* | ||
104 | * This is to avoid a deadlock condition like below. | ||
105 | * writeback_single_inode(inode) | ||
106 | * - f2fs_write_data_page | ||
107 | * - f2fs_gc -> iput -> evict | ||
108 | * - inode_wait_for_writeback(inode) | ||
109 | */ | ||
110 | if (!inode_unhashed(inode) && inode->i_state & I_SYNC) | ||
111 | return 0; | ||
112 | return generic_drop_inode(inode); | ||
113 | } | ||
114 | |||
101 | static void f2fs_i_callback(struct rcu_head *head) | 115 | static void f2fs_i_callback(struct rcu_head *head) |
102 | { | 116 | { |
103 | struct inode *inode = container_of(head, struct inode, i_rcu); | 117 | struct inode *inode = container_of(head, struct inode, i_rcu); |
@@ -232,6 +246,7 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) | |||
232 | 246 | ||
233 | static struct super_operations f2fs_sops = { | 247 | static struct super_operations f2fs_sops = { |
234 | .alloc_inode = f2fs_alloc_inode, | 248 | .alloc_inode = f2fs_alloc_inode, |
249 | .drop_inode = f2fs_drop_inode, | ||
235 | .destroy_inode = f2fs_destroy_inode, | 250 | .destroy_inode = f2fs_destroy_inode, |
236 | .write_inode = f2fs_write_inode, | 251 | .write_inode = f2fs_write_inode, |
237 | .show_options = f2fs_show_options, | 252 | .show_options = f2fs_show_options, |