diff options
author | Eric Ren <zren@suse.com> | 2016-08-02 14:02:10 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-02 17:31:41 -0400 |
commit | 2070ad1aebfff2c26190188844c38e55d2df2ae2 (patch) | |
tree | 8e144229b87b8daf0767efb0e688d36ddad88f7a /fs/ocfs2/alloc.h | |
parent | 01a36b6758e723f919420ef20cea5fca1fc06e2b (diff) | |
download | linux-stable-2070ad1aebfff2c26190188844c38e55d2df2ae2.tar.gz linux-stable-2070ad1aebfff2c26190188844c38e55d2df2ae2.tar.bz2 linux-stable-2070ad1aebfff2c26190188844c38e55d2df2ae2.zip |
ocfs2: retry on ENOSPC if sufficient space in truncate log
The testcase "mmaptruncate" in ocfs2 test suite always fails with ENOSPC
error on small volume (say less than 10G). This testcase repeatedly
performs "extend" and "truncate" on a file. Continuously, it truncates
the file to 1/2 of the size, and then extends to 100% of the size. The
main bitmap will quickly run out of space because the "truncate" code
prevent truncate log from being flushed by
ocfs2_schedule_truncate_log_flush(osb, 1), while truncate log may have
cached lots of clusters.
So retry to allocate after flushing truncate log when ENOSPC is
returned. And we cannot reuse the deleted blocks before the transaction
committed. Fortunately, we already have a function to do this -
ocfs2_try_to_free_truncate_log(). Just need to remove the "static"
modifier and put it into the right place.
The "unlock"/"lock" code isn't elegant, but there seems to be no better
option.
[zren@suse.com: locking fix]
Link: http://lkml.kernel.org/r/1468031546-4797-1-git-send-email-zren@suse.com
Link: http://lkml.kernel.org/r/1466586469-5541-1-git-send-email-zren@suse.com
Signed-off-by: Eric Ren <zren@suse.com>
Reviewed-by: Gang He <ghe@suse.com>
Reviewed-by: Joseph Qi <joseph.qi@huawei.com>
Reviewed-by: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2/alloc.h')
-rw-r--r-- | fs/ocfs2/alloc.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index f3dc1b0dfffc..4a5152ec88a3 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h @@ -188,6 +188,8 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb, u64 start_blk, unsigned int num_clusters); int __ocfs2_flush_truncate_log(struct ocfs2_super *osb); +int ocfs2_try_to_free_truncate_log(struct ocfs2_super *osb, + unsigned int needed); /* * Process local structure which describes the block unlinks done |