Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-6.19-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:

- protect reading super block vs setting block size externally (found
by syzbot)

- make sure no transaction is started in read-only mode even with some
rescue mount option combinations

- fix checksum calculation of backup super blocks when block-group-tree
is enabled

- more extensive mount-time checks of device items that could be left
after device replace and attempting degraded mount

- fix build warning with -Wmaybe-uninitialized on loongarch64-gcc 12

* tag 'for-6.19-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: add extra device item checks at mount
btrfs: fix missing fields in superblock backup with BLOCK_GROUP_TREE
btrfs: reject new transactions if the fs is fully read-only
btrfs: sync read disk super and set block size
btrfs: fix Wmaybe-uninitialized warning in replay_one_buffer()

+73 -2
+18 -1
fs/btrfs/disk-io.c
··· 1661 1661 btrfs_set_backup_chunk_root_level(root_backup, 1662 1662 btrfs_header_level(info->chunk_root->node)); 1663 1663 1664 - if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) { 1664 + if (!btrfs_fs_incompat(info, EXTENT_TREE_V2)) { 1665 1665 struct btrfs_root *extent_root = btrfs_extent_root(info, 0); 1666 1666 struct btrfs_root *csum_root = btrfs_csum_root(info, 0); 1667 1667 ··· 3255 3255 return 0; 3256 3256 } 3257 3257 3258 + static bool fs_is_full_ro(const struct btrfs_fs_info *fs_info) 3259 + { 3260 + if (!sb_rdonly(fs_info->sb)) 3261 + return false; 3262 + if (unlikely(fs_info->mount_opt & BTRFS_MOUNT_FULL_RO_MASK)) 3263 + return true; 3264 + return false; 3265 + } 3266 + 3258 3267 int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices) 3259 3268 { 3260 3269 u32 sectorsize; ··· 3371 3362 /* check FS state, whether FS is broken. */ 3372 3363 if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_ERROR) 3373 3364 WRITE_ONCE(fs_info->fs_error, -EUCLEAN); 3365 + 3366 + /* If the fs has any rescue options, no transaction is allowed. */ 3367 + if (fs_is_full_ro(fs_info)) 3368 + WRITE_ONCE(fs_info->fs_error, -EROFS); 3374 3369 3375 3370 /* Set up fs_info before parsing mount options */ 3376 3371 nodesize = btrfs_super_nodesize(disk_super); ··· 3502 3489 fs_info->generation == btrfs_super_uuid_tree_generation(disk_super)) 3503 3490 set_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags); 3504 3491 3492 + if (unlikely(btrfs_verify_dev_items(fs_info))) { 3493 + ret = -EUCLEAN; 3494 + goto fail_block_groups; 3495 + } 3505 3496 ret = btrfs_verify_dev_extents(fs_info); 3506 3497 if (ret) { 3507 3498 btrfs_err(fs_info,
+8
fs/btrfs/fs.h
··· 264 264 BTRFS_MOUNT_REF_TRACKER = (1ULL << 33), 265 265 }; 266 266 267 + /* These mount options require a full read-only fs, no new transaction is allowed. */ 268 + #define BTRFS_MOUNT_FULL_RO_MASK \ 269 + (BTRFS_MOUNT_NOLOGREPLAY | \ 270 + BTRFS_MOUNT_IGNOREBADROOTS | \ 271 + BTRFS_MOUNT_IGNOREDATACSUMS | \ 272 + BTRFS_MOUNT_IGNOREMETACSUMS | \ 273 + BTRFS_MOUNT_IGNORESUPERFLAGS) 274 + 267 275 /* 268 276 * Compat flags that we support. If any incompat flags are set other than the 269 277 * ones specified below then we will fail to mount
+1 -1
fs/btrfs/tree-log.c
··· 2798 2798 2799 2799 nritems = btrfs_header_nritems(eb); 2800 2800 for (wc->log_slot = 0; wc->log_slot < nritems; wc->log_slot++) { 2801 - struct btrfs_inode_item *inode_item; 2801 + struct btrfs_inode_item *inode_item = NULL; 2802 2802 2803 2803 btrfs_item_key_to_cpu(eb, &wc->log_key, wc->log_slot); 2804 2804
+42
fs/btrfs/volumes.c
··· 1364 1364 (bytenr + BTRFS_SUPER_INFO_SIZE) >> PAGE_SHIFT); 1365 1365 } 1366 1366 1367 + filemap_invalidate_lock(mapping); 1367 1368 page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS); 1369 + filemap_invalidate_unlock(mapping); 1368 1370 if (IS_ERR(page)) 1369 1371 return ERR_CAST(page); 1370 1372 ··· 7259 7257 return -EINVAL; 7260 7258 } 7261 7259 } 7260 + set_bit(BTRFS_DEV_STATE_ITEM_FOUND, &device->dev_state); 7262 7261 set_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state); 7263 7262 if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) && 7264 7263 !test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) { ··· 8083 8080 8084 8081 /* Ensure all chunks have corresponding dev extents */ 8085 8082 return verify_chunk_dev_extent_mapping(fs_info); 8083 + } 8084 + 8085 + /* 8086 + * Ensure that all devices registered in the fs have their device items in the 8087 + * chunk tree. 8088 + * 8089 + * Return true if unexpected device is found. 8090 + * Return false otherwise. 8091 + */ 8092 + bool btrfs_verify_dev_items(const struct btrfs_fs_info *fs_info) 8093 + { 8094 + struct btrfs_fs_devices *seed_devs; 8095 + struct btrfs_device *dev; 8096 + bool ret = false; 8097 + 8098 + mutex_lock(&uuid_mutex); 8099 + list_for_each_entry(dev, &fs_info->fs_devices->devices, dev_list) { 8100 + if (!test_bit(BTRFS_DEV_STATE_ITEM_FOUND, &dev->dev_state)) { 8101 + btrfs_err(fs_info, 8102 + "devid %llu path %s is registered but not found in chunk tree", 8103 + dev->devid, btrfs_dev_name(dev)); 8104 + ret = true; 8105 + } 8106 + } 8107 + list_for_each_entry(seed_devs, &fs_info->fs_devices->seed_list, seed_list) { 8108 + list_for_each_entry(dev, &seed_devs->devices, dev_list) { 8109 + if (!test_bit(BTRFS_DEV_STATE_ITEM_FOUND, &dev->dev_state)) { 8110 + btrfs_err(fs_info, 8111 + "devid %llu path %s is registered but not found in chunk tree", 8112 + dev->devid, btrfs_dev_name(dev)); 8113 + ret = true; 8114 + } 8115 + } 8116 + } 8117 + mutex_unlock(&uuid_mutex); 8118 + if (ret) 8119 + btrfs_err(fs_info, 8120 + "remove the above devices or use 'btrfs device scan --forget <dev>' to unregister them before mount"); 8121 + return ret; 8086 8122 } 8087 8123 8088 8124 /*
+4
fs/btrfs/volumes.h
··· 100 100 #define BTRFS_DEV_STATE_FLUSH_SENT (4) 101 101 #define BTRFS_DEV_STATE_NO_READA (5) 102 102 103 + /* Set when the device item is found in chunk tree, used to catch unexpected registered device. */ 104 + #define BTRFS_DEV_STATE_ITEM_FOUND (7) 105 + 103 106 /* Special value encoding failure to write primary super block. */ 104 107 #define BTRFS_SUPER_PRIMARY_WRITE_ERROR (INT_MAX / 2) 105 108 ··· 896 893 int btrfs_bg_type_to_factor(u64 flags); 897 894 const char *btrfs_bg_type_to_raid_name(u64 flags); 898 895 int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info); 896 + bool btrfs_verify_dev_items(const struct btrfs_fs_info *fs_info); 899 897 bool btrfs_repair_one_zone(struct btrfs_fs_info *fs_info, u64 logical); 900 898 901 899 bool btrfs_pinned_by_swapfile(struct btrfs_fs_info *fs_info, void *ptr);