for-7.3-rc3-tag

-----BEGIN PGP SIGNATURE-----
 
 iQJPBAABCgA5FiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmqu3wQbFIAAAAAABAAO
 bWFudTIsMi41KzEuMTIsMiwyAAoJEMVl1fnXbVg7Y5kQAJ1ANaQWod+AUKhgbtA6
 IcEFH8AAVrrTqqN0SxOl/tqHL6Xt/5mKlQcTpYPxeccUkp72M9BeGik4Gp7OwN1D
 vkVTgrmhHT4r+4ae4GJP0yCtNJBa0fRXjsMFbNYTKGWcz9yOsW1OkBsq8VtRo7ym
 CSVBc57buUi0mzbnLNDh69G/YA7NCTyaxXKjPARNYy+cy0LMIDmgZCByhgePQvzB
 aqJUakRKpaeXEQIf0nT/70XcGhXNtfK1GOnLZM1ySFqLufMzdTsEzFsT8dVugqU1
 wr1HMaMq1iNKwE4sJgNWS84wRT1zxZopKIOsTufFu98Zb2C0kvUSjWeJSqtFM88G
 ggj/jmaoRhCU1cXE1jvZWy4Fe5zQH8deSQZ7zUB4ZzqCaDRwOEAj4IpuQQ9Ok91E
 J/07SCvKPk/QUPbA2e5lwRL3aximsD1LfRxWIOZ+xg/HVX+vYfHmy5gzkl/hhfrm
 RHkHLz8iXNHV7qhIVzZ/GYvTxR6U6nbLVUbkl5n/8eFePM7YHnoWtvMHT71qWwrh
 mPx8uTK+4BI2+rAHTKqxnwEQ27OHj5odlGKTlKiaMrQR9eqnnhJLTMPDJMzqQ7TI
 ZiibxG8UqSTsNbvOXXtd7MykSRpSb/VWyJImKuw30kx3f7f2yd1aCUyU4T7o5N/3
 FRI+2AbkoSeype3Rw+VcEPoi
 =WxSA
 -----END PGP SIGNATURE-----

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

Pull btrfs fixes from David Sterba:
 "Among the regular fixes, there are two that were reported recently and
  have user impact:

   - filesystem id is now stable again on the default and common case
     (it broke openconnect key derivation, while this is not secure,
     it's still in use), the intention was to change id for the
     temp_fsid use case

   - fix detection of /dev/root and rename it after device scan, this
     broke booting of initramdisk-less system with grub2 as the probe
     needs the real device

  Regular fixes:

   - don't store compressed inline extent if the size is larger than
     uncompressed

   - in zoned mode, handle activation of zones for all supported block
     group profiles in case there are still free ones left

   - check space for a chunk item when reading sys array from superblock

   - allow using space reserves when removing verity items fails

   - fix error handling after free space tree rebuild fails

   - abort transaction if reflink or hole punching fails and it's not
     possible to update the inode

   - properly protect block group iteration during device replace start

   - error message fixups"

* tag 'for-7.3-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: derive f_fsid with dev_t only when temp_fsid is active
  btrfs: add "/dev/root" exception for device path update
  btrfs: check if there is space for chunk item when validating sys chunk array
  btrfs: abort transaction on failure to update inode for hole punching and reflinking
  btrfs: clear free space tree creation state on rebuild failure
  btrfs: handle lack of space when cleaning up verity items
  btrfs: fix creation of compressed inline extents that don't save space
  btrfs: tree-checker: fix error message regarding free space extent items
  btrfs: tree-checker: print dev extent offset in error message
  btrfs: take commit root semaphore when iterating in mark_block_group_to_copy()
  btrfs: zoned: handle RAID profiles in btrfs_can_activate_zone()
This commit is contained in:
Linus Torvalds 2026-09-19 13:48:20 -07:00
commit 518e5b794c
10 changed files with 96 additions and 13 deletions

View File

@ -494,6 +494,7 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,
path->reada = READA_FORWARD;
path->search_commit_root = true;
path->skip_locking = true;
path->need_commit_sem = true;
key.objectid = src_dev->devid;
key.type = BTRFS_DEV_EXTENT_KEY;

View File

@ -2357,6 +2357,10 @@ static int validate_sys_chunk_array(const struct btrfs_fs_info *fs_info,
key.type, cur);
return -EUCLEAN;
}
if (unlikely(cur + sizeof(*chunk) > sys_array_size))
goto short_read;
chunk = (struct btrfs_chunk *)(sb->sys_chunk_array + cur);
num_stripes = btrfs_stack_chunk_num_stripes(chunk);
if (unlikely(cur + btrfs_chunk_item_size(num_stripes) > sys_array_size))

