mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
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:
commit
518e5b794c
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user