Skip to contentSkip to conversation

btrfs: Allow more disks missing for RAID10

PATCH In review Qu Wenruo 4 participants 7 messages Jul 18, 2019 – Jul 31, 2019 Btrfs file system

lore
Share & tools
lore

Qu Wenruo

author
#0 lore raw

PATCH 1/1 btrfs: Allow more disks missing for RAID10

RAID10 can accept as much as half of its disks to be missing, as long as each sub stripe still has a good mirror.

Thanks to the per-chunk degradable check, we can handle it pretty easily now.

So Add this special check for RAID10, to allow user to be creative (or crazy) using btrfs RAID10.

---
 fs/btrfs/volumes.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
fs/btrfs/volumes.c +45 -0
index f209127a8bc6..65b10d13fc2d 100644
@@ -7088,6 +7088,42 @@ int btrfs_read_sys_array(struct btrfs_fs_info *fs_info)
 	return -EIO;
 }
 
+static bool check_raid10_rw_degradable(struct btrfs_fs_info *fs_info,
+				       struct extent_map *em)
+{
+	struct map_lookup *map = em->map_lookup;
+	int sub_stripes = map->sub_stripes;
+	int num_stripes = map->num_stripes;
+	int tolerance = 1;
+	int i, j;
+
+	ASSERT(sub_stripes == 2);
+	ASSERT(num_stripes % sub_stripes == 0);
+	/*
+	 * Check substripes as a group, in each group we need to
+	 * have at least one good mirror;
+	 */
+	for (i = 0; i < num_stripes / sub_stripes; i ++) {
+		int missing = 0;
+		for (j = 0; j < sub_stripes; j++) {
+			struct btrfs_device *dev = map->stripes[i * 2 + j].dev;
+
+			if (!dev || !dev->bdev ||
+			    test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state) ||
+			    dev->last_flush_error)
+				missing++;
+		}
+		if (missing > tolerance) {
+			btrfs_warn(fs_info,
+"chunk %llu stripes %d,%d missing %d devices, max tolerance is %d for writable mount",
+				   em->start, i, i + sub_stripes - 1, missing,
+				   tolerance);
+			return false;
+		}
+	}
+	return true;
+}
+
 /*
  * Check if all chunks in the fs are OK for read-write degraded mount
  *
@@ -7119,6 +7155,14 @@ bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info,
 		int i;
 
 		map = em->map_lookup;
+		if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
+			ret = check_raid10_rw_degradable(fs_info, em);
+			if (!ret) {
+				free_extent_map(em);
+				goto out;
+			}
+			goto next;
+		}
 		max_tolerated =
 			btrfs_get_num_tolerated_disk_barrier_failures(
 					map->type);
@@ -7141,6 +7185,7 @@ bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info,
 			ret = false;
 			goto out;
 		}
+next:
 		next_start = extent_map_end(em);
 		free_extent_map(em);
 
Signature · 1 line
2.22.0
#1 lore raw
Quoted 2 lines · Qu Wenruo

RAID10 can accept as much as half of its disks to be missing, as long as each sub stripe still has a good mirror.

Can you please make a test case for that?

I think the number of devices that can be lost can be higher than a half in some extreme cases: one device has copies of all stripes, 2nd copy can be scattered randomly on the other devices, but that's highly unlikely to happen.

On average it's same as raid1, but the more exact check can potentially utilize the stripe layout.

#2 lore raw
Quoted 10 lines · David Sterba
Quoted 2 lines · Qu Wenruo

RAID10 can accept as much as half of its disks to be missing, as long as each sub stripe still has a good mirror.

Can you please make a test case for that?

I think the number of devices that can be lost can be higher than a half in some extreme cases: one device has copies of all stripes, 2nd copy can be scattered randomly on the other devices, but that's highly unlikely to happen.

It is possible, but as you mention highly unlikely. It's also possible with raid1 mode too, and a lot less unlikely there (in fact, it's almost guaranteed to happen in certain configurations).

Quoted 4 lines

On average it's same as raid1, but the more exact check can potentially utilize the stripe layout.

#3 lore raw
In reply to David Sterba
Quoted 5 lines · David Sterba
Quoted 2 lines · Qu Wenruo

RAID10 can accept as much as half of its disks to be missing, as long as each sub stripe still has a good mirror.

Can you please make a test case for that?

Fstests one or btrfs-progs one?

Quoted 9 lines

I think the number of devices that can be lost can be higher than a half in some extreme cases: one device has copies of all stripes, 2nd copy can be scattered randomly on the other devices, but that's highly unlikely to happen.

On average it's same as raid1, but the more exact check can potentially utilize the stripe layout.

That will be at extent level, to me it's an internal level violation, far from what we want to improve.

So not that worthy.

Thanks,
Qu

#4 lore raw
Quoted 10 lines · Qu Wenruo
Quoted 5 lines · David Sterba
Quoted 2 lines · Qu Wenruo

RAID10 can accept as much as half of its disks to be missing, as long as each sub stripe still has a good mirror.

Can you please make a test case for that?

Fstests one or btrfs-progs one?

For fstests.

Quoted 10 lines
Quoted 8 lines

I think the number of devices that can be lost can be higher than a half in some extreme cases: one device has copies of all stripes, 2nd copy can be scattered randomly on the other devices, but that's highly unlikely to happen.

On average it's same as raid1, but the more exact check can potentially utilize the stripe layout.

That will be at extent level, to me it's an internal level violation, far from what we want to improve.

Ah I don't mean to go the extent level, as you implemented it is enough and an improvement.

#5 lore raw
Quoted 5 lines · David Sterba
Quoted 4 lines · Qu Wenruo
Quoted 1 line · David Sterba

On Thu, Jul 18, 2019 at 02:27:49PM +0800, Qu Wenruo wrote:

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

RAID10 can accept as much as half of its disks to be missing, as long as each sub stripe still has a good mirror.

Can you please make a test case for that?

Fstests one or btrfs-progs one?

For fstests.

OK, that test case in fact exposed a long-existing bug, we can't create degraded chunks.

So if we're replacing the missing devices on a 4 disk RAID10 btrfs, we will hit ENOSPC as we can't find 4 devices to fulfill a new chunk. And it will finally trigger transaction abort.

Please discard this patch until we solve that problem.

Thanks,
Qu

Quoted 15 lines
Quoted 11 lines
Quoted 9 lines

I think the number of devices that can be lost can be higher than a half in some extreme cases: one device has copies of all stripes, 2nd copy can be scattered randomly on the other devices, but that's highly unlikely to happen.

On average it's same as raid1, but the more exact check can potentially utilize the stripe layout.

That will be at extent level, to me it's an internal level violation, far from what we want to improve.

Ah I don't mean to go the extent level, as you implemented it is enough and an improvement.

#6 lore raw
Quoted 17 lines · Qu Wenruo
Quoted 5 lines · David Sterba
Quoted 4 lines · Qu Wenruo
Quoted 1 line · David Sterba

On Thu, Jul 18, 2019 at 02:27:49PM +0800, Qu Wenruo wrote:

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

RAID10 can accept as much as half of its disks to be missing, as long as each sub stripe still has a good mirror.

Can you please make a test case for that?

Fstests one or btrfs-progs one?

For fstests.

Quoted 8 lines

OK, that test case in fact exposed a long-existing bug, we can't create degraded chunks.

So if we're replacing the missing devices on a 4 disk RAID10 btrfs, we will hit ENOSPC as we can't find 4 devices to fulfill a new chunk. And it will finally trigger transaction abort.

Please discard this patch until we solve that problem.

Ok, done.