View File

@ -2509,8 +2509,10 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
inode_set_ctime_current(&inode->vfs_inode));
ret = btrfs_update_inode(trans, inode);
if (ret)
if (unlikely(ret)) {
btrfs_abort_transaction(trans, ret);
break;
}
btrfs_end_transaction(trans);
btrfs_btree_balance_dirty(fs_info);

View File

@ -1353,7 +1353,7 @@ int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info)
if (unlikely(ret)) {
btrfs_abort_transaction(trans, ret);
btrfs_end_transaction(trans);
return ret;
goto out_clear;
}
node = rb_first_cached(&fs_info->block_group_cache_tree);
@ -1371,14 +1371,16 @@ int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info)
if (unlikely(ret)) {
btrfs_abort_transaction(trans, ret);
btrfs_end_transaction(trans);
return ret;
goto out_clear;
}
next:
if (btrfs_should_end_transaction(trans)) {
btrfs_end_transaction(trans);
trans = btrfs_start_transaction(free_space_root, 1);
if (IS_ERR(trans))
return PTR_ERR(trans);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
goto out_clear;
}
}
node = rb_next(node);
}
@ -1390,6 +1392,10 @@ int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info)
ret = btrfs_commit_transaction(trans);
clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
return ret;
out_clear:
clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
return ret;
}
static int __add_block_group_free_space(struct btrfs_trans_handle *trans,

View File

@ -2339,12 +2339,27 @@ static int run_delalloc_inline(struct btrfs_inode *inode, struct folio *locked_f
} else if (inode->prop_compress) {
compress_type = inode->prop_compress;
}
/*
* We need to pass blocksize and not i_size, otherwise we can't
* create compressed inline extents for data smaller than sector
* size with lzo.
*/
cb = btrfs_compress_bio(inode, 0, blocksize, compress_type, compress_level, 0);
if (IS_ERR(cb)) {
cb = NULL;
/* Just fall back to non-compressed case. */
} else {
compressed_size = cb->bbio.bio.bi_iter.bi_size;
/*
* If we did not save space, it's pointless and wasteful
* to have an inline compressed extent, so fallback to
* an uncompressed inline extent.
*/
if (compressed_size >= i_size) {
cleanup_compressed_bio(cb);
cb = NULL;
compressed_size = 0;
}
}
}
if (!can_cow_file_range_inline(inode, 0, i_size, compressed_size)) {
@ -3877,7 +3892,8 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
if (ret)
goto out;
}
trans = btrfs_start_transaction(root, 1);
/* Only deletes the orphan. */
trans = btrfs_start_transaction_fallback_global_rsv(root, 1);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
goto out;

View File

