Linux Btrfs filesystem development
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 0/4] btrfs: enhance primary super block writeback errors
Date: Thu, 28 Aug 2025 13:46:21 +0930	[thread overview]
Message-ID: <cover.1756353444.git.wqu@suse.com> (raw)

Mark recently exposed a bug that btrfs can add zero sized devices into
an fs.

Inspired by his fix, I also exposed a situation which is pretty
concerning:

 # lsblk  /dev/loop0
 NAME  MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
 loop0   7:0    0  64K  0 loop
 # mount /dev/test/scratch1  /mnt/btrfs/
 # btrfs device add -f /dev/loop0 /mnt/btrfs/
 Performing full device TRIM /dev/loop0 (64.00KiB) ...
 # umount /mnt/btrfs
 # mount /dev/test/scratch1 /mnt/btrfs
 mount: /mnt/btrfs: fsconfig() failed: No such file or directory.
       dmesg(1) may have more information after failed mount system call.
 # dmesg -t | tail -n4
 BTRFS info (device dm-3): using crc32c (crc32c-lib) checksum algorithm
 BTRFS error (device dm-3): devid 2 uuid e449b62e-faca-4cbd-b8cb-bcfb5c549f0b is missing
 BTRFS error (device dm-3): failed to read chunk tree: -2
 BTRFS error (device dm-3): open_ctree failed: -2

That device is too small to even have the primary super block, thus
btrfs just skips it, resulting the fs unable to find the new device in
the next mount.
(Thankfully this can be fixed by mounting degraded and remove the tiny
device)

This exposed several problems related to the super block writeback
behavior:

- We should always try to writeback the primary super block
  If the device is too small, it shouldn't be added in the first place.

  And even if such device is added, we should hit an critical error
  during the first transaction on that device.

- Primary super block write failure is ignored in write_dev_supers()
  Unlike wait_dev_supers(), if we failed to submit the primary sb, but
  succeeded submitting the backup ones, we still call it a aday.

- We treat super block writeback errors too loosely
  Btrfs will not error out even if there is only one device finished the
  super block.

Enhance the error handling by:

- Treat primary sb writeback error more seriously
  In fact we don't care that much about backups, and wait_dev_supers()
  is already doing that.

  So we don't need an atomic_t to track all sb writeback errors, but
  only a single flag for the primary sb.

- Treat newly added device more seriously
  If the super block write into the newly added device failed, it will
  prevent the fs to be mounted, as btrfs can not find the device.

  So here we introduce a concept, critical device, that if sb writeback
  failed for those devices, the transaction should be aborted.

- Treat sb writeback error as if the device is missing
  And if the fs can not handle the missing device and maintain RW, we
  should flip RO.

- Revert failed new device if btrfs_init_new_device() failed
  This can be a problem of the new device itself.
  We should remove the new device if the btrfs_commit_transaction() call
  failed.


All those enhancements lead to a pretty interesting error handling
situation, where a too small device can be added to btrfs, but it will
not commit, and the original fs can still be remounted again correctly:

 # lsblk  /dev/loop0
 NAME  MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
 loop0   7:0    0  64K  0 loop
 # mount /dev/test/scratch1  /mnt/btrfs/
 # btrfs device add -f /dev/loop0 /mnt/btrfs/
 Performing full device TRIM /dev/loop0 (64.00KiB) ...
 ERROR: error adding device '/dev/loop0': Input/output error
 # umount /mnt/btrfs
 # mount /dev/test/scratch1 /mnt/btrfs
 ^^^ This will succeed, as the new device is not committed

Qu Wenruo (4):
  btrfs: enhance primary super block write error detection
  btrfs: return error if the primary super block write to a new device
    failed
  btrfs: treat super block write back error more seriously
  btrfs: add extra error handling for btrfs_init_new_device()

 fs/btrfs/disk-io.c | 93 ++++++++++++++++++++++++++++++++++------------
 fs/btrfs/volumes.c |  9 +++--
 fs/btrfs/volumes.h |  8 +---
 3 files changed, 78 insertions(+), 32 deletions(-)

-- 
2.50.1


             reply	other threads:[~2025-08-28  4:16 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-28  4:16 Qu Wenruo [this message]
2025-08-28  4:16 ` [PATCH 1/4] btrfs: enhance primary super block write error detection Qu Wenruo
2025-08-28  4:16 ` [PATCH 2/4] btrfs: return error if the primary super block write to a new device failed Qu Wenruo
2025-08-28  4:16 ` [PATCH 3/4] btrfs: treat super block write back error more seriously Qu Wenruo
2025-08-28  4:16 ` [PATCH 4/4] btrfs: add extra error handling for btrfs_init_new_device() Qu Wenruo
2025-08-28  5:20 ` [PATCH 0/4] btrfs: enhance primary super block writeback errors Qu Wenruo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cover.1756353444.git.wqu@suse.com \
    --to=wqu@suse.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox