btrfs: wait for delayed iputs on no space

btrfs will report no_space when we run following write and delete
file loop:
 # FILE_SIZE_M=[ 75% of fs space ]
 # DEV=[ some dev ]
 # MNT=[ some dir ]
 #
 # mkfs.btrfs -f "$DEV"
 # mount -o nodatacow "$DEV" "$MNT"
 # for ((i = 0; i < 100; i++)); do dd if=/dev/zero of="$MNT"/file0 bs=1M count="$FILE_SIZE_M"; rm -f "$MNT"/file0; done
 #

Reason:
 iput() and evict() is run after write pages to block device, if
 write pages work is not finished before next write, the "rm"ed space
 is not freed, and caused above bug.

Fix:
 We can add "-o flushoncommit" mount option to avoid above bug, but
 it have performance problem. Actually, we can to wait for on-the-fly
 writes only when no-space happened, it is which this patch do.

Signed-off-by: Zhao Lei <zhaolei@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
Zhao Lei 2015-04-09 12:34:43 +08:00 committed by Chris Mason
parent d672633545
commit 9a4e7276d3
1 changed files with 3 additions and 0 deletions

View File

@ -3918,6 +3918,9 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes, u64 write_bytes)
!atomic_read(&root->fs_info->open_ioctl_trans)) {
need_commit--;
if (need_commit > 0)
btrfs_wait_ordered_roots(fs_info, -1);
trans = btrfs_join_transaction(root);
if (IS_ERR(trans))
return PTR_ERR(trans);