[PATCH] btrfs: Fix no space bug caused by removing bg

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



btrfs in v4.3-rc1 failed many xfstests items with '-o nospace_cache'
mount option.

Failed cases are:
 btrfs/008,016,019,020,026,027,028,029,031,041,046,048,050,051,053,054,
 077,083,084,087,092,094
 generic/004,010,014,023,024,074,075,080,086,087,089,091,092,100,112,123,
 124,125,126,127,131,133,192,193,198,207,208,209,213,214,215,228,239,240,
 246,247,248,255,263,285,306,313,316,323

We can reproduce this bug with following simple command:
 TEST_DEV=/dev/vdh
 TEST_DIR=/mnt/tmp

 umount "$TEST_DEV" >/dev/null
 mkfs.btrfs -f "$TEST_DEV"
 mount "$TEST_DEV" "$TEST_DIR"

 umount "$TEST_DEV"
 mount "$TEST_DEV" "$TEST_DIR"

 cp /bin/bash $TEST_DIR

Result is:
 (omit previous commands)
 # cp /bin/bash $TEST_DIR
 cp: writing `/mnt/tmp/bash': No space left on device

By bisect, we can see it is triggered by patch titled:
 commit e44163e17796
 ("btrfs: explictly delete unused block groups in close_ctree and ro-remount")

But the wrong code is not in above patch, btrfs delete all chunks
if no data in filesystem, and above patch just make it obviously.

Detail reason:
 1: mkfs a blank filesystem, or delete everything in filesystem
 2: umount fs
    (current code will delete all data chunks)
 3: mount fs
    Because no any data chunks, data's space_cache have no chance
    to init, it means: space_info->total_bytes == 0, and
    space_info->full == 1.
 4: do some write
    Current code will ignore chunk allocate because space_info->full,
    and return -ENOSPC.

Fix:
 Don't auto-delete last blockgroup for a raid type.
 If we delete all blockgroup for a raidtype, it not only cause above bug,
 but also may change filesystem to all-single in some case.

Test:
 Test by above script, and confirmed the logic by debug output.

Signed-off-by: Zhao Lei <zhaolei@xxxxxxxxxxxxxx>
---
 fs/btrfs/extent-tree.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 5411f0a..35cf7eb 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -10012,7 +10012,8 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
 					       bg_list);
 		space_info = block_group->space_info;
 		list_del_init(&block_group->bg_list);
-		if (ret || btrfs_mixed_space_info(space_info)) {
+		if (ret || btrfs_mixed_space_info(space_info) ||
+		    block_group->list.next == block_group->list.prev) {
 			btrfs_put_block_group(block_group);
 			continue;
 		}
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux