Skip to content

Commit 12eba99

Browse files
zhangyi089tytso
authored andcommitted
ext4: make ext4_es_insert_delayed_block() insert multi-blocks
Rename ext4_es_insert_delayed_block() to ext4_es_insert_delayed_extent() and pass length parameter to make it insert multiple delalloc blocks at a time. For the case of bigalloc, split the allocated parameter to lclu_allocated and end_allocated. lclu_allocated indicates the allocation state of the cluster which is containing the lblk, end_allocated indicates the allocation state of the extent end, clusters in the middle of delay allocated extent must be unallocated. Signed-off-by: Zhang Yi <[email protected]> Reviewed-by: Jan Kara <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent bb6b180 commit 12eba99

File tree

4 files changed

+62
-31
lines changed

4 files changed

+62
-31
lines changed

fs/ext4/extents_status.c

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,34 +2054,49 @@ bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk)
20542054
}
20552055

20562056
/*
2057-
* ext4_es_insert_delayed_block - adds a delayed block to the extents status
2058-
* tree, adding a pending reservation where
2059-
* needed
2057+
* ext4_es_insert_delayed_extent - adds some delayed blocks to the extents
2058+
* status tree, adding a pending reservation
2059+
* where needed
20602060
*
20612061
* @inode - file containing the newly added block
2062-
* @lblk - logical block to be added
2063-
* @allocated - indicates whether a physical cluster has been allocated for
2064-
* the logical cluster that contains the block
2062+
* @lblk - start logical block to be added
2063+
* @len - length of blocks to be added
2064+
* @lclu_allocated/end_allocated - indicates whether a physical cluster has
2065+
* been allocated for the logical cluster
2066+
* that contains the start/end block. Note that
2067+
* end_allocated should always be set to false
2068+
* if the start and the end block are in the
2069+
* same cluster
20652070
*/
2066-
void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
2067-
bool allocated)
2071+
void ext4_es_insert_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
2072+
ext4_lblk_t len, bool lclu_allocated,
2073+
bool end_allocated)
20682074
{
2075+
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
20692076
struct extent_status newes;
2077+
ext4_lblk_t end = lblk + len - 1;
20702078
int err1 = 0, err2 = 0, err3 = 0;
20712079
struct extent_status *es1 = NULL;
20722080
struct extent_status *es2 = NULL;
2073-
struct pending_reservation *pr = NULL;
2081+
struct pending_reservation *pr1 = NULL;
2082+
struct pending_reservation *pr2 = NULL;
20742083

20752084
if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
20762085
return;
20772086

2078-
es_debug("add [%u/1) delayed to extent status tree of inode %lu\n",
2079-
lblk, inode->i_ino);
2087+
es_debug("add [%u/%u) delayed to extent status tree of inode %lu\n",
2088+
lblk, len, inode->i_ino);
2089+
if (!len)
2090+
return;
2091+
2092+
WARN_ON_ONCE((EXT4_B2C(sbi, lblk) == EXT4_B2C(sbi, end)) &&
2093+
end_allocated);
20802094

20812095
newes.es_lblk = lblk;
2082-
newes.es_len = 1;
2096+
newes.es_len = len;
20832097
ext4_es_store_pblock_status(&newes, ~0, EXTENT_STATUS_DELAYED);
2084-
trace_ext4_es_insert_delayed_block(inode, &newes, allocated);
2098+
trace_ext4_es_insert_delayed_extent(inode, &newes, lclu_allocated,
2099+
end_allocated);
20852100

20862101
ext4_es_insert_extent_check(inode, &newes);
20872102

@@ -2090,11 +2105,15 @@ void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
20902105
es1 = __es_alloc_extent(true);
20912106
if ((err1 || err2) && !es2)
20922107
es2 = __es_alloc_extent(true);
2093-
if ((err1 || err2 || err3) && allocated && !pr)
2094-
pr = __alloc_pending(true);
2108+
if (err1 || err2 || err3) {
2109+
if (lclu_allocated && !pr1)
2110+
pr1 = __alloc_pending(true);
2111+
if (end_allocated && !pr2)
2112+
pr2 = __alloc_pending(true);
2113+
}
20952114
write_lock(&EXT4_I(inode)->i_es_lock);
20962115

2097-
err1 = __es_remove_extent(inode, lblk, lblk, NULL, es1);
2116+
err1 = __es_remove_extent(inode, lblk, end, NULL, es1);
20982117
if (err1 != 0)
20992118
goto error;
21002119
/* Free preallocated extent if it didn't get used. */
@@ -2114,13 +2133,22 @@ void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
21142133
es2 = NULL;
21152134
}
21162135

2117-
if (allocated) {
2118-
err3 = __insert_pending(inode, lblk, &pr);
2136+
if (lclu_allocated) {
2137+
err3 = __insert_pending(inode, lblk, &pr1);
21192138
if (err3 != 0)
21202139
goto error;
2121-
if (pr) {
2122-
__free_pending(pr);
2123-
pr = NULL;
2140+
if (pr1) {
2141+
__free_pending(pr1);
2142+
pr1 = NULL;
2143+
}
2144+
}
2145+
if (end_allocated) {
2146+
err3 = __insert_pending(inode, end, &pr2);
2147+
if (err3 != 0)
2148+
goto error;
2149+
if (pr2) {
2150+
__free_pending(pr2);
2151+
pr2 = NULL;
21242152
}
21252153
}
21262154
error:

fs/ext4/extents_status.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,9 @@ extern void ext4_exit_pending(void);
249249
extern void ext4_init_pending_tree(struct ext4_pending_tree *tree);
250250
extern void ext4_remove_pending(struct inode *inode, ext4_lblk_t lblk);
251251
extern bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk);
252-
extern void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
253-
bool allocated);
252+
extern void ext4_es_insert_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
253+
ext4_lblk_t len, bool lclu_allocated,
254+
bool end_allocated);
254255
extern unsigned int ext4_es_delayed_clu(struct inode *inode, ext4_lblk_t lblk,
255256
ext4_lblk_t len);
256257
extern void ext4_clear_inode_es(struct inode *inode);

fs/ext4/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1702,7 +1702,7 @@ static int ext4_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk)
17021702
}
17031703
}
17041704

1705-
ext4_es_insert_delayed_block(inode, lblk, allocated);
1705+
ext4_es_insert_delayed_extent(inode, lblk, 1, allocated, false);
17061706
return 0;
17071707
}
17081708

include/trace/events/ext4.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2478,11 +2478,11 @@ TRACE_EVENT(ext4_es_shrink,
24782478
__entry->scan_time, __entry->nr_skipped, __entry->retried)
24792479
);
24802480

2481-
TRACE_EVENT(ext4_es_insert_delayed_block,
2481+
TRACE_EVENT(ext4_es_insert_delayed_extent,
24822482
TP_PROTO(struct inode *inode, struct extent_status *es,
2483-
bool allocated),
2483+
bool lclu_allocated, bool end_allocated),
24842484

2485-
TP_ARGS(inode, es, allocated),
2485+
TP_ARGS(inode, es, lclu_allocated, end_allocated),
24862486

24872487
TP_STRUCT__entry(
24882488
__field( dev_t, dev )
@@ -2491,7 +2491,8 @@ TRACE_EVENT(ext4_es_insert_delayed_block,
24912491
__field( ext4_lblk_t, len )
24922492
__field( ext4_fsblk_t, pblk )
24932493
__field( char, status )
2494-
__field( bool, allocated )
2494+
__field( bool, lclu_allocated )
2495+
__field( bool, end_allocated )
24952496
),
24962497

24972498
TP_fast_assign(
@@ -2501,16 +2502,17 @@ TRACE_EVENT(ext4_es_insert_delayed_block,
25012502
__entry->len = es->es_len;
25022503
__entry->pblk = ext4_es_show_pblock(es);
25032504
__entry->status = ext4_es_status(es);
2504-
__entry->allocated = allocated;
2505+
__entry->lclu_allocated = lclu_allocated;
2506+
__entry->end_allocated = end_allocated;
25052507
),
25062508

25072509
TP_printk("dev %d,%d ino %lu es [%u/%u) mapped %llu status %s "
2508-
"allocated %d",
2510+
"allocated %d %d",
25092511
MAJOR(__entry->dev), MINOR(__entry->dev),
25102512
(unsigned long) __entry->ino,
25112513
__entry->lblk, __entry->len,
25122514
__entry->pblk, show_extent_status(__entry->status),
2513-
__entry->allocated)
2515+
__entry->lclu_allocated, __entry->end_allocated)
25142516
);
25152517

25162518
/* fsmap traces */

0 commit comments

Comments
 (0)