diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-11-21 16:37:40 -0800 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-11-23 21:51:57 -0800 |
commit | 0341845efcb4a656707b6d551c3057d6dd27009f (patch) | |
tree | 1939d07eeaf6b094877eecc5aee10c560b22d265 /fs/f2fs | |
parent | 9486ba442b00a6b227bfe0d66b0f4dbcd1a2ee91 (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.c | 11 |
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) .rw = WRITE_SYNC, }; - f2fs_balance_fs(sbi); + /* + * The abort is true only when f2fs_evict_inode is called. + * Basically, the f2fs_evict_inode doesn't produce any data writes, so + * that we don't need to call f2fs_balance_fs. + * Otherwise, f2fs_gc in f2fs_balance_fs can wait forever until this + * inode becomes free by iget_locked in f2fs_iget. + */ + if (!abort) + f2fs_balance_fs(sbi); + f2fs_lock_op(sbi); mutex_lock(&fi->inmem_lock); |