mirror of
https://github.com/torvalds/linux.git
synced 2026-03-07 23:04:33 +01:00
for-7.0-rc2-tag
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmmm7WwACgkQxWXV+ddt
WDs7PQ/+Mc0CHhMhRH3DyEnZTPO5YcNLGl2ytqu19X2VdGu3Ra86Au4V+0tWJ+zf
g4jI8UdgJWdR7aIoIgtMkl2BbK0tyY0WBEJ76EJNDsatByNmTXc0iXwGROe6tL9p
n4qrEnaTMh4SmYEsFEQX9lO5ISbDbk+kfN8qapCl03c9JyKO6D3PSGrM7wzIkXX4
oIyfDWpYpAxbyWKjn+uJlpPzdsdfRceJ0fyCbq9sJITVW/FhicqTr6xvqqeoPSXp
oJiL/Bbsilh7AtCLHguqpczt0X+Fus9enpjT9QqATN/JgUsaXt6O6Mk6NHcnEwjS
vW6ZdeiFdELz2yLnJyb15ROf6Uorm3Mt2kAnkatLpyHxG9Z7rkxs3+cX4nm7MxSG
GfLBkFB+HGw155z7cK0dPHMAhQ0KCF66I99VKTgLChjmUs8ipjPAYR8f/Tsq82RD
mrYf3mEgWYnw6alx2ak454hsNjiXuYmc9bNy8Q+TXD73gQGqwUcZR6alIV+eoWVB
xbX/0BQPemMITlhX6IuNn5EkCZSoB7eLcDMmYRSOpJOd8oo+gXmzQ5WvQIpwYhwz
IZIH+KTdErw2FKJ8x9tStydnrmzN63QTEMMtuBy8pRsP5qJMrncPfAOMNBlqhqMq
3W1GJuurHt2dBmUOQXWrUcMQlDLPyOxUHV6TdpCL83xNzdZK8G4=
=REHq
-----END PGP SIGNATURE-----
Merge tag 'for-7.0-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba:
"One-liner or short fixes for minor/moderate problems reported recently:
- fixes or level adjustments of error messages
- fix leaked transaction handles after aborted transactions, when
using the remap tree feature
- fix a few leaked chunk maps after errors
- fix leaked page array in io_uring encoded read if an error occurs
and the 'finished' is not called
- fix double release of reserved extents when doing a range COW
- don't commit super block when the filesystem is in shutdown state
- fix squota accounting condition when checking members vs parent
usage
- other error handling fixes"
* tag 'for-7.0-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: check block group lookup in remove_range_from_remap_tree()
btrfs: fix transaction handle leaks in btrfs_last_identity_remap_gone()
btrfs: fix chunk map leak in btrfs_map_block() after btrfs_translate_remap()
btrfs: fix chunk map leak in btrfs_map_block() after btrfs_chunk_map_num_copies()
btrfs: fix compat mask in error messages in btrfs_check_features()
btrfs: print correct subvol num if active swapfile prevents deletion
btrfs: fix warning in scrub_verify_one_metadata()
btrfs: fix objectid value in error message in check_extent_data_ref()
btrfs: fix incorrect key offset in error message in check_dev_extent_item()
btrfs: fix error message order of parameters in btrfs_delete_delayed_dir_index()
btrfs: don't commit the super block when unmounting a shutdown filesystem
btrfs: free pages on error in btrfs_uring_read_extent()
btrfs: fix referenced/exclusive check in squota_check_parent_usage()
btrfs: remove pointless WARN_ON() in cache_save_setup()
btrfs: convert log messages to error level in btrfs_replay_log()
btrfs: remove btrfs_handle_fs_error() after failure to recover log trees
btrfs: remove redundant warning message in btrfs_check_uuid_tree()
btrfs: change warning messages to error level in open_ctree()
btrfs: fix a double release on reserved extents in cow_one_range()
btrfs: handle discard errors in in btrfs_finish_extent_commit()
This commit is contained in:
commit
c44db6c820
11 changed files with 67 additions and 28 deletions
|
|
@ -3340,7 +3340,6 @@ again:
|
|||
btrfs_abort_transaction(trans, ret);
|
||||
goto out_put;
|
||||
}
|
||||
WARN_ON(ret);
|
||||
|
||||
/* We've already setup this transaction, go ahead and exit */
|
||||
if (block_group->cache_generation == trans->transid &&
|
||||
|
|
|
|||
|
|
@ -1657,7 +1657,7 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
|
|||
if (unlikely(ret)) {
|
||||
btrfs_err(trans->fs_info,
|
||||
"failed to add delayed dir index item, root: %llu, inode: %llu, index: %llu, error: %d",
|
||||
index, btrfs_root_id(node->root), node->inode_id, ret);
|
||||
btrfs_root_id(node->root), node->inode_id, index, ret);
|
||||
btrfs_delayed_item_release_metadata(dir->root, item);
|
||||
btrfs_release_delayed_item(item);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1994,7 +1994,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
|
|||
int level = btrfs_super_log_root_level(disk_super);
|
||||
|
||||
if (unlikely(fs_devices->rw_devices == 0)) {
|
||||
btrfs_warn(fs_info, "log replay required on RO media");
|
||||
btrfs_err(fs_info, "log replay required on RO media");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -2008,9 +2008,9 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
|
|||
check.owner_root = BTRFS_TREE_LOG_OBJECTID;
|
||||
log_tree_root->node = read_tree_block(fs_info, bytenr, &check);
|
||||
if (IS_ERR(log_tree_root->node)) {
|
||||
btrfs_warn(fs_info, "failed to read log tree");
|
||||
ret = PTR_ERR(log_tree_root->node);
|
||||
log_tree_root->node = NULL;
|
||||
btrfs_err(fs_info, "failed to read log tree with error: %d", ret);
|
||||
btrfs_put_root(log_tree_root);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2023,9 +2023,9 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
|
|||
/* returns with log_tree_root freed on success */
|
||||
ret = btrfs_recover_log_trees(log_tree_root);
|
||||
btrfs_put_root(log_tree_root);
|
||||
if (ret) {
|
||||
btrfs_handle_fs_error(fs_info, ret,
|
||||
"Failed to recover log tree");
|
||||
if (unlikely(ret)) {
|
||||
ASSERT(BTRFS_FS_ERROR(fs_info) != 0);
|
||||
btrfs_err(fs_info, "failed to recover log trees with error: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -2972,7 +2972,6 @@ static int btrfs_check_uuid_tree(struct btrfs_fs_info *fs_info)
|
|||
task = kthread_run(btrfs_uuid_rescan_kthread, fs_info, "btrfs-uuid");
|
||||
if (IS_ERR(task)) {
|
||||
/* fs_info->update_uuid_tree_gen remains 0 in all error case */
|
||||
btrfs_warn(fs_info, "failed to start uuid_rescan task");
|
||||
up(&fs_info->uuid_tree_rescan_sem);
|
||||
return PTR_ERR(task);
|
||||
}
|
||||
|
|
@ -3188,7 +3187,7 @@ int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount)
|
|||
if (incompat & ~BTRFS_FEATURE_INCOMPAT_SUPP) {
|
||||
btrfs_err(fs_info,
|
||||
"cannot mount because of unknown incompat features (0x%llx)",
|
||||
incompat);
|
||||
incompat & ~BTRFS_FEATURE_INCOMPAT_SUPP);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -3220,7 +3219,7 @@ int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount)
|
|||
if (compat_ro_unsupp && is_rw_mount) {
|
||||
btrfs_err(fs_info,
|
||||
"cannot mount read-write because of unknown compat_ro features (0x%llx)",
|
||||
compat_ro);
|
||||
compat_ro_unsupp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -3233,7 +3232,7 @@ int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount)
|
|||
!btrfs_test_opt(fs_info, NOLOGREPLAY)) {
|
||||
btrfs_err(fs_info,
|
||||
"cannot replay dirty log with unsupported compat_ro features (0x%llx), try rescue=nologreplay",
|
||||
compat_ro);
|
||||
compat_ro_unsupp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -3642,7 +3641,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
|||
fs_info->fs_root = btrfs_get_fs_root(fs_info, BTRFS_FS_TREE_OBJECTID, true);
|
||||
if (IS_ERR(fs_info->fs_root)) {
|
||||
ret = PTR_ERR(fs_info->fs_root);
|
||||
btrfs_warn(fs_info, "failed to read fs tree: %d", ret);
|
||||
btrfs_err(fs_info, "failed to read fs tree: %d", ret);
|
||||
fs_info->fs_root = NULL;
|
||||
goto fail_qgroup;
|
||||
}
|
||||
|
|
@ -3663,8 +3662,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
|||
btrfs_info(fs_info, "checking UUID tree");
|
||||
ret = btrfs_check_uuid_tree(fs_info);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info,
|
||||
"failed to check the UUID tree: %d", ret);
|
||||
btrfs_err(fs_info, "failed to check the UUID tree: %d", ret);
|
||||
close_ctree(fs_info);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -4399,9 +4397,17 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
|
|||
*/
|
||||
btrfs_flush_workqueue(fs_info->delayed_workers);
|
||||
|
||||
ret = btrfs_commit_super(fs_info);
|
||||
if (ret)
|
||||
btrfs_err(fs_info, "commit super ret %d", ret);
|
||||
/*
|
||||
* If the filesystem is shutdown, then an attempt to commit the
|
||||
* super block (or any write) will just fail. Since we freeze
|
||||
* the filesystem before shutting it down, the filesystem is in
|
||||
* a consistent state and we don't need to commit super blocks.
|
||||
*/
|
||||
if (!btrfs_is_shutdown(fs_info)) {
|
||||
ret = btrfs_commit_super(fs_info);
|
||||
if (ret)
|
||||
btrfs_err(fs_info, "commit super block returned %d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
kthread_stop(fs_info->transaction_kthread);
|
||||
|
|
|
|||
|
|
@ -2933,9 +2933,15 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
|
|||
while (!TRANS_ABORTED(trans) && cached_state) {
|
||||
struct extent_state *next_state;
|
||||
|
||||
if (btrfs_test_opt(fs_info, DISCARD_SYNC))
|
||||
if (btrfs_test_opt(fs_info, DISCARD_SYNC)) {
|
||||
ret = btrfs_discard_extent(fs_info, start,
|
||||
end + 1 - start, NULL, true);
|
||||
if (ret) {
|
||||
btrfs_warn(fs_info,
|
||||
"discard failed for extent [%llu, %llu]: errno=%d %s",
|
||||
start, end, ret, btrfs_decode_error(ret));
|
||||
}
|
||||
}
|
||||
|
||||
next_state = btrfs_next_extent_state(unpin, cached_state);
|
||||
btrfs_clear_extent_dirty(unpin, start, end, &cached_state);
|
||||
|
|
|
|||
|
|
@ -1392,10 +1392,25 @@ static int cow_one_range(struct btrfs_inode *inode, struct folio *locked_folio,
|
|||
return ret;
|
||||
|
||||
free_reserved:
|
||||
/*
|
||||
* If we have reserved an extent for the current range and failed to
|
||||
* create the respective extent map or ordered extent, it means that
|
||||
* when we reserved the extent we decremented the extent's size from
|
||||
* the data space_info's bytes_may_use counter and
|
||||
* incremented the space_info's bytes_reserved counter by the same
|
||||
* amount.
|
||||
*
|
||||
* We must make sure extent_clear_unlock_delalloc() does not try
|
||||
* to decrement again the data space_info's bytes_may_use counter, which
|
||||
* will be handled by btrfs_free_reserved_extent().
|
||||
*
|
||||
* Therefore we do not pass it the flag EXTENT_CLEAR_DATA_RESV, but only
|
||||
* EXTENT_CLEAR_META_RESV.
|
||||
*/
|
||||
extent_clear_unlock_delalloc(inode, file_offset, cur_end, locked_folio, cached,
|
||||
EXTENT_LOCKED | EXTENT_DELALLOC |
|
||||
EXTENT_DELALLOC_NEW |
|
||||
EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING,
|
||||
EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV,
|
||||
PAGE_UNLOCK | PAGE_START_WRITEBACK |
|
||||
PAGE_END_WRITEBACK);
|
||||
btrfs_qgroup_free_data(inode, NULL, file_offset, cur_len, NULL);
|
||||
|
|
@ -4764,7 +4779,7 @@ int btrfs_delete_subvolume(struct btrfs_inode *dir, struct dentry *dentry)
|
|||
spin_unlock(&dest->root_item_lock);
|
||||
btrfs_warn(fs_info,
|
||||
"attempt to delete subvolume %llu with active swapfile",
|
||||
btrfs_root_id(root));
|
||||
btrfs_root_id(dest));
|
||||
ret = -EPERM;
|
||||
goto out_up_write;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4581,7 +4581,7 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter,
|
|||
{
|
||||
struct btrfs_inode *inode = BTRFS_I(file_inode(iocb->ki_filp));
|
||||
struct extent_io_tree *io_tree = &inode->io_tree;
|
||||
struct page **pages;
|
||||
struct page **pages = NULL;
|
||||
struct btrfs_uring_priv *priv = NULL;
|
||||
unsigned long nr_pages;
|
||||
int ret;
|
||||
|
|
@ -4639,6 +4639,11 @@ out_fail:
|
|||
btrfs_unlock_extent(io_tree, start, lockend, &cached_state);
|
||||
btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED);
|
||||
kfree(priv);
|
||||
for (int i = 0; i < nr_pages; i++) {
|
||||
if (pages[i])
|
||||
__free_page(pages[i]);
|
||||
}
|
||||
kfree(pages);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ static bool squota_check_parent_usage(struct btrfs_fs_info *fs_info, struct btrf
|
|||
nr_members++;
|
||||
}
|
||||
mismatch = (parent->excl != excl_sum || parent->rfer != rfer_sum ||
|
||||
parent->excl_cmpr != excl_cmpr_sum || parent->rfer_cmpr != excl_cmpr_sum);
|
||||
parent->excl_cmpr != excl_cmpr_sum || parent->rfer_cmpr != rfer_cmpr_sum);
|
||||
|
||||
WARN(mismatch,
|
||||
"parent squota qgroup %hu/%llu has mismatched usage from its %d members. "
|
||||
|
|
|
|||
|
|
@ -4723,6 +4723,7 @@ int btrfs_last_identity_remap_gone(struct btrfs_chunk_map *chunk_map,
|
|||
ret = btrfs_remove_dev_extents(trans, chunk_map);
|
||||
if (unlikely(ret)) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
btrfs_end_transaction(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -4732,6 +4733,7 @@ int btrfs_last_identity_remap_gone(struct btrfs_chunk_map *chunk_map,
|
|||
if (unlikely(ret)) {
|
||||
mutex_unlock(&trans->fs_info->chunk_mutex);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
btrfs_end_transaction(trans);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -4750,6 +4752,7 @@ int btrfs_last_identity_remap_gone(struct btrfs_chunk_map *chunk_map,
|
|||
ret = remove_chunk_stripes(trans, chunk_map, path);
|
||||
if (unlikely(ret)) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
btrfs_end_transaction(trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -5982,6 +5985,9 @@ static int remove_range_from_remap_tree(struct btrfs_trans_handle *trans,
|
|||
struct btrfs_block_group *dest_bg;
|
||||
|
||||
dest_bg = btrfs_lookup_block_group(fs_info, new_addr);
|
||||
if (unlikely(!dest_bg))
|
||||
return -EUCLEAN;
|
||||
|
||||
adjust_block_group_remap_bytes(trans, dest_bg, -overlap_length);
|
||||
btrfs_put_block_group(dest_bg);
|
||||
ret = btrfs_add_to_free_space_tree(trans,
|
||||
|
|
|
|||
|
|
@ -743,7 +743,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr
|
|||
btrfs_warn_rl(fs_info,
|
||||
"scrub: tree block %llu mirror %u has bad fsid, has %pU want %pU",
|
||||
logical, stripe->mirror_num,
|
||||
header->fsid, fs_info->fs_devices->fsid);
|
||||
header->fsid, fs_info->fs_devices->metadata_uuid);
|
||||
return;
|
||||
}
|
||||
if (memcmp(header->chunk_tree_uuid, fs_info->chunk_tree_uuid,
|
||||
|
|
|
|||
|
|
@ -1740,7 +1740,7 @@ static int check_extent_data_ref(struct extent_buffer *leaf,
|
|||
objectid > BTRFS_LAST_FREE_OBJECTID)) {
|
||||
extent_err(leaf, slot,
|
||||
"invalid extent data backref objectid value %llu",
|
||||
root);
|
||||
objectid);
|
||||
return -EUCLEAN;
|
||||
}
|
||||
if (unlikely(!IS_ALIGNED(offset, leaf->fs_info->sectorsize))) {
|
||||
|
|
@ -1921,7 +1921,7 @@ static int check_dev_extent_item(const struct extent_buffer *leaf,
|
|||
if (unlikely(prev_key->offset + prev_len > key->offset)) {
|
||||
generic_err(leaf, slot,
|
||||
"dev extent overlap, prev offset %llu len %llu current offset %llu",
|
||||
prev_key->objectid, prev_len, key->offset);
|
||||
prev_key->offset, prev_len, key->offset);
|
||||
return -EUCLEAN;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6907,7 +6907,7 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
|
|||
|
||||
ret = btrfs_translate_remap(fs_info, &new_logical, length);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
if (new_logical != logical) {
|
||||
btrfs_free_chunk_map(map);
|
||||
|
|
@ -6921,8 +6921,10 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
|
|||
}
|
||||
|
||||
num_copies = btrfs_chunk_map_num_copies(map);
|
||||
if (io_geom.mirror_num > num_copies)
|
||||
return -EINVAL;
|
||||
if (io_geom.mirror_num > num_copies) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
map_offset = logical - map->start;
|
||||
io_geom.raid56_full_stripe_start = (u64)-1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue