[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