mirror of
https://github.com/torvalds/linux.git
synced 2026-09-09 09:22:02 +02:00
for-7.3-rc1-tag
-----BEGIN PGP SIGNATURE-----
iQJPBAABCgA5FiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmqcOFUbFIAAAAAABAAO
bWFudTIsMi41KzEuMTIsMiwyAAoJEMVl1fnXbVg7DwAP/i5lmUS85n22uWD7wkmU
5ocMbdl9cKprtcpi8axR9kbtBIC5bq0j3sUwmiFgR6KI774v7FnxJ3AIrey3GwtF
okiaWLffKOYROCDvmLg36ciSbFGEqjS8lwOPl1geBX7tZhhnGgcV+XRXcMv4ehj8
HiOtjN8a+8kXrYTMB73JhBkzku7Hojb/vA9ZHXeCLjP4nfzlXneqltSQw/+3uVvf
jrLfOX3a1lgLkz0Q7AlfAO7ppXv5msrZYu7E1aILYtLA5K6J6Gh1jyK+Y8OZlvdg
hukhU3mAw2pCV5dg6rAurYWzVhE/tNmKmlg2s1LiW3K1Q2NNSPGvR0ArmAnd9bPY
6ZwoK47m98xuZgIAO7v+ej9LYI3XANGwdupTmrKhQ7shLYtzvSsob7kWRYfjCMWu
UaTGshMsrfMXZNznXm2Ydy1Gmr3TBI2J1HpUFiibRL4XgsQ7u9hLUFwiFUiMEi9V
g9oqTN/1VUMsImADlnrdAf30pLtOe8PHV1naFLdmdl+iCPc9o0cX9X5m2fHWtkpt
Cjz/au8Z0zMVJMIDUZuBgCX4mWNSx7pWYKQYvlGOLQEehXNLRVcY5SnIqRman8WF
gnUPaaTb6KDS+SJjRDPkRH9ihGlNEd2c/tzrxek4/42CF842PGeMvGK06PtPyzxW
LWtmCtBWRArSHUq09NZbboim
=z6qW
-----END PGP SIGNATURE-----
Merge tag 'for-7.3-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba:
- preserve inode compression level when changing attributes
- fix lost wakeup when waiting for a zstd workspace
- fix bio context leaks after ordered extent processing errors
- in send, handle unexpected extents for non-regular inodes
- handle edge case in creation of reloc tree with enabled quotas
- in scrub report the exact failing offset, not the stripe base
- error handling fixes
- error code propagation in send, zoned mode and raid-stripe-tree
- restore active device pointer after seeding device addition error
- transaction abort fixups
- update Chris' email address
* tag 'for-7.3-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
MAINTAINERS: update Chris Mason's email address
btrfs: tests: do not touch page cache if root/inode allocation failed
btrfs: zstd: fix lost wakeup when waiting for a workspace
btrfs: do not force reloc root creation during qgroup_account_snapshot()
btrfs: send: fix lost error return value in will_overwrite_ref()
btrfs: abort transaction before releasing tree_log_mutex on commit failure
btrfs: zoned: propagate do_zone_finish() error in btrfs_zone_finish_endio()
btrfs: zoned: finish active block group cleanup if call_zone_finish() fails
btrfs: send: reject extents for non-regular inodes
btrfs: return proper negative error code for update_raid_extent_item()
btrfs: fix the possible bioc_list memory leak during error
btrfs: fix transaction use-after-free in raid stripe insertion
btrfs: scrub: report the failing sector's address, not the stripe base
btrfs: preserve the compression property when other inode flags change
btrfs: restore active device pointers after failed sprout
btrfs: detach failed sprout device from transaction update list
btrfs: clean up target device if block group marking fails
This commit is contained in:
commit
d9d80a859b
|
|
@ -5671,8 +5671,8 @@ W: http://bu3sch.de/btgpio.php
|
|||
F: drivers/gpio/gpio-bt8xx.c
|
||||
|
||||
BTRFS FILE SYSTEM
|
||||
M: Chris Mason <clm@fb.com>
|
||||
M: David Sterba <dsterba@suse.com>
|
||||
R: Chris Mason <mason@kernel.org>
|
||||
L: linux-btrfs@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://btrfs.readthedocs.io
|
||||
|
|
|
|||
|
|
@ -636,7 +636,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
|
|||
|
||||
ret = mark_block_group_to_copy(fs_info, src_device);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto leave;
|
||||
|
||||
down_write(&dev_replace->rwsem);
|
||||
dev_replace->replace_task = current;
|
||||
|
|
|
|||
|
|
@ -3436,6 +3436,9 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
|
|||
*/
|
||||
btrfs_remove_ordered_extent(ordered_extent);
|
||||
|
||||
/* Cleanup any remaining biocs attached to the OE. */
|
||||
btrfs_cleanup_ordered_bioc_list(ordered_extent);
|
||||
|
||||
/* once for us */
|
||||
btrfs_put_ordered_extent(ordered_extent);
|
||||
/* once for the tree */
|
||||
|
|
|
|||
|
|
@ -384,6 +384,7 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap,
|
|||
inode_flags &= ~BTRFS_INODE_COMPRESS;
|
||||
inode_flags |= BTRFS_INODE_NOCOMPRESS;
|
||||
} else if (fsflags & FS_COMPR_FL) {
|
||||
enum btrfs_compression_type comp_type;
|
||||
|
||||
if (IS_SWAPFILE(&inode->vfs_inode))
|
||||
return -ETXTBSY;
|
||||
|
|
@ -391,9 +392,23 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap,
|
|||
inode_flags |= BTRFS_INODE_COMPRESS;
|
||||
inode_flags &= ~BTRFS_INODE_NOCOMPRESS;
|
||||
|
||||
comp = btrfs_compress_type2str(fs_info->compress_type);
|
||||
if (!comp || comp[0] == 0)
|
||||
comp = btrfs_compress_type2str(BTRFS_COMPRESS_ZLIB);
|
||||
/*
|
||||
* Keep the algorithm recorded in the compression property,
|
||||
* otherwise changing an unrelated attribute would reset it to
|
||||
* the mount default, since FS_IOC_SETFLAGS callers write back
|
||||
* the whole flag set they got from FS_IOC_GETFLAGS and that
|
||||
* includes FS_COMPR_FL for any inode carrying the property.
|
||||
*
|
||||
* Inodes with the compress flag set but no property keep using
|
||||
* the mount default, so they behave as before.
|
||||
*/
|
||||
if (inode->prop_compress)
|
||||
comp_type = inode->prop_compress;
|
||||
else if (fs_info->compress_type)
|
||||
comp_type = fs_info->compress_type;
|
||||
else
|
||||
comp_type = BTRFS_COMPRESS_ZLIB;
|
||||
comp = btrfs_compress_type2str(comp_type);
|
||||
} else {
|
||||
inode_flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,8 +310,10 @@ static int update_raid_extent_item(struct btrfs_trans_handle *trans,
|
|||
|
||||
ret = btrfs_search_slot(trans, trans->fs_info->stripe_root, key, path,
|
||||
0, 1);
|
||||
if (ret)
|
||||
return (ret == 1 ? ret : -EINVAL);
|
||||
if (ret > 0)
|
||||
ret = -ENOENT;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
leaf = path->nodes[0];
|
||||
slot = path->slots[0];
|
||||
|
|
@ -337,7 +339,6 @@ int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans,
|
|||
stripe_extent = kzalloc(item_size, GFP_NOFS);
|
||||
if (unlikely(!stripe_extent)) {
|
||||
btrfs_abort_transaction(trans, -ENOMEM);
|
||||
btrfs_end_transaction(trans);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
@ -374,7 +375,7 @@ int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans,
|
|||
struct btrfs_ordered_extent *ordered_extent)
|
||||
{
|
||||
struct btrfs_io_context *bioc;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!btrfs_fs_incompat(trans->fs_info, RAID_STRIPE_TREE))
|
||||
return 0;
|
||||
|
|
@ -382,17 +383,23 @@ int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans,
|
|||
list_for_each_entry(bioc, &ordered_extent->bioc_list, rst_ordered_entry) {
|
||||
ret = btrfs_insert_one_raid_extent(trans, bioc);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
|
||||
while (!list_empty(&ordered_extent->bioc_list)) {
|
||||
bioc = list_first_entry(&ordered_extent->bioc_list,
|
||||
btrfs_cleanup_ordered_bioc_list(ordered_extent);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void btrfs_cleanup_ordered_bioc_list(struct btrfs_ordered_extent *ordered)
|
||||
{
|
||||
while (!list_empty(&ordered->bioc_list)) {
|
||||
struct btrfs_io_context *bioc;
|
||||
|
||||
bioc = list_first_entry(&ordered->bioc_list,
|
||||
typeof(*bioc), rst_ordered_entry);
|
||||
list_del(&bioc->rst_ordered_entry);
|
||||
btrfs_put_bioc(bioc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info,
|
|||
u32 stripe_index, struct btrfs_io_stripe *stripe);
|
||||
int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_ordered_extent *ordered_extent);
|
||||
void btrfs_cleanup_ordered_bioc_list(struct btrfs_ordered_extent *ordered);
|
||||
|
||||
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
|
||||
int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans,
|
||||
|
|
|
|||
|
|
@ -1023,6 +1023,10 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
|
|||
|
||||
skip:
|
||||
for_each_set_bit(sector_nr, &extent_bitmap, stripe->nr_sectors) {
|
||||
const u64 sector_logical = stripe->logical +
|
||||
((u64)sector_nr << fs_info->sectorsize_bits);
|
||||
const u64 sector_physical = physical +
|
||||
((u64)sector_nr << fs_info->sectorsize_bits);
|
||||
bool repaired = false;
|
||||
|
||||
if (scrub_bitmap_test_bit_is_metadata(stripe, sector_nr)) {
|
||||
|
|
@ -1051,12 +1055,12 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
|
|||
if (dev) {
|
||||
btrfs_err_rl(fs_info,
|
||||
"scrub: fixed up error at logical %llu on dev %s physical %llu",
|
||||
stripe->logical, btrfs_dev_name(dev),
|
||||
physical);
|
||||
sector_logical, btrfs_dev_name(dev),
|
||||
sector_physical);
|
||||
} else {
|
||||
btrfs_err_rl(fs_info,
|
||||
"scrub: fixed up error at logical %llu on mirror %u",
|
||||
stripe->logical, stripe->mirror_num);
|
||||
sector_logical, stripe->mirror_num);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1065,30 +1069,30 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
|
|||
if (dev) {
|
||||
btrfs_err_rl(fs_info,
|
||||
"scrub: unable to fixup (regular) error at logical %llu on dev %s physical %llu",
|
||||
stripe->logical, btrfs_dev_name(dev),
|
||||
physical);
|
||||
sector_logical, btrfs_dev_name(dev),
|
||||
sector_physical);
|
||||
} else {
|
||||
btrfs_err_rl(fs_info,
|
||||
"scrub: unable to fixup (regular) error at logical %llu on mirror %u",
|
||||
stripe->logical, stripe->mirror_num);
|
||||
sector_logical, stripe->mirror_num);
|
||||
}
|
||||
|
||||
if (scrub_bitmap_test_bit_io_error(stripe, sector_nr))
|
||||
if (__ratelimit(&rs) && dev)
|
||||
scrub_print_common_warning("i/o error", dev, false,
|
||||
stripe->logical, physical);
|
||||
sector_logical, sector_physical);
|
||||
if (scrub_bitmap_test_bit_csum_error(stripe, sector_nr))
|
||||
if (__ratelimit(&rs) && dev)
|
||||
scrub_print_common_warning("checksum error", dev, false,
|
||||
stripe->logical, physical);
|
||||
sector_logical, sector_physical);
|
||||
if (scrub_bitmap_test_bit_meta_error(stripe, sector_nr))
|
||||
if (__ratelimit(&rs) && dev)
|
||||
scrub_print_common_warning("header error", dev, false,
|
||||
stripe->logical, physical);
|
||||
sector_logical, sector_physical);
|
||||
if (scrub_bitmap_test_bit_meta_gen_error(stripe, sector_nr))
|
||||
if (__ratelimit(&rs) && dev)
|
||||
scrub_print_common_warning("generation error", dev, false,
|
||||
stripe->logical, physical);
|
||||
sector_logical, sector_physical);
|
||||
}
|
||||
|
||||
/* Update the device stats. */
|
||||
|
|
|
|||
|
|
@ -2065,7 +2065,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
|
|||
|
||||
ret = is_inode_existent(sctx, dir, dir_gen, NULL, &parent_root_dir_gen);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If we have a parent root we need to verify that the parent dir was
|
||||
|
|
@ -6417,6 +6417,13 @@ static int process_extent(struct send_ctx *sctx,
|
|||
|
||||
if (S_ISLNK(sctx->cur_inode_mode))
|
||||
return 0;
|
||||
if (unlikely(!S_ISREG(sctx->cur_inode_mode))) {
|
||||
btrfs_crit(sctx->send_root->fs_info,
|
||||
"send: extent for non-regular inode %llu root %llu mode 0%llo",
|
||||
key->objectid, btrfs_root_id(sctx->send_root),
|
||||
sctx->cur_inode_mode & S_IFMT);
|
||||
return -EUCLEAN;
|
||||
}
|
||||
|
||||
if (sctx->parent_root && !sctx->cur_inode_new) {
|
||||
ret = is_extent_unchanged(sctx, path, key);
|
||||
|
|
|
|||
|
|
@ -133,14 +133,14 @@ static int test_find_delalloc(u32 sectorsize, u32 nodesize)
|
|||
if (IS_ERR(root)) {
|
||||
test_std_err(TEST_ALLOC_ROOT);
|
||||
ret = PTR_ERR(root);
|
||||
goto out;
|
||||
goto out_root_info;
|
||||
}
|
||||
|
||||
inode = btrfs_new_test_inode();
|
||||
if (!inode) {
|
||||
test_std_err(TEST_ALLOC_INODE);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
goto out_root_info;
|
||||
}
|
||||
tmp = &BTRFS_I(inode)->io_tree;
|
||||
BTRFS_I(inode)->root = root;
|
||||
|
|
@ -333,6 +333,7 @@ static int test_find_delalloc(u32 sectorsize, u32 nodesize)
|
|||
process_page_range(inode, 0, total_dirty - 1,
|
||||
PROCESS_UNLOCK | PROCESS_RELEASE);
|
||||
iput(inode);
|
||||
out_root_info:
|
||||
btrfs_free_dummy_root(root);
|
||||
btrfs_free_dummy_fs_info(fs_info);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -458,8 +458,19 @@ static int record_root_in_trans(struct btrfs_trans_handle *trans,
|
|||
* through btrfs_record_root_in_trans without having to take the
|
||||
* lock. smp_wmb() makes sure that all the writes above are
|
||||
* done before we pop in the zero below
|
||||
*
|
||||
* If @force is true, it means the call is from
|
||||
* qgroup_account_snapshot(), which only requires radix tree
|
||||
* tracking.
|
||||
* We should not force reloc root creation here, as the root
|
||||
* may have already been modified, and in that case
|
||||
* root->commit_root has already been dropped.
|
||||
*
|
||||
* Using that commit root will cause the reloc root to refer
|
||||
* to a deleted extent, causing extent tree corruption.
|
||||
*/
|
||||
ret = btrfs_init_reloc_root(trans, root);
|
||||
if (!force)
|
||||
ret = btrfs_init_reloc_root(trans, root);
|
||||
smp_mb__before_atomic();
|
||||
clear_bit(BTRFS_ROOT_IN_TRANS_SETUP, &root->state);
|
||||
}
|
||||
|
|
@ -2583,6 +2594,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
|
|||
ret = btrfs_write_and_wait_transaction(trans);
|
||||
if (unlikely(ret)) {
|
||||
btrfs_err(fs_info, "error while writing out transaction: %pe", ERR_PTR(ret));
|
||||
/*
|
||||
* Abort before releasing tree_log_mutex, so a log sync waiting
|
||||
* on it sees the fs error and skips writing super_for_commit
|
||||
* for this failed transaction. See btrfs_sync_log().
|
||||
*/
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
mutex_unlock(&fs_info->tree_log_mutex);
|
||||
goto scrub_continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3117,7 +3117,11 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
|
|||
error_sysfs:
|
||||
btrfs_sysfs_remove_device(device);
|
||||
mutex_lock(&fs_info->fs_devices->device_list_mutex);
|
||||
if (seeding_dev)
|
||||
btrfs_assign_next_active_device(device, seed_devices->latest_dev);
|
||||
mutex_lock(&fs_info->chunk_mutex);
|
||||
if (!list_empty(&device->post_commit_list))
|
||||
list_del_init(&device->post_commit_list);
|
||||
list_del_rcu(&device->dev_list);
|
||||
list_del(&device->dev_alloc_list);
|
||||
fs_info->fs_devices->num_devices--;
|
||||
|
|
|
|||
|
|
@ -2626,16 +2626,13 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
|
|||
down_read(&dev_replace->rwsem);
|
||||
map = block_group->physical_map;
|
||||
for (i = 0; i < map->num_stripes; i++) {
|
||||
|
||||
ret = call_zone_finish(block_group, &map->stripes[i]);
|
||||
if (ret) {
|
||||
up_read(&dev_replace->rwsem);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
up_read(&dev_replace->rwsem);
|
||||
|
||||
if (!fully_written)
|
||||
if (!ret && !fully_written)
|
||||
btrfs_dec_block_group_ro(block_group);
|
||||
|
||||
spin_lock(&fs_info->zone_active_bgs_lock);
|
||||
|
|
@ -2648,7 +2645,7 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
|
|||
|
||||
clear_and_wake_up_bit(BTRFS_FS_NEED_ZONE_FINISH, &fs_info->flags);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_zone_finish(struct btrfs_block_group *block_group)
|
||||
|
|
@ -2713,6 +2710,7 @@ int btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 leng
|
|||
{
|
||||
struct btrfs_block_group *block_group;
|
||||
u64 min_alloc_bytes;
|
||||
int ret = 0;
|
||||
|
||||
if (!btrfs_is_zoned(fs_info))
|
||||
return 0;
|
||||
|
|
@ -2732,11 +2730,11 @@ int btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 leng
|
|||
block_group->start + block_group->zone_capacity)
|
||||
goto out;
|
||||
|
||||
do_zone_finish(block_group, true);
|
||||
ret = do_zone_finish(block_group, true);
|
||||
|
||||
out:
|
||||
btrfs_put_block_group(block_group);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void btrfs_zone_finish_endio_workfn(struct work_struct *work)
|
||||
|
|
|
|||
|
|
@ -307,8 +307,17 @@ struct list_head *zstd_get_workspace(struct btrfs_fs_info *fs_info, int level)
|
|||
DEFINE_WAIT(wait);
|
||||
|
||||
prepare_to_wait(&zwsm->wait, &wait, TASK_UNINTERRUPTIBLE);
|
||||
schedule();
|
||||
/*
|
||||
* Re-check after being queued: zstd_put_workspace() only wakes
|
||||
* a queue that already has a sleeper, so a workspace returned
|
||||
* since the failed allocation woke nobody.
|
||||
*/
|
||||
ws = zstd_find_workspace(fs_info, level);
|
||||
if (!ws)
|
||||
schedule();
|
||||
finish_wait(&zwsm->wait, &wait);
|
||||
if (ws)
|
||||
return ws;
|
||||
|
||||
goto again;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user