Skip to content

Commit d1a3924

Browse files
Kemeng Shitytso
authored andcommitted
ext4: call ext4_mb_mark_free_simple to free continuous bits in found chunk
In mb_mark_used, we will find free chunk and mark it inuse. For chunk in mid of passed range, we could simply mark whole chunk inuse. For chunk at end of range, we may need to mark a continuous bits at end of part of chunk inuse and keep rest part of chunk free. To only mark a part of chunk inuse, we firstly mark whole chunk inuse and then mark a continuous range at end of chunk free. Function mb_mark_used does several times of "mb_find_buddy; mb_clear_bit; ..." to mark a continuous range free which can be done by simply calling ext4_mb_mark_free_simple which free continuous bits in a more effective way. Just call ext4_mb_mark_free_simple in mb_mark_used to use existing and effective code to free continuous blocks in chunk at end of passed range. Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20240424061904.987525-4-shikemeng@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent d0b8862 commit d1a3924

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

fs/ext4/mballoc.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,13 +2044,12 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
20442044
int ord;
20452045
int mlen = 0;
20462046
int max = 0;
2047-
int cur;
20482047
int start = ex->fe_start;
20492048
int len = ex->fe_len;
20502049
unsigned ret = 0;
20512050
int len0 = len;
20522051
void *buddy;
2053-
bool split = false;
2052+
int ord_start, ord_end;
20542053

20552054
BUG_ON(start + len > (e4b->bd_sb->s_blocksize << 3));
20562055
BUG_ON(e4b->bd_group != ex->fe_group);
@@ -2075,16 +2074,12 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
20752074

20762075
/* let's maintain buddy itself */
20772076
while (len) {
2078-
if (!split)
2079-
ord = mb_find_order_for_block(e4b, start);
2077+
ord = mb_find_order_for_block(e4b, start);
20802078

20812079
if (((start >> ord) << ord) == start && len >= (1 << ord)) {
20822080
/* the whole chunk may be allocated at once! */
20832081
mlen = 1 << ord;
2084-
if (!split)
2085-
buddy = mb_find_buddy(e4b, ord, &max);
2086-
else
2087-
split = false;
2082+
buddy = mb_find_buddy(e4b, ord, &max);
20882083
BUG_ON((start >> ord) >= max);
20892084
mb_set_bit(start >> ord, buddy);
20902085
e4b->bd_info->bb_counters[ord]--;
@@ -2098,20 +2093,29 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
20982093
if (ret == 0)
20992094
ret = len | (ord << 16);
21002095

2101-
/* we have to split large buddy */
21022096
BUG_ON(ord <= 0);
21032097
buddy = mb_find_buddy(e4b, ord, &max);
21042098
mb_set_bit(start >> ord, buddy);
21052099
e4b->bd_info->bb_counters[ord]--;
21062100

2107-
ord--;
2108-
cur = (start >> ord) & ~1U;
2109-
buddy = mb_find_buddy(e4b, ord, &max);
2110-
mb_clear_bit(cur, buddy);
2111-
mb_clear_bit(cur + 1, buddy);
2112-
e4b->bd_info->bb_counters[ord]++;
2113-
e4b->bd_info->bb_counters[ord]++;
2114-
split = true;
2101+
ord_start = (start >> ord) << ord;
2102+
ord_end = ord_start + (1 << ord);
2103+
/* first chunk */
2104+
if (start > ord_start)
2105+
ext4_mb_mark_free_simple(e4b->bd_sb, e4b->bd_buddy,
2106+
ord_start, start - ord_start,
2107+
e4b->bd_info);
2108+
2109+
/* last chunk */
2110+
if (start + len < ord_end) {
2111+
ext4_mb_mark_free_simple(e4b->bd_sb, e4b->bd_buddy,
2112+
start + len,
2113+
ord_end - (start + len),
2114+
e4b->bd_info);
2115+
break;
2116+
}
2117+
len = start + len - ord_end;
2118+
start = ord_end;
21152119
}
21162120
mb_set_largest_free_order(e4b->bd_sb, e4b->bd_info);
21172121

0 commit comments

Comments
 (0)