mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
for-6.10-rc5-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmZ9gV0ACgkQxWXV+ddt WDsK2hAAmbOArbK5QHprawdOqqvJL46yoGCMba798EjYo53+hO1F8/lb531+zCUI GDhdIC2mHdRIkARJ8Cde5POUjID1Kv3Rlc0rdHy3nOw38WZmA/+HdkcKzQhsDFSR /FX9RKSWiu0xl6JdCLh4KkIWE+2m1v1kybhvRHCKb+70iBua1e+OSoM33BeiIhrP yoFwMwIbzG2CoZOHoobDxUjs9ZMUHm4wH0csJYG9R59Vv7uLBOgpWuQB46iqpoj4 EYR8Sg8PscI7YXa0y8VTP3pdrNMW48IC6jerIAKHUeWRWRoTCh9He+3/E4xjNHxz 3Pm+Aat5QYdsqmE68IbeN5c7QB1YAdUCgoJJJwAFjwe9WtTn8RS9RiMjWIr+VHYm E3REibQI151p0yHwAl8xPHDiTecmlNisof0eg6gzHdvODm/NYFuFapD+aDxWribX G63dOa8Fy0h4pwDoF73Rd2YYbtO6tDVSNVIG3bWpPep3r+SI/oC4JMHbmn1aqmqF c0/ZYVbsx/Hm066l4LCrpgi7kJ8en2zQ8MmcZHHt+2gXe1AyAON7kvRHaEizUCaA fnLVhQvaOofC4g7DJc1JkwyLc9VF5hMTYUhldoJvqj1wm2qsT/siJgKVvllRGoMs FU2qlWYaN/fPRylyEySyZPq/sWKHOAZZSOhyWM8SB2nYoBXNkO0= =qpEp -----END PGP SIGNATURE----- Merge tag 'for-6.10-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: - fix quota root leak after quota disable failure - fix condition when checking if a zone can be added as free - allocate inode in NOFS context during logging or tree-log replay - handle raid-stripe-tree lookup correctly during scrub * tag 'for-6.10-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: qgroup: fix quota root leak after quota disable failure btrfs: scrub: handle RST lookup error correctly btrfs: zoned: fix initial free space detection btrfs: use NOFS context when getting inodes during logging and log replay
This commit is contained in:
commit
66e55ff12e
@ -2697,7 +2697,7 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group,
|
||||
u64 offset = bytenr - block_group->start;
|
||||
u64 to_free, to_unusable;
|
||||
int bg_reclaim_threshold = 0;
|
||||
bool initial = (size == block_group->length);
|
||||
bool initial = ((size == block_group->length) && (block_group->alloc_offset == 0));
|
||||
u64 reclaimable_unusable;
|
||||
|
||||
WARN_ON(!initial && offset + size > block_group->zone_capacity);
|
||||
|
@ -1351,7 +1351,7 @@ static int flush_reservations(struct btrfs_fs_info *fs_info)
|
||||
|
||||
int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct btrfs_root *quota_root;
|
||||
struct btrfs_root *quota_root = NULL;
|
||||
struct btrfs_trans_handle *trans = NULL;
|
||||
int ret = 0;
|
||||
|
||||
@ -1449,9 +1449,9 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
|
||||
btrfs_free_tree_block(trans, btrfs_root_id(quota_root),
|
||||
quota_root->node, 0, 1);
|
||||
|
||||
btrfs_put_root(quota_root);
|
||||
|
||||
out:
|
||||
btrfs_put_root(quota_root);
|
||||
mutex_unlock(&fs_info->qgroup_ioctl_lock);
|
||||
if (ret && trans)
|
||||
btrfs_end_transaction(trans);
|
||||
|
@ -1688,20 +1688,24 @@ static void scrub_submit_extent_sector_read(struct scrub_ctx *sctx,
|
||||
(i << fs_info->sectorsize_bits);
|
||||
int err;
|
||||
|
||||
io_stripe.is_scrub = true;
|
||||
stripe_len = (nr_sectors - i) << fs_info->sectorsize_bits;
|
||||
/*
|
||||
* For RST cases, we need to manually split the bbio to
|
||||
* follow the RST boundary.
|
||||
*/
|
||||
err = btrfs_map_block(fs_info, BTRFS_MAP_READ, logical,
|
||||
&stripe_len, &bioc, &io_stripe, &mirror);
|
||||
btrfs_put_bioc(bioc);
|
||||
if (err < 0) {
|
||||
set_bit(i, &stripe->io_error_bitmap);
|
||||
set_bit(i, &stripe->error_bitmap);
|
||||
continue;
|
||||
}
|
||||
|
||||
bbio = btrfs_bio_alloc(stripe->nr_sectors, REQ_OP_READ,
|
||||
fs_info, scrub_read_endio, stripe);
|
||||
bbio->bio.bi_iter.bi_sector = logical >> SECTOR_SHIFT;
|
||||
|
||||
io_stripe.is_scrub = true;
|
||||
err = btrfs_map_block(fs_info, BTRFS_MAP_READ, logical,
|
||||
&stripe_len, &bioc, &io_stripe,
|
||||
&mirror);
|
||||
btrfs_put_bioc(bioc);
|
||||
if (err) {
|
||||
btrfs_bio_end_io(bbio,
|
||||
errno_to_blk_status(err));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
__bio_add_page(&bbio->bio, page, fs_info->sectorsize, pgoff);
|
||||
|
@ -138,6 +138,25 @@ static void wait_log_commit(struct btrfs_root *root, int transid);
|
||||
* and once to do all the other items.
|
||||
*/
|
||||
|
||||
static struct inode *btrfs_iget_logging(u64 objectid, struct btrfs_root *root)
|
||||
{
|
||||
unsigned int nofs_flag;
|
||||
struct inode *inode;
|
||||
|
||||
/*
|
||||
* We're holding a transaction handle whether we are logging or
|
||||
* replaying a log tree, so we must make sure NOFS semantics apply
|
||||
* because btrfs_alloc_inode() may be triggered and it uses GFP_KERNEL
|
||||
* to allocate an inode, which can recurse back into the filesystem and
|
||||
* attempt a transaction commit, resulting in a deadlock.
|
||||
*/
|
||||
nofs_flag = memalloc_nofs_save();
|
||||
inode = btrfs_iget(root->fs_info->sb, objectid, root);
|
||||
memalloc_nofs_restore(nofs_flag);
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
/*
|
||||
* start a sub transaction and setup the log tree
|
||||
* this increments the log tree writer count to make the people
|
||||
@ -600,7 +619,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root,
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
inode = btrfs_iget(root->fs_info->sb, objectid, root);
|
||||
inode = btrfs_iget_logging(objectid, root);
|
||||
if (IS_ERR(inode))
|
||||
inode = NULL;
|
||||
return inode;
|
||||
@ -5438,7 +5457,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_log_ctx *ctx)
|
||||
{
|
||||
struct btrfs_root *root = start_inode->root;
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct btrfs_path *path;
|
||||
LIST_HEAD(dir_list);
|
||||
struct btrfs_dir_list *dir_elem;
|
||||
@ -5499,7 +5517,7 @@ again:
|
||||
continue;
|
||||
|
||||
btrfs_release_path(path);
|
||||
di_inode = btrfs_iget(fs_info->sb, di_key.objectid, root);
|
||||
di_inode = btrfs_iget_logging(di_key.objectid, root);
|
||||
if (IS_ERR(di_inode)) {
|
||||
ret = PTR_ERR(di_inode);
|
||||
goto out;
|
||||
@ -5559,7 +5577,7 @@ again:
|
||||
btrfs_add_delayed_iput(curr_inode);
|
||||
curr_inode = NULL;
|
||||
|
||||
vfs_inode = btrfs_iget(fs_info->sb, ino, root);
|
||||
vfs_inode = btrfs_iget_logging(ino, root);
|
||||
if (IS_ERR(vfs_inode)) {
|
||||
ret = PTR_ERR(vfs_inode);
|
||||
break;
|
||||
@ -5654,7 +5672,7 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans,
|
||||
if (ctx->num_conflict_inodes >= MAX_CONFLICT_INODES)
|
||||
return BTRFS_LOG_FORCE_COMMIT;
|
||||
|
||||
inode = btrfs_iget(root->fs_info->sb, ino, root);
|
||||
inode = btrfs_iget_logging(ino, root);
|
||||
/*
|
||||
* If the other inode that had a conflicting dir entry was deleted in
|
||||
* the current transaction then we either:
|
||||
@ -5755,7 +5773,6 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_log_ctx *ctx)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
@ -5786,7 +5803,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
|
||||
list_del(&curr->list);
|
||||
kfree(curr);
|
||||
|
||||
inode = btrfs_iget(fs_info->sb, ino, root);
|
||||
inode = btrfs_iget_logging(ino, root);
|
||||
/*
|
||||
* If the other inode that had a conflicting dir entry was
|
||||
* deleted in the current transaction, we need to log its parent
|
||||
@ -5797,7 +5814,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
|
||||
if (ret != -ENOENT)
|
||||
break;
|
||||
|
||||
inode = btrfs_iget(fs_info->sb, parent, root);
|
||||
inode = btrfs_iget_logging(parent, root);
|
||||
if (IS_ERR(inode)) {
|
||||
ret = PTR_ERR(inode);
|
||||
break;
|
||||
@ -6319,7 +6336,6 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_log_ctx *ctx)
|
||||
{
|
||||
const bool orig_log_new_dentries = ctx->log_new_dentries;
|
||||
struct btrfs_fs_info *fs_info = trans->fs_info;
|
||||
struct btrfs_delayed_item *item;
|
||||
int ret = 0;
|
||||
|
||||
@ -6345,7 +6361,7 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
|
||||
if (key.type == BTRFS_ROOT_ITEM_KEY)
|
||||
continue;
|
||||
|
||||
di_inode = btrfs_iget(fs_info->sb, key.objectid, inode->root);
|
||||
di_inode = btrfs_iget_logging(key.objectid, inode->root);
|
||||
if (IS_ERR(di_inode)) {
|
||||
ret = PTR_ERR(di_inode);
|
||||
break;
|
||||
@ -6729,7 +6745,6 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_inode *inode,
|
||||
struct btrfs_log_ctx *ctx)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = trans->fs_info;
|
||||
int ret;
|
||||
struct btrfs_path *path;
|
||||
struct btrfs_key key;
|
||||
@ -6794,8 +6809,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
|
||||
cur_offset = item_size;
|
||||
}
|
||||
|
||||
dir_inode = btrfs_iget(fs_info->sb, inode_key.objectid,
|
||||
root);
|
||||
dir_inode = btrfs_iget_logging(inode_key.objectid, root);
|
||||
/*
|
||||
* If the parent inode was deleted, return an error to
|
||||
* fallback to a transaction commit. This is to prevent
|
||||
@ -6857,7 +6871,6 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
|
||||
btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]);
|
||||
|
||||
while (true) {
|
||||
struct btrfs_fs_info *fs_info = root->fs_info;
|
||||
struct extent_buffer *leaf;
|
||||
int slot;
|
||||
struct btrfs_key search_key;
|
||||
@ -6872,7 +6885,7 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
|
||||
search_key.objectid = found_key.offset;
|
||||
search_key.type = BTRFS_INODE_ITEM_KEY;
|
||||
search_key.offset = 0;
|
||||
inode = btrfs_iget(fs_info->sb, ino, root);
|
||||
inode = btrfs_iget_logging(ino, root);
|
||||
if (IS_ERR(inode))
|
||||
return PTR_ERR(inode);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user