From nobody Wed Feb 11 15:46:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 02C9BC61DA4 for ; Mon, 13 Mar 2023 20:13:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230232AbjCMUNU (ORCPT ); Mon, 13 Mar 2023 16:13:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230123AbjCMUNK (ORCPT ); Mon, 13 Mar 2023 16:13:10 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D36D687373; Mon, 13 Mar 2023 13:12:44 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 76476B81440; Mon, 13 Mar 2023 20:12:30 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2B725C4339C; Mon, 13 Mar 2023 20:12:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678738349; bh=hiJPq+Qod/oo0MGBfHO6b0w87dgL0jFHZXJ7ITNisLA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gIwZrqVC8Kk0TCZ8lTIznDZNdWEnxjYVDW0AG/z6TUUv2Qrrp0pK1eK/v9Sv9ngfR 1gSn/Q8XFpM2FG3o7vjNtykSJ98wBs/Lx6RuPybTscLXnE9YuROMCyPXAiyvpcYeTS GenY39o901vqeCPlSqSl2YMOwMlzzJO1SjQSL4NR66oJwwJG/yCiUF4NEL21mVVawa p8kdUvYrjoXBxEvBGFsxoAehRTDrtFs+LdwFvq2tzjzaJu/TPxBzS+clzyn1mi3jMH zz10bGY2gswzAvCKrPYn+NK2uEzaKOWzPnFPO2u+31cCkQf/Ji+cYWL/4wk9d+EuKH P51+dEadP1zbQ== From: Jaegeuk Kim To: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net Cc: Jaegeuk Kim , stable@vger.kernel.org Subject: [PATCH 2/3] f2fs: factor out discard_cmd usage from general rb_tree use Date: Mon, 13 Mar 2023 13:12:15 -0700 Message-Id: <20230313201216.924234-3-jaegeuk@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230313201216.924234-1-jaegeuk@kernel.org> References: <20230313201216.924234-1-jaegeuk@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This is a second part to remove the mixed use of rb_tree in discard_cmd from extent_cache. This should also fix arm32 memory alignment issue caused by shared rb_entry. [struct discard_cmd] [struct rb_entry] [0] struct rb_node rb_node; [0] struct rb_node rb_node; union { union { struct { struct { [16] block_t lstart; [12] unsigned int ofs; block_t len; unsigned int len; }; unsigned long long key; } __packed; Cc: Fixes: 004b68621897 ("f2fs: use rb-tree to track pending discard commands") Signed-off-by: Jaegeuk Kim Reviewed-by: Chao Yu --- fs/f2fs/extent_cache.c | 36 +----- fs/f2fs/f2fs.h | 23 +--- fs/f2fs/segment.c | 252 +++++++++++++++++++++++++++-------------- 3 files changed, 169 insertions(+), 142 deletions(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index d1aa4609ca6b..5c206f941aac 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -192,7 +192,7 @@ static struct rb_entry *__lookup_rb_tree_slow(struct rb= _root_cached *root, return NULL; } =20 -struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root, +static struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root, struct rb_entry *cached_re, unsigned int ofs) { struct rb_entry *re; @@ -204,7 +204,7 @@ struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cac= hed *root, return re; } =20 -struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi, +static struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info= *sbi, struct rb_root_cached *root, struct rb_node **parent, unsigned int ofs, bool *leftmost) @@ -238,7 +238,7 @@ struct rb_node **f2fs_lookup_rb_tree_for_insert(struct = f2fs_sb_info *sbi, * in order to simplify the insertion after. * tree must stay unchanged between lookup and insertion. */ -struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root_cached *root, +static struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root_cached *roo= t, struct rb_entry *cached_re, unsigned int ofs, struct rb_entry **prev_entry, @@ -311,36 +311,6 @@ struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_roo= t_cached *root, return re; } =20 -bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi, - struct rb_root_cached *root) -{ -#ifdef CONFIG_F2FS_CHECK_FS - struct rb_node *cur =3D rb_first_cached(root), *next; - struct rb_entry *cur_re, *next_re; - - if (!cur) - return true; - - while (cur) { - next =3D rb_next(cur); - if (!next) - return true; - - cur_re =3D rb_entry(cur, struct rb_entry, rb_node); - next_re =3D rb_entry(next, struct rb_entry, rb_node); - - if (cur_re->ofs + cur_re->len > next_re->ofs) { - f2fs_info(sbi, "inconsistent rbtree, cur(%u, %u) next(%u, %u)", - cur_re->ofs, cur_re->len, - next_re->ofs, next_re->len); - return false; - } - cur =3D next; - } -#endif - return true; -} - static struct kmem_cache *extent_tree_slab; static struct kmem_cache *extent_node_slab; =20 diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 9396549e112d..6e04fea9c34f 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -353,15 +353,7 @@ struct discard_info { =20 struct discard_cmd { struct rb_node rb_node; /* rb node located in rb-tree */ - union { - struct { - block_t lstart; /* logical start address */ - block_t len; /* length */ - block_t start; /* actual start address in dev */ - }; - struct discard_info di; /* discard info */ - - }; + struct discard_info di; /* discard info */ struct list_head list; /* command list */ struct completion wait; /* compleation */ struct block_device *bdev; /* bdev */ @@ -4132,19 +4124,6 @@ void f2fs_leave_shrinker(struct f2fs_sb_info *sbi); * extent_cache.c */ bool sanity_check_extent_cache(struct inode *inode); -struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root, - struct rb_entry *cached_re, unsigned int ofs); -struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi, - struct rb_root_cached *root, - struct rb_node **parent, - unsigned int ofs, bool *leftmost); -struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root_cached *root, - struct rb_entry *cached_re, unsigned int ofs, - struct rb_entry **prev_entry, struct rb_entry **next_entry, - struct rb_node ***insert_p, struct rb_node **insert_parent, - bool force, bool *leftmost); -bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi, - struct rb_root_cached *root); void f2fs_init_extent_tree(struct inode *inode); void f2fs_drop_extent_tree(struct inode *inode); void f2fs_destroy_extent_node(struct inode *inode); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index e98a12e8dca1..5f65c8110453 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -933,9 +933,9 @@ static struct discard_cmd *__create_discard_cmd(struct = f2fs_sb_info *sbi, dc =3D f2fs_kmem_cache_alloc(discard_cmd_slab, GFP_NOFS, true, NULL); INIT_LIST_HEAD(&dc->list); dc->bdev =3D bdev; - dc->lstart =3D lstart; - dc->start =3D start; - dc->len =3D len; + dc->di.lstart =3D lstart; + dc->di.start =3D start; + dc->di.len =3D len; dc->ref =3D 0; dc->state =3D D_PREP; dc->queued =3D 0; @@ -950,20 +950,108 @@ static struct discard_cmd *__create_discard_cmd(stru= ct f2fs_sb_info *sbi, return dc; } =20 -static struct discard_cmd *__attach_discard_cmd(struct f2fs_sb_info *sbi, - struct block_device *bdev, block_t lstart, - block_t start, block_t len, - struct rb_node *parent, struct rb_node **p, - bool leftmost) +static bool f2fs_check_discard_tree(struct f2fs_sb_info *sbi) { +#ifdef CONFIG_F2FS_CHECK_FS struct discard_cmd_control *dcc =3D SM_I(sbi)->dcc_info; + struct rb_node *cur =3D rb_first_cached(&dcc->root), *next; + struct discard_cmd *cur_dc, *next_dc; + + while (cur) { + next =3D rb_next(cur); + if (!next) + return true; + + cur_dc =3D rb_entry(cur, struct discard_cmd, rb_node); + next_dc =3D rb_entry(next, struct discard_cmd, rb_node); + + if (cur_dc->di.lstart + cur_dc->di.len > next_dc->di.lstart) { + f2fs_info(sbi, "broken discard_rbtree, " + "cur(%u, %u) next(%u, %u)", + cur_dc->di.lstart, cur_dc->di.len, + next_dc->di.lstart, next_dc->di.len); + return false; + } + cur =3D next; + } +#endif + return true; +} + +static struct discard_cmd *__lookup_discard_cmd(struct f2fs_sb_info *sbi, + block_t blkaddr) +{ + struct discard_cmd_control *dcc =3D SM_I(sbi)->dcc_info; + struct rb_node *node =3D dcc->root.rb_root.rb_node; struct discard_cmd *dc; =20 - dc =3D __create_discard_cmd(sbi, bdev, lstart, start, len); + while (node) { + dc =3D rb_entry(node, struct discard_cmd, rb_node); =20 - rb_link_node(&dc->rb_node, parent, p); - rb_insert_color_cached(&dc->rb_node, &dcc->root, leftmost); + if (blkaddr < dc->di.lstart) + node =3D node->rb_left; + else if (blkaddr >=3D dc->di.lstart + dc->di.len) + node =3D node->rb_right; + else + return dc; + } + return NULL; +} + +static struct discard_cmd *__lookup_discard_cmd_ret(struct rb_root_cached = *root, + block_t blkaddr, + struct discard_cmd **prev_entry, + struct discard_cmd **next_entry, + struct rb_node ***insert_p, + struct rb_node **insert_parent) +{ + struct rb_node **pnode =3D &root->rb_root.rb_node; + struct rb_node *parent =3D NULL, *tmp_node; + struct discard_cmd *dc; =20 + *insert_p =3D NULL; + *insert_parent =3D NULL; + *prev_entry =3D NULL; + *next_entry =3D NULL; + + if (RB_EMPTY_ROOT(&root->rb_root)) + return NULL; + + while (*pnode) { + parent =3D *pnode; + dc =3D rb_entry(*pnode, struct discard_cmd, rb_node); + + if (blkaddr < dc->di.lstart) + pnode =3D &(*pnode)->rb_left; + else if (blkaddr >=3D dc->di.lstart + dc->di.len) + pnode =3D &(*pnode)->rb_right; + else + goto lookup_neighbors; + } + + *insert_p =3D pnode; + *insert_parent =3D parent; + + dc =3D rb_entry(parent, struct discard_cmd, rb_node); + tmp_node =3D parent; + if (parent && blkaddr > dc->di.lstart) + tmp_node =3D rb_next(parent); + *next_entry =3D rb_entry_safe(tmp_node, struct discard_cmd, rb_node); + + tmp_node =3D parent; + if (parent && blkaddr < dc->di.lstart) + tmp_node =3D rb_prev(parent); + *prev_entry =3D rb_entry_safe(tmp_node, struct discard_cmd, rb_node); + return NULL; + +lookup_neighbors: + /* lookup prev node for merging backward later */ + tmp_node =3D rb_prev(&dc->rb_node); + *prev_entry =3D rb_entry_safe(tmp_node, struct discard_cmd, rb_node); + + /* lookup next node for merging frontward later */ + tmp_node =3D rb_next(&dc->rb_node); + *next_entry =3D rb_entry_safe(tmp_node, struct discard_cmd, rb_node); return dc; } =20 @@ -975,7 +1063,7 @@ static void __detach_discard_cmd(struct discard_cmd_co= ntrol *dcc, =20 list_del(&dc->list); rb_erase_cached(&dc->rb_node, &dcc->root); - dcc->undiscard_blks -=3D dc->len; + dcc->undiscard_blks -=3D dc->di.len; =20 kmem_cache_free(discard_cmd_slab, dc); =20 @@ -988,7 +1076,7 @@ static void __remove_discard_cmd(struct f2fs_sb_info *= sbi, struct discard_cmd_control *dcc =3D SM_I(sbi)->dcc_info; unsigned long flags; =20 - trace_f2fs_remove_discard(dc->bdev, dc->start, dc->len); + trace_f2fs_remove_discard(dc->bdev, dc->di.start, dc->di.len); =20 spin_lock_irqsave(&dc->lock, flags); if (dc->bio_ref) { @@ -1006,7 +1094,7 @@ static void __remove_discard_cmd(struct f2fs_sb_info = *sbi, printk_ratelimited( "%sF2FS-fs (%s): Issue discard(%u, %u, %u) failed, ret: %d", KERN_INFO, sbi->sb->s_id, - dc->lstart, dc->start, dc->len, dc->error); + dc->di.lstart, dc->di.start, dc->di.len, dc->error); __detach_discard_cmd(dcc, dc); } =20 @@ -1122,14 +1210,14 @@ static int __submit_discard_cmd(struct f2fs_sb_info= *sbi, if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) return 0; =20 - trace_f2fs_issue_discard(bdev, dc->start, dc->len); + trace_f2fs_issue_discard(bdev, dc->di.start, dc->di.len); =20 - lstart =3D dc->lstart; - start =3D dc->start; - len =3D dc->len; + lstart =3D dc->di.lstart; + start =3D dc->di.start; + len =3D dc->di.len; total_len =3D len; =20 - dc->len =3D 0; + dc->di.len =3D 0; =20 while (total_len && *issued < dpolicy->max_requests && !err) { struct bio *bio =3D NULL; @@ -1145,7 +1233,7 @@ static int __submit_discard_cmd(struct f2fs_sb_info *= sbi, if (*issued =3D=3D dpolicy->max_requests) last =3D true; =20 - dc->len +=3D len; + dc->di.len +=3D len; =20 if (time_to_inject(sbi, FAULT_DISCARD)) { err =3D -EIO; @@ -1207,34 +1295,41 @@ static int __submit_discard_cmd(struct f2fs_sb_info= *sbi, return err; } =20 -static void __insert_discard_tree(struct f2fs_sb_info *sbi, +static void __insert_discard_cmd(struct f2fs_sb_info *sbi, struct block_device *bdev, block_t lstart, - block_t start, block_t len, - struct rb_node **insert_p, - struct rb_node *insert_parent) + block_t start, block_t len) { struct discard_cmd_control *dcc =3D SM_I(sbi)->dcc_info; - struct rb_node **p; + struct rb_node **p =3D &dcc->root.rb_root.rb_node; struct rb_node *parent =3D NULL; + struct discard_cmd *dc; bool leftmost =3D true; =20 - if (insert_p && insert_parent) { - parent =3D insert_parent; - p =3D insert_p; - goto do_insert; + /* look up rb tree to find parent node */ + while (*p) { + parent =3D *p; + dc =3D rb_entry(parent, struct discard_cmd, rb_node); + + if (lstart < dc->di.lstart) { + p =3D &(*p)->rb_left; + } else if (lstart >=3D dc->di.lstart + dc->di.len) { + p =3D &(*p)->rb_right; + leftmost =3D false; + } else { + f2fs_bug_on(sbi, 1); + } } =20 - p =3D f2fs_lookup_rb_tree_for_insert(sbi, &dcc->root, &parent, - lstart, &leftmost); -do_insert: - __attach_discard_cmd(sbi, bdev, lstart, start, len, parent, - p, leftmost); + dc =3D __create_discard_cmd(sbi, bdev, lstart, start, len); + + rb_link_node(&dc->rb_node, parent, p); + rb_insert_color_cached(&dc->rb_node, &dcc->root, leftmost); } =20 static void __relocate_discard_cmd(struct discard_cmd_control *dcc, struct discard_cmd *dc) { - list_move_tail(&dc->list, &dcc->pend_list[plist_idx(dc->len)]); + list_move_tail(&dc->list, &dcc->pend_list[plist_idx(dc->di.len)]); } =20 static void __punch_discard_cmd(struct f2fs_sb_info *sbi, @@ -1244,7 +1339,7 @@ static void __punch_discard_cmd(struct f2fs_sb_info *= sbi, struct discard_info di =3D dc->di; bool modified =3D false; =20 - if (dc->state =3D=3D D_DONE || dc->len =3D=3D 1) { + if (dc->state =3D=3D D_DONE || dc->di.len =3D=3D 1) { __remove_discard_cmd(sbi, dc); return; } @@ -1252,23 +1347,22 @@ static void __punch_discard_cmd(struct f2fs_sb_info= *sbi, dcc->undiscard_blks -=3D di.len; =20 if (blkaddr > di.lstart) { - dc->len =3D blkaddr - dc->lstart; - dcc->undiscard_blks +=3D dc->len; + dc->di.len =3D blkaddr - dc->di.lstart; + dcc->undiscard_blks +=3D dc->di.len; __relocate_discard_cmd(dcc, dc); modified =3D true; } =20 if (blkaddr < di.lstart + di.len - 1) { if (modified) { - __insert_discard_tree(sbi, dc->bdev, blkaddr + 1, + __insert_discard_cmd(sbi, dc->bdev, blkaddr + 1, di.start + blkaddr + 1 - di.lstart, - di.lstart + di.len - 1 - blkaddr, - NULL, NULL); + di.lstart + di.len - 1 - blkaddr); } else { - dc->lstart++; - dc->len--; - dc->start++; - dcc->undiscard_blks +=3D dc->len; + dc->di.lstart++; + dc->di.len--; + dc->di.start++; + dcc->undiscard_blks +=3D dc->di.len; __relocate_discard_cmd(dcc, dc); } } @@ -1287,37 +1381,33 @@ static void __update_discard_tree_range(struct f2fs= _sb_info *sbi, SECTOR_TO_BLOCK(bdev_max_discard_sectors(bdev)); block_t end =3D lstart + len; =20 - dc =3D (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root, - NULL, lstart, - (struct rb_entry **)&prev_dc, - (struct rb_entry **)&next_dc, - &insert_p, &insert_parent, true, NULL); + dc =3D __lookup_discard_cmd_ret(&dcc->root, lstart, + &prev_dc, &next_dc, &insert_p, &insert_parent); if (dc) prev_dc =3D dc; =20 if (!prev_dc) { di.lstart =3D lstart; - di.len =3D next_dc ? next_dc->lstart - lstart : len; + di.len =3D next_dc ? next_dc->di.lstart - lstart : len; di.len =3D min(di.len, len); di.start =3D start; } =20 while (1) { struct rb_node *node; - bool merged =3D false; struct discard_cmd *tdc =3D NULL; =20 if (prev_dc) { - di.lstart =3D prev_dc->lstart + prev_dc->len; + di.lstart =3D prev_dc->di.lstart + prev_dc->di.len; if (di.lstart < lstart) di.lstart =3D lstart; if (di.lstart >=3D end) break; =20 - if (!next_dc || next_dc->lstart > end) + if (!next_dc || next_dc->di.lstart > end) di.len =3D end - di.lstart; else - di.len =3D next_dc->lstart - di.lstart; + di.len =3D next_dc->di.lstart - di.lstart; di.start =3D start + di.lstart - lstart; } =20 @@ -1333,7 +1423,7 @@ static void __update_discard_tree_range(struct f2fs_s= b_info *sbi, __relocate_discard_cmd(dcc, prev_dc); di =3D prev_dc->di; tdc =3D prev_dc; - merged =3D true; + goto next; } =20 if (next_dc && next_dc->state =3D=3D D_PREP && @@ -1347,13 +1437,10 @@ static void __update_discard_tree_range(struct f2fs= _sb_info *sbi, __relocate_discard_cmd(dcc, next_dc); if (tdc) __remove_discard_cmd(sbi, tdc); - merged =3D true; + goto next; } =20 - if (!merged) { - __insert_discard_tree(sbi, bdev, di.lstart, di.start, - di.len, NULL, NULL); - } + __insert_discard_cmd(sbi, bdev, di.lstart, di.start, di.len); next: prev_dc =3D next_dc; if (!prev_dc) @@ -1392,15 +1479,11 @@ static void __issue_discard_cmd_orderly(struct f2fs= _sb_info *sbi, struct rb_node **insert_p =3D NULL, *insert_parent =3D NULL; struct discard_cmd *dc; struct blk_plug plug; - unsigned int pos =3D dcc->next_pos; bool io_interrupted =3D false; =20 mutex_lock(&dcc->cmd_lock); - dc =3D (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root, - NULL, pos, - (struct rb_entry **)&prev_dc, - (struct rb_entry **)&next_dc, - &insert_p, &insert_parent, true, NULL); + dc =3D __lookup_discard_cmd_ret(&dcc->root, dcc->next_pos, + &prev_dc, &next_dc, &insert_p, &insert_parent); if (!dc) dc =3D next_dc; =20 @@ -1418,7 +1501,7 @@ static void __issue_discard_cmd_orderly(struct f2fs_s= b_info *sbi, break; } =20 - dcc->next_pos =3D dc->lstart + dc->len; + dcc->next_pos =3D dc->di.lstart + dc->di.len; err =3D __submit_discard_cmd(sbi, dpolicy, dc, issued); =20 if (*issued >=3D dpolicy->max_requests) @@ -1477,8 +1560,7 @@ static int __issue_discard_cmd(struct f2fs_sb_info *s= bi, if (list_empty(pend_list)) goto next; if (unlikely(dcc->rbtree_check)) - f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi, - &dcc->root)); + f2fs_bug_on(sbi, !f2fs_check_discard_tree(sbi)); blk_start_plug(&plug); list_for_each_entry_safe(dc, tmp, pend_list, list) { f2fs_bug_on(sbi, dc->state !=3D D_PREP); @@ -1556,7 +1638,7 @@ static unsigned int __wait_one_discard_bio(struct f2f= s_sb_info *sbi, dc->ref--; if (!dc->ref) { if (!dc->error) - len =3D dc->len; + len =3D dc->di.len; __remove_discard_cmd(sbi, dc); } mutex_unlock(&dcc->cmd_lock); @@ -1579,14 +1661,15 @@ static unsigned int __wait_discard_cmd_range(struct= f2fs_sb_info *sbi, =20 mutex_lock(&dcc->cmd_lock); list_for_each_entry_safe(iter, tmp, wait_list, list) { - if (iter->lstart + iter->len <=3D start || end <=3D iter->lstart) + if (iter->di.lstart + iter->di.len <=3D start || + end <=3D iter->di.lstart) continue; - if (iter->len < dpolicy->granularity) + if (iter->di.len < dpolicy->granularity) continue; if (iter->state =3D=3D D_DONE && !iter->ref) { wait_for_completion_io(&iter->wait); if (!iter->error) - trimmed +=3D iter->len; + trimmed +=3D iter->di.len; __remove_discard_cmd(sbi, iter); } else { iter->ref++; @@ -1630,8 +1713,7 @@ static void f2fs_wait_discard_bio(struct f2fs_sb_info= *sbi, block_t blkaddr) bool need_wait =3D false; =20 mutex_lock(&dcc->cmd_lock); - dc =3D (struct discard_cmd *)f2fs_lookup_rb_tree(&dcc->root, - NULL, blkaddr); + dc =3D __lookup_discard_cmd(sbi, blkaddr); if (dc) { if (dc->state =3D=3D D_PREP) { __punch_discard_cmd(sbi, dc, blkaddr); @@ -2964,24 +3046,20 @@ static unsigned int __issue_discard_cmd_range(struc= t f2fs_sb_info *sbi, =20 mutex_lock(&dcc->cmd_lock); if (unlikely(dcc->rbtree_check)) - f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi, - &dcc->root)); - - dc =3D (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root, - NULL, start, - (struct rb_entry **)&prev_dc, - (struct rb_entry **)&next_dc, - &insert_p, &insert_parent, true, NULL); + f2fs_bug_on(sbi, !f2fs_check_discard_tree(sbi)); + + dc =3D __lookup_discard_cmd_ret(&dcc->root, start, + &prev_dc, &next_dc, &insert_p, &insert_parent); if (!dc) dc =3D next_dc; =20 blk_start_plug(&plug); =20 - while (dc && dc->lstart <=3D end) { + while (dc && dc->di.lstart <=3D end) { struct rb_node *node; int err =3D 0; =20 - if (dc->len < dpolicy->granularity) + if (dc->di.len < dpolicy->granularity) goto skip; =20 if (dc->state !=3D D_PREP) { @@ -2992,7 +3070,7 @@ static unsigned int __issue_discard_cmd_range(struct = f2fs_sb_info *sbi, err =3D __submit_discard_cmd(sbi, dpolicy, dc, &issued); =20 if (issued >=3D dpolicy->max_requests) { - start =3D dc->lstart + dc->len; + start =3D dc->di.lstart + dc->di.len; =20 if (err) __remove_discard_cmd(sbi, dc); --=20 2.40.0.rc1.284.g88254d51c5-goog