[RFC PATCH] btrfs: Write as many copies as possible if the current RAID1 profile is unreachable

Logan Finley <[email protected]>
Newsgroups org.kernel.vger.linux-btrfs
Message-ID <[email protected]>
While testing a three-disk btrfs filesystem consisting of only RAID1C3
block groups, I noticed that if I unmounted the filesystem, wiped one of
the disks, and then remounted the filesystem from the remaining two disks
with `-o degraded`, after a certain point new data begins to be written
into a "single" block group.

It appears that some data is initially written into the existing RAID1C3
chunks, but once enough data is written such that a new chunk needs to
be allocated, the next chunk allocated uses the "single" profile.

I'm not sure of a good way to fill up the System and Metadata block groups
enough to trigger a new chunk to be allocated, so I wasn't able to see
whether they also allocate "single"-profile chunks.

This was unexpected, since, to me, one of the benefits of RAID1C3 was more
time to keep operating safely (albeit in a degraded state) while an
operator makes their way to a machine to physically replace the failed
disk. With the current behavior, it seems that this isn't a valid use case
because any further disk failure could lead to the loss of newly written
data.

This (admittedly naive) patch modifies this behavior so that the RAID1
family of profiles writes as many copies as possible in a degraded state
when there are not enough disks present to write data in the configured
RAID profile.

Signed-off-by: Logan Finley <[email protected]>
---
What I'm looking for is feedback on whether this sort of patch is
desired upstream, whether the approach is valid, and whether or not
there are any gotchas I may have missed in the implementation.

Testing was done on an x86_64 qemu vm at commit a13307e97d5c ("Merge tag
'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf")
on the kdave/linux tree.
---
 fs/btrfs/block-group.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 8def7abb728f..50a21a0d8765 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -176,6 +176,12 @@ u64 btrfs_get_alloc_profile(struct btrfs_fs_info *fs_info, u64 orig_flags)
 			flags |= fs_info->avail_metadata_alloc_bits;
 	} while (read_seqretry(&fs_info->profiles_lock, seq));
 
+	/* Degrade to a less redundant, but still redundant, RAID1 profile if possible. */
+	if (flags & BTRFS_BLOCK_GROUP_RAID1C4)
+		flags |= BTRFS_BLOCK_GROUP_RAID1C3 | BTRFS_BLOCK_GROUP_RAID1;
+	else if (flags & BTRFS_BLOCK_GROUP_RAID1C3)
+		flags |= BTRFS_BLOCK_GROUP_RAID1;
+
 	return btrfs_reduce_alloc_profile(fs_info, flags);
 }
 
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.