aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2014-11-21 19:37:40 -0500
committerJaegeuk Kim <jaegeuk@kernel.org>2014-11-24 00:51:57 -0500
commit0341845efcb4a656707b6d551c3057d6dd27009f (patch)
tree1939d07eeaf6b094877eecc5aee10c560b22d265 /fs/f2fs
parent9486ba442b00a6b227bfe0d66b0f4dbcd1a2ee91 (diff)
f2fs: fix livelock calling f2fs_iget during f2fs_evict_inode
In f2fs_evict_inode, commit_inmemory_pages f2fs_gc f2fs_iget iget_locked -> wait for inode free Here, if the inode is same as the one to be evicted, f2fs should wait forever. Actually, we should not call f2fs_balance_fs during f2fs_evict_inode to avoid this. But, the commit_inmem_pages calls f2fs_balance_fs by default, even if f2fs_evict_inode wants to free inmemory pages only. Hence, this patch adds to trigger f2fs_balance_fs only when there is something to write. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/segment.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 9de857f6899b..9a33e34d26ce 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -230,7 +230,16 @@ void commit_inmem_pages(struct inode *inode, bool abort)
230 .rw = WRITE_SYNC, 230 .rw = WRITE_SYNC,
231 }; 231 };
232 232
233 f2fs_balance_fs(sbi); 233 /*
234 * The abort is true only when f2fs_evict_inode is called.
235 * Basically, the f2fs_evict_inode doesn't produce any data writes, so
236 * that we don't need to call f2fs_balance_fs.
237 * Otherwise, f2fs_gc in f2fs_balance_fs can wait forever until this
238 * inode becomes free by iget_locked in f2fs_iget.
239 */
240 if (!abort)
241 f2fs_balance_fs(sbi);
242
234 f2fs_lock_op(sbi); 243 f2fs_lock_op(sbi);
235 244
236 mutex_lock(&fi->inmem_lock); 245 mutex_lock(&fi->inmem_lock);