@ -1836,8 +1836,12 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
f_fsid.val[0] ^= btrfs_root_id(BTRFS_I(d_inode(dentry))->root) >> 32;
f_fsid.val[1] ^= btrfs_root_id(BTRFS_I(d_inode(dentry))->root);
/* Hash dev_t to avoid f_fsid collision with cloned filesystems. */
if (fs_info->fs_devices->total_devices == 1) {
/*
* Hash dev_t to avoid f_fsid collisions with cloned filesystems.
* Only do this when a clone is present so the original filesystem
* (mounted first) maintains backward-compatible f_fsid behavior.
*/
if (fs_info->fs_devices->temp_fsid) {
__kernel_fsid_t dev_fsid =
u64_to_fsid(huge_encode_dev(fs_info->fs_devices->latest_dev->bdev->bd_dev));

View File

@ -2129,7 +2129,7 @@ static int check_dev_extent_item(const struct extent_buffer *leaf,
sectorsize))) {
generic_err(leaf, slot,
"invalid dev extent chunk offset, has %llu not aligned to %u",
btrfs_dev_extent_chunk_objectid(leaf, de),
btrfs_dev_extent_chunk_offset(leaf, de),
sectorsize);
return -EUCLEAN;
}
@ -2306,7 +2306,7 @@ static int check_free_space_extent(struct extent_buffer *leaf, struct btrfs_key
if (unlikely(btrfs_item_size(leaf, slot) != 0)) {
generic_err(leaf, slot,
"invalid item size for free space info, has %u expect 0",
"invalid item size for free space extent, has %u expect 0",
btrfs_item_size(leaf, slot));
return -EUCLEAN;
}

View File

@ -93,6 +93,20 @@ static loff_t merkle_file_pos(const struct inode *inode)
return rounded;
}
/*
* Start a transaction for removing verity items or the verity orphan.
*
* Like unlink, this only deletes items and frees space in the end, so the
* reservation may come from the global reserve when the filesystem is full
* (-ENOSPC) and is not subject to the qgroup limit (-EDQUOT). Otherwise a
* failed enable could never be cleaned up in either situation.
*/
static struct btrfs_trans_handle *start_verity_cleanup_trans(struct btrfs_root *root,
unsigned int num_items)
{
return btrfs_start_transaction_fallback_global_rsv(root, num_items);
}
/*
* Drop all the items for this inode with this key_type.
*
@ -120,7 +134,7 @@ static int drop_verity_items(struct btrfs_inode *inode, u8 key_type)
while (1) {
/* 1 for the item being dropped */
trans = btrfs_start_transaction(root, 1);
trans = start_verity_cleanup_trans(root, 1);
if (IS_ERR(trans))
return PTR_ERR(trans);
@ -466,7 +480,7 @@ static int rollback_verity(struct btrfs_inode *inode)
* 1 for updating the inode flag
* 1 for deleting the orphan
*/
trans = btrfs_start_transaction(root, 2);
trans = start_verity_cleanup_trans(root, 2);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
trans = NULL;

View File

@ -749,6 +749,36 @@ const u8 *btrfs_sb_fsid_ptr(const struct btrfs_super_block *sb)
return has_metadata_uuid ? sb->metadata_uuid : sb->fsid;
}
static bool should_rename_device(const struct btrfs_device *dev)
{
bool ret;
const char *old_name;
rcu_read_lock();
old_name = rcu_dereference(dev->name);
/*
* For systems booted without an initramfs, the rootfs has the device
* name "/dev/root".
*
* Although using btrfs without an initramfs is not recommended (if a
* new device is added to the rootfs, the system can no longer boot, as
* there is no way to register all devices), there is still a minority
* of users doing this.
*
* And after the system is up, a later device scan on the real block
* device file will never get this device's name updated, as the
* device->devt is still the same.
*
* Here we add one and only one exception for "/dev/root", to allow the
* device name to be updated even if the new path points to the same
* block device.
*/
ret = (strcmp(old_name, "/dev/root") == 0);
rcu_read_unlock();
return ret;
}
/*
* Add new device to list of registered devices
*
@ -869,7 +899,8 @@ static noinline struct btrfs_device *device_list_add(const char *path,
MAJOR(path_devt), MINOR(path_devt),
current->comm, task_pid_nr(current));
} else if (!device->name || device->devt != path_devt) {
} else if (!device->name || device->devt != path_devt ||
should_rename_device(device)) {
const char *old_name;
/*

View File

@ -2688,6 +2688,11 @@ bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags)
switch (flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
case 0: /* single */
case BTRFS_BLOCK_GROUP_RAID0:
case BTRFS_BLOCK_GROUP_RAID1:
case BTRFS_BLOCK_GROUP_RAID1C3:
case BTRFS_BLOCK_GROUP_RAID1C4:
case BTRFS_BLOCK_GROUP_RAID10:
ret = (atomic_read(&zinfo->active_zones_left) >= (1 + reserved));
break;
case BTRFS_BLOCK_GROUP_DUP: