kernel_optimize_test/fs/btrfs
Qu Wenruo 509e9710b8 btrfs: repair super block num_devices automatically
commit d201238ccd2f30b9bfcfadaeae0972e3a486a176 upstream.

[BUG]
There is a report that a btrfs has a bad super block num devices.

This makes btrfs to reject the fs completely.

  BTRFS error (device sdd3): super_num_devices 3 mismatch with num_devices 2 found here
  BTRFS error (device sdd3): failed to read chunk tree: -22
  BTRFS error (device sdd3): open_ctree failed

[CAUSE]
During btrfs device removal, chunk tree and super block num devs are
updated in two different transactions:

  btrfs_rm_device()
  |- btrfs_rm_dev_item(device)
  |  |- trans = btrfs_start_transaction()
  |  |  Now we got transaction X
  |  |
  |  |- btrfs_del_item()
  |  |  Now device item is removed from chunk tree
  |  |
  |  |- btrfs_commit_transaction()
  |     Transaction X got committed, super num devs untouched,
  |     but device item removed from chunk tree.
  |     (AKA, super num devs is already incorrect)
  |
  |- cur_devices->num_devices--;
  |- cur_devices->total_devices--;
  |- btrfs_set_super_num_devices()
     All those operations are not in transaction X, thus it will
     only be written back to disk in next transaction.

So after the transaction X in btrfs_rm_dev_item() committed, but before
transaction X+1 (which can be minutes away), a power loss happen, then
we got the super num mismatch.

This has been fixed by commit bbac58698a55 ("btrfs: remove device item
and update super block in the same transaction").

[FIX]
Make the super_num_devices check less strict, converting it from a hard
error to a warning, and reset the value to a correct one for the current
or next transaction commit.

As the number of device items is the critical information where the
super block num_devices is only a cached value (and also useful for
cross checking), it's safe to automatically update it. Other device
related problems like missing device are handled after that and may
require other means to resolve, like degraded mount. With this fix,
potentially affected filesystems won't fail mount and require the manual
repair by btrfs check.

Reported-by: Luca Béla Palkovics <luca.bela.palkovics@gmail.com>
Link: https://lore.kernel.org/linux-btrfs/CA+8xDSpvdm_U0QLBAnrH=zqDq_cWCOH5TiV46CKmp3igr44okQ@mail.gmail.com/
CC: stable@vger.kernel.org # 4.14+
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-09 10:20:49 +02:00
..
tests
acl.c
async-thread.c btrfs: fix memory ordering between normal and ordered work functions 2021-11-26 10:39:20 +01:00
async-thread.h
backref.c btrfs: remove BUG_ON(!eie) in find_parent_nodes 2022-01-27 10:54:19 +01:00
backref.h btrfs: add asserts for deleting backref cache nodes 2021-03-04 11:38:29 +01:00
block-group.c btrfs: remove unused variable in btrfs_{start,write}_dirty_block_groups() 2022-04-20 09:23:10 +02:00
block-group.h btrfs: fix race between writes to swap files and scrub 2021-03-09 11:11:11 +01:00
block-rsv.c
block-rsv.h
btrfs_inode.h btrfs: fix race between marking inode needs to be logged and log syncing 2021-09-03 10:09:28 +02:00
check-integrity.c
check-integrity.h
compression.c btrfs: mark compressed range uptodate only if all bio succeed 2021-08-04 12:46:39 +02:00
compression.h
ctree.c btrfs: check the root node for uptodate before returning it 2022-01-27 10:54:27 +01:00
ctree.h btrfs: fix race between writes to swap files and scrub 2021-03-09 11:11:11 +01:00
delalloc-space.c
delalloc-space.h
delayed-inode.c btrfs: abort transaction if we fail to update the delayed inode 2021-07-14 16:55:55 +02:00
delayed-inode.h
delayed-ref.c btrfs: account for new extents being deleted in total_bytes_pinned 2021-03-04 11:38:30 +01:00
delayed-ref.h btrfs: handle space_info::total_bytes_pinned inside the delayed ref itself 2021-03-04 11:38:30 +01:00
dev-replace.c btrfs: fix deadlock when cloning inline extent and low on free metadata space 2021-01-17 14:16:54 +01:00
dev-replace.h
dir-item.c
discard.c btrfs: merge critical sections of discard lock in workfn 2021-01-19 18:27:24 +01:00
discard.h
disk-io.c btrfs: add "0x" prefix for unsupported optional features 2022-06-09 10:20:49 +02:00
disk-io.h
export.c
export.h
extent_io.c btrfs: clear extent buffer uptodate when we fail to write it 2021-12-14 11:32:38 +01:00
extent_io.h btrfs: fix qgroup reserve overflow the qgroup limit 2022-04-13 21:01:08 +02:00
extent_map.c
extent_map.h
extent-io-tree.h
extent-tree.c btrfs: unlock newly allocated extent buffer after error 2021-10-20 11:44:59 +02:00
file-item.c btrfs: replace BUG_ON() in btrfs_csum_one_bio() with proper error handling 2021-10-09 14:40:56 +02:00
file.c btrfs: fix fallocate to use file_modified to update permissions consistently 2022-04-20 09:23:19 +02:00
free-space-cache.c btrfs: fix race between extent freeing/allocation when using bitmaps 2021-03-09 11:11:11 +01:00
free-space-cache.h
free-space-tree.c btrfs: fix possible free space tree corruption with online conversion 2021-02-03 23:28:40 +01:00
free-space-tree.h
inode-item.c
inode-map.c
inode-map.h
inode.c btrfs: do not warn for free space inode in cow_file_range 2022-04-20 09:23:19 +02:00
ioctl.c fsnotify: invalidate dcache before IN_DELETE event 2022-02-01 17:25:48 +01:00
Kconfig btrfs: disable build on platforms having page size 256K 2021-07-14 16:55:56 +02:00
locking.c
locking.h
lzo.c
Makefile
misc.h
ordered-data.c
ordered-data.h
orphan.c
print-tree.c btrfs: print the actual offset in btrfs_root_name 2021-01-27 11:55:06 +01:00
print-tree.h btrfs: print the actual offset in btrfs_root_name 2021-01-27 11:55:06 +01:00
props.c
props.h
qgroup.c btrfs: qgroup: fix deadlock between rescan worker and remove qgroup 2022-03-08 19:09:38 +01:00
qgroup.h btrfs: export and rename qgroup_reserve_meta 2021-03-11 14:17:22 +01:00
raid56.c treewide: Change list_sort to use const pointers 2021-09-30 10:11:04 +02:00
raid56.h
rcu-string.h
reada.c
ref-verify.c
ref-verify.h
reflink.c btrfs: fix unexpected error path when reflinking an inline extent 2022-04-08 14:40:04 +02:00
reflink.h
relocation.c btrfs: convert logic BUG_ON()'s in replace_path to ASSERT()'s 2021-05-11 14:47:22 +02:00
root-tree.c btrfs: replace the BUG_ON in btrfs_del_root_ref with proper error handling 2021-12-14 11:32:38 +01:00
scrub.c btrfs: fix race between writes to swap files and scrub 2021-03-09 11:11:11 +01:00
send.c btrfs: send: in case of IO error log it 2022-02-23 12:00:58 +01:00
send.h
space-info.c btrfs: prevent __btrfs_dump_space_info() to underflow its free space 2021-09-30 10:11:00 +02:00
space-info.h btrfs: handle space_info::total_bytes_pinned inside the delayed ref itself 2021-03-04 11:38:30 +01:00
struct-funcs.c
super.c btrfs: fix transaction leak and crash after RO remount caused by qgroup rescan 2021-01-19 18:27:24 +01:00
sysfs.c btrfs: sysfs: fix format string for some discard stats 2021-07-14 16:55:55 +02:00
sysfs.h
transaction.c btrfs: clear defrag status of a root if starting transaction fails 2021-07-14 16:55:40 +02:00
transaction.h btrfs: fix race between marking inode needs to be logged and log syncing 2021-09-03 10:09:28 +02:00
tree-checker.c btrfs: tree-checker: check item_size for dev_item 2022-03-02 11:42:45 +01:00
tree-checker.h
tree-defrag.c
tree-log.c btrfs: always log symlinks in full mode 2022-05-12 12:25:43 +02:00
tree-log.h
ulist.c
ulist.h
uuid-tree.c
volumes.c btrfs: repair super block num_devices automatically 2022-06-09 10:20:49 +02:00
volumes.h btrfs: fix lockdep warning due to seqcount_mutex on 32bit arch 2021-02-03 23:28:40 +01:00
xattr.c btrfs: fix warning when creating a directory with smack enabled 2021-03-09 11:11:12 +01:00
xattr.h
zlib.c
zstd.c