From: Zhao Lei <zhao...@cn.fujitsu.com> Btrfs will report NO_SPACE when we create and remove files for several times: 1: Create a single-dev btrfs fs with default option 2: Write a file into it to take up most fs space 3: Delete above file 4: Wait about 100s to let chunk removed 5: goto 2
Script is like following: #!/bin/bash # Recommend 1.2G space, too large disk will make test slow DEV="/dev/sda16" MNT="/mnt/tmp" dev_size="$(lsblk -bn -o SIZE "$DEV")" || exit 2 file_size_m=$((dev_size * 75 / 100 / 1024 / 1024)) echo "Loop write ${file_size_m}M file on $((dev_size / 1024 / 1024))M dev" for ((i = 0; i < 10; i++)); do umount "$MNT" 2>/dev/null; done echo "mkfs $DEV" mkfs.btrfs -f "$DEV" >/dev/null || exit 2 echo "mount $DEV $MNT" mount "$DEV" "$MNT" || exit 2 for ((loop_i = 0; loop_i < 20; loop_i++)); do echo echo "loop $loop_i" echo "dd file..." cmd=(dd if=/dev/zero of="$MNT"/file0 bs=1M count="$file_size_m") "${cmd[@]}" 2>/dev/null || { # NO_SPACE error triggered echo "dd failed: ${cmd[*]}" exit 1 } echo "rm file..." rm -f "$MNT"/file0 || exit 2 for ((i = 0; i < 10; i++)); do df "$MNT" | tail -1 sleep 10 done done Reason: It is triggered by commit: 47ab2a6c689913db23ccae38349714edf8365e0a which is used to remove empty block groups automatically, but the reason is not in that patch. Code before works well because btrfs don't need to create and delete chunks so many times and with high complexity. Reason1: Btrfs get free disk space by calling find_free_dev_extent() when re-create chunk for write, but current code set search_commit_root flag in searching tree, so disk spaces which was freed from dev_tree but not commited can not get from find_free_dev_extent(), then btrfs report NO_SPACE on above case. Fixed in patch 1/2. Reason2: When we remove some continuous chunks but leave other chunks after, these disk space should be used by chunk-recreating, but in current code, only first create will successed. Fixed in patch 2/2. Reason3: contains_pending_extent() return wrong value in calculation. Fixed by Forrest Liu <forre...@synology.com> in: Btrfs: fix find_free_dev_extent() malfunction in case device tree has hole Tested by above script, and confirmed action with many printk. Reported-by: Tsutomu Itoh <t-i...@jp.fujitsu.com> Signed-off-by: Zhao Lei <zhao...@cn.fujitsu.com> Zhao Lei (2): btrfs: Fix out-of-space bug caused by searching commit_root in find_free_dev_extent() btrfs: Set hole_size to free space in case of contains_pending_extent fs/btrfs/volumes.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) -- 1.8.5.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html