summaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dir.c
diff options
context:
space:
mode:
authorJunxiao Bi <junxiao.bi@oracle.com>2014-12-18 16:17:32 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-18 19:08:11 -0800
commitf62f12b3a426c8f65b10011b1ec40ba4277cbf5f (patch)
tree08e41966685e3bd305089e9a5aed257a2272461c /fs/ocfs2/dir.c
parentd82fa87d2b60e8affea3b244ad23c5d9a59c584a (diff)
downloadlinux-f62f12b3a426c8f65b10011b1ec40ba4277cbf5f.tar.gz
linux-f62f12b3a426c8f65b10011b1ec40ba4277cbf5f.tar.bz2
linux-f62f12b3a426c8f65b10011b1ec40ba4277cbf5f.zip
ocfs2: reflink: fix slow unlink for refcounted file
When running ocfs2 test suite multiple nodes reflink stress test, for a 4 nodes cluster, every unlink() for refcounted file needs about 700s. The slow unlink is caused by the contention of refcount tree lock since all nodes are unlink files using the same refcount tree. When the unlinking file have many extents(over 1600 in our test), most of the extents has refcounted flag set. In ocfs2_commit_truncate(), it will execute the following call trace for every extents. This means it needs get and released refcount tree lock about 1600 times. And when several nodes are do this at the same time, the performance will be very low. ocfs2_remove_btree_range() -- ocfs2_lock_refcount_tree() ---- ocfs2_refcount_lock() ------ __ocfs2_cluster_lock() ocfs2_refcount_lock() is costly, move it to ocfs2_commit_truncate() to do lock/unlock once can improve a lot performance. Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com> Cc: Wengang <wen.gang.wang@oracle.com> Reviewed-by: Mark Fasheh <mfasheh@suse.de> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2/dir.c')
-rw-r--r--fs/ocfs2/dir.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 79d56dc981bc..319e786175af 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -4479,7 +4479,7 @@ int ocfs2_dx_dir_truncate(struct inode *dir, struct buffer_head *di_bh)
p_cpos = ocfs2_blocks_to_clusters(dir->i_sb, blkno);
ret = ocfs2_remove_btree_range(dir, &et, cpos, p_cpos, clen, 0,
- &dealloc, 0);
+ &dealloc, 0, false);
if (ret) {
mlog_errno(ret);
goto out;