* [PATCH 0/3 v2] Switch to on-stack variables for block reserves
@ 2025-06-04 9:29 David Sterba
2025-06-04 9:29 ` [PATCH 1/3] btrfs: use on-stack variable for block reserve in btrfs_evict_inode() David Sterba
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: David Sterba @ 2025-06-04 9:29 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
The block reserve structure is small enough to fit on stack so do that
in a few functions and avoid allocation.
v2:
- drop patch replacing allocated reserve in relocation, crash in btrfs/190
- v1 https://lore.kernel.org/linux-btrfs/cover.1695408280.git.dsterba@suse.com/
David Sterba (3):
btrfs: use on-stack variable for block reserve in btrfs_evict_inode()
btrfs: use on-stack variable for block reserve in btrfs_truncate()
btrfs: use on-stack variable for block reserve in
btrfs_replace_file_extents()
fs/btrfs/file.c | 29 ++++++++++++-----------------
fs/btrfs/inode.c | 47 ++++++++++++++++++++++-------------------------
2 files changed, 34 insertions(+), 42 deletions(-)
--
2.47.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] btrfs: use on-stack variable for block reserve in btrfs_evict_inode()
2025-06-04 9:29 [PATCH 0/3 v2] Switch to on-stack variables for block reserves David Sterba
@ 2025-06-04 9:29 ` David Sterba
2025-06-04 9:29 ` [PATCH 2/3] btrfs: use on-stack variable for block reserve in btrfs_truncate() David Sterba
2025-06-04 9:29 ` [PATCH 3/3] btrfs: use on-stack variable for block reserve in btrfs_replace_file_extents() David Sterba
2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2025-06-04 9:29 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
We can avoid potential memory allocation failure in btrfs_evict_inode()
as the block reserve lifetime is limited to the scope of the function.
This requires +48 bytes on stack.
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/inode.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index c297963f56bd..496194832166 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5434,7 +5434,7 @@ void btrfs_evict_inode(struct inode *inode)
struct btrfs_fs_info *fs_info;
struct btrfs_trans_handle *trans;
struct btrfs_root *root = BTRFS_I(inode)->root;
- struct btrfs_block_rsv *rsv = NULL;
+ struct btrfs_block_rsv rsv;
int ret;
trace_btrfs_inode_evict(inode);
@@ -5482,11 +5482,9 @@ void btrfs_evict_inode(struct inode *inode)
*/
btrfs_kill_delayed_inode_items(BTRFS_I(inode));
- rsv = btrfs_alloc_block_rsv(fs_info, BTRFS_BLOCK_RSV_TEMP);
- if (!rsv)
- goto out;
- rsv->size = btrfs_calc_metadata_size(fs_info, 1);
- rsv->failfast = true;
+ btrfs_init_metadata_block_rsv(fs_info, &rsv, BTRFS_BLOCK_RSV_TEMP);
+ rsv.size = btrfs_calc_metadata_size(fs_info, 1);
+ rsv.failfast = true;
btrfs_i_size_write(BTRFS_I(inode), 0);
@@ -5498,11 +5496,11 @@ void btrfs_evict_inode(struct inode *inode)
.min_type = 0,
};
- trans = evict_refill_and_join(root, rsv);
+ trans = evict_refill_and_join(root, &rsv);
if (IS_ERR(trans))
- goto out;
+ goto out_release;
- trans->block_rsv = rsv;
+ trans->block_rsv = &rsv;
ret = btrfs_truncate_inode_items(trans, root, &control);
trans->block_rsv = &fs_info->trans_block_rsv;
@@ -5514,7 +5512,7 @@ void btrfs_evict_inode(struct inode *inode)
*/
btrfs_btree_balance_dirty_nodelay(fs_info);
if (ret && ret != -ENOSPC && ret != -EAGAIN)
- goto out;
+ goto out_release;
else if (!ret)
break;
}
@@ -5528,16 +5526,17 @@ void btrfs_evict_inode(struct inode *inode)
* If it turns out that we are dropping too many of these, we might want
* to add a mechanism for retrying these after a commit.
*/
- trans = evict_refill_and_join(root, rsv);
+ trans = evict_refill_and_join(root, &rsv);
if (!IS_ERR(trans)) {
- trans->block_rsv = rsv;
+ trans->block_rsv = &rsv;
btrfs_orphan_del(trans, BTRFS_I(inode));
trans->block_rsv = &fs_info->trans_block_rsv;
btrfs_end_transaction(trans);
}
+out_release:
+ btrfs_block_rsv_release(fs_info, &rsv, (u64)-1, NULL);
out:
- btrfs_free_block_rsv(fs_info, rsv);
/*
* If we didn't successfully delete, the orphan item will still be in
* the tree and we'll retry on the next mount. Again, we might also want
--
2.47.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] btrfs: use on-stack variable for block reserve in btrfs_truncate()
2025-06-04 9:29 [PATCH 0/3 v2] Switch to on-stack variables for block reserves David Sterba
2025-06-04 9:29 ` [PATCH 1/3] btrfs: use on-stack variable for block reserve in btrfs_evict_inode() David Sterba
@ 2025-06-04 9:29 ` David Sterba
2025-06-04 9:29 ` [PATCH 3/3] btrfs: use on-stack variable for block reserve in btrfs_replace_file_extents() David Sterba
2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2025-06-04 9:29 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
We can avoid potential memory allocation failure in btrfs_truncate() as
the block reserve lifetime is limited to the scope of the function. This
requires +48 bytes on stack.
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/inode.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 496194832166..3976a90e3c3c 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7604,7 +7604,7 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)
};
struct btrfs_root *root = inode->root;
struct btrfs_fs_info *fs_info = root->fs_info;
- struct btrfs_block_rsv *rsv;
+ struct btrfs_block_rsv rsv;
int ret;
struct btrfs_trans_handle *trans;
u64 mask = fs_info->sectorsize - 1;
@@ -7646,11 +7646,9 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)
* 2) fs_info->trans_block_rsv - this will have 1 items worth left for
* updating the inode.
*/
- rsv = btrfs_alloc_block_rsv(fs_info, BTRFS_BLOCK_RSV_TEMP);
- if (!rsv)
- return -ENOMEM;
- rsv->size = min_size;
- rsv->failfast = true;
+ btrfs_init_metadata_block_rsv(fs_info, &rsv, BTRFS_BLOCK_RSV_TEMP);
+ rsv.size = min_size;
+ rsv.failfast = true;
/*
* 1 for the truncate slack space
@@ -7663,7 +7661,7 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)
}
/* Migrate the slack space for the truncate to our reserve */
- ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, rsv,
+ ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, &rsv,
min_size, false);
/*
* We have reserved 2 metadata units when we started the transaction and
@@ -7675,7 +7673,7 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)
goto out;
}
- trans->block_rsv = rsv;
+ trans->block_rsv = &rsv;
while (1) {
struct extent_state *cached_state = NULL;
@@ -7718,9 +7716,9 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)
break;
}
- btrfs_block_rsv_release(fs_info, rsv, -1, NULL);
+ btrfs_block_rsv_release(fs_info, &rsv, -1, NULL);
ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv,
- rsv, min_size, false);
+ &rsv, min_size, false);
/*
* We have reserved 2 metadata units when we started the
* transaction and min_size matches 1 unit, so this should never
@@ -7729,7 +7727,7 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)
if (WARN_ON(ret))
break;
- trans->block_rsv = rsv;
+ trans->block_rsv = &rsv;
}
/*
@@ -7768,7 +7766,7 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback)
btrfs_btree_balance_dirty(fs_info);
}
out:
- btrfs_free_block_rsv(fs_info, rsv);
+ btrfs_block_rsv_release(fs_info, &rsv, (u64)-1, NULL);
/*
* So if we truncate and then write and fsync we normally would just
* write the extents that changed, which is a problem if we need to
--
2.47.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] btrfs: use on-stack variable for block reserve in btrfs_replace_file_extents()
2025-06-04 9:29 [PATCH 0/3 v2] Switch to on-stack variables for block reserves David Sterba
2025-06-04 9:29 ` [PATCH 1/3] btrfs: use on-stack variable for block reserve in btrfs_evict_inode() David Sterba
2025-06-04 9:29 ` [PATCH 2/3] btrfs: use on-stack variable for block reserve in btrfs_truncate() David Sterba
@ 2025-06-04 9:29 ` David Sterba
2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2025-06-04 9:29 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
We can avoid potential memory allocation failure in
btrfs_replace_file_extents() as the block reserve lifetime is limited to
the scope of the function. This requires +48 bytes on stack.
Signed-off-by: David Sterba <dsterba@suse.com>
---
fs/btrfs/file.c | 29 ++++++++++++-----------------
1 file changed, 12 insertions(+), 17 deletions(-)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 8ce6f45f45e0..2902de88dd1b 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2341,7 +2341,7 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
u64 min_size = btrfs_calc_insert_metadata_size(fs_info, 1);
u64 ino_size = round_up(inode->vfs_inode.i_size, fs_info->sectorsize);
struct btrfs_trans_handle *trans = NULL;
- struct btrfs_block_rsv *rsv;
+ struct btrfs_block_rsv rsv;
unsigned int rsv_count;
u64 cur_offset;
u64 len = end - start;
@@ -2350,13 +2350,9 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
if (end <= start)
return -EINVAL;
- rsv = btrfs_alloc_block_rsv(fs_info, BTRFS_BLOCK_RSV_TEMP);
- if (!rsv) {
- ret = -ENOMEM;
- goto out;
- }
- rsv->size = btrfs_calc_insert_metadata_size(fs_info, 1);
- rsv->failfast = true;
+ btrfs_init_metadata_block_rsv(fs_info, &rsv, BTRFS_BLOCK_RSV_TEMP);
+ rsv.size = btrfs_calc_insert_metadata_size(fs_info, 1);
+ rsv.failfast = true;
/*
* 1 - update the inode
@@ -2373,14 +2369,14 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
trans = NULL;
- goto out_free;
+ goto out_release;
}
- ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, rsv,
+ ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv, &rsv,
min_size, false);
if (WARN_ON(ret))
goto out_trans;
- trans->block_rsv = rsv;
+ trans->block_rsv = &rsv;
cur_offset = start;
drop_args.path = path;
@@ -2496,10 +2492,10 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
}
ret = btrfs_block_rsv_migrate(&fs_info->trans_block_rsv,
- rsv, min_size, false);
+ &rsv, min_size, false);
if (WARN_ON(ret))
break;
- trans->block_rsv = rsv;
+ trans->block_rsv = &rsv;
cur_offset = drop_args.drop_end;
len = end - cur_offset;
@@ -2576,16 +2572,15 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
out_trans:
if (!trans)
- goto out_free;
+ goto out_release;
trans->block_rsv = &fs_info->trans_block_rsv;
if (ret)
btrfs_end_transaction(trans);
else
*trans_out = trans;
-out_free:
- btrfs_free_block_rsv(fs_info, rsv);
-out:
+out_release:
+ btrfs_block_rsv_release(fs_info, &rsv, (u64)-1, NULL);
return ret;
}
--
2.47.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-06-04 9:37 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-04 9:29 [PATCH 0/3 v2] Switch to on-stack variables for block reserves David Sterba
2025-06-04 9:29 ` [PATCH 1/3] btrfs: use on-stack variable for block reserve in btrfs_evict_inode() David Sterba
2025-06-04 9:29 ` [PATCH 2/3] btrfs: use on-stack variable for block reserve in btrfs_truncate() David Sterba
2025-06-04 9:29 ` [PATCH 3/3] btrfs: use on-stack variable for block reserve in btrfs_replace_file_extents() David Sterba
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox