Commit 42bd8f4f authored by Zhao Lei's avatar Zhao Lei Committed by Sasha Levin

btrfs: wait for delayed iputs on no space

[ Upstream commit 9a4e7276 ]

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: default avatarZhao Lei <zhaolei@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
Signed-off-by: default avatarSasha Levin <sasha.levin@oracle.com>
parent ee6ad435
...@@ -3975,6 +3975,9 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes, u64 write_bytes) ...@@ -3975,6 +3975,9 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes, u64 write_bytes)
!atomic_read(&root->fs_info->open_ioctl_trans)) { !atomic_read(&root->fs_info->open_ioctl_trans)) {
need_commit--; need_commit--;
if (need_commit > 0)
btrfs_wait_ordered_roots(fs_info, -1);
trans = btrfs_join_transaction(root); trans = btrfs_join_transaction(root);
if (IS_ERR(trans)) if (IS_ERR(trans))
return PTR_ERR(trans); return PTR_ERR(trans);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment