This patch add a rb tree for discard command.

Signed-off-by: Yunlei He <[email protected]>
---
 fs/f2fs/f2fs.h    |  2 ++
 fs/f2fs/segment.c | 35 ++++++++++++++++++++++++++++++-----
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 5a2b8cd..5bc80dc 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -197,6 +197,7 @@ enum {
 
 struct discard_cmd {
        struct list_head list;          /* command list */
+       struct rb_node rb_node;         /* rb node located in rb-tree */
        struct completion wait;         /* compleation */
        struct block_device *bdev;      /* bdev */
        block_t lstart;                 /* logical start address */
@@ -210,6 +211,7 @@ struct discard_cmd_control {
        struct task_struct *f2fs_issue_discard; /* discard thread */
        struct list_head discard_entry_list;    /* 4KB discard entry list */
        int nr_discards;                        /* # of discards in the list */
+       struct rb_root root;            /* root of extent info rb-tree */
        struct list_head discard_pend_list;     /* store pending entries */
        struct list_head discard_wait_list;     /* store on-flushing entries */
        wait_queue_head_t discard_wait_queue;   /* waiting queue for wake-up */
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index eedbed6..d96f11a 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -678,7 +678,9 @@ static void __add_discard_cmd(struct f2fs_sb_info *sbi,
 {
        struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
        struct list_head *pend_list = &(dcc->discard_pend_list);
-       struct discard_cmd *dc;
+       struct discard_cmd *dc, *tmp;
+       struct rb_node **p = &dcc->root.rb_node;
+       struct rb_node *parent = NULL;
 
        dc = f2fs_kmem_cache_alloc(discard_cmd_slab, GFP_NOFS);
        INIT_LIST_HEAD(&dc->list);
@@ -691,6 +693,20 @@ static void __add_discard_cmd(struct f2fs_sb_info *sbi,
        init_completion(&dc->wait);
 
        mutex_lock(&dcc->cmd_lock);
+       while (*p) {
+               parent = *p;
+               tmp = rb_entry_safe(parent, struct discard_cmd, rb_node);
+
+               if (dc->lstart + dc->len <= tmp->lstart)
+                       p = &(*p)->rb_left;
+               else if (dc->lstart >= tmp->lstart + tmp->len)
+                       p = &(*p)->rb_right;
+               else
+                       f2fs_bug_on(sbi, 1);
+       }
+
+       rb_link_node(&dc->rb_node, parent, p);
+       rb_insert_color(&dc->rb_node, &dcc->root);
        list_add_tail(&dc->list, pend_list);
        mutex_unlock(&dcc->cmd_lock);
 
@@ -709,6 +725,7 @@ static void __remove_discard_cmd(struct f2fs_sb_info *sbi, 
struct discard_cmd *d
                f2fs_msg(sbi->sb, KERN_INFO,
                                "Issue discard failed, ret: %d", dc->error);
        list_del(&dc->list);
+       rb_erase(&dc->rb_node, &(SM_I(sbi)->dcc_info->root));
        kmem_cache_free(discard_cmd_slab, dc);
        atomic_dec(&SM_I(sbi)->dcc_info->discard_cmd_cnt);
 }
@@ -794,16 +811,23 @@ static void __punch_discard_cmd(struct f2fs_sb_info *sbi,
 void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)
 {
        struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
-       struct list_head *pend_list = &(dcc->discard_pend_list);
-       struct discard_cmd *dc, *tmp;
+       struct discard_cmd *dc;
+       struct rb_node *node = dcc->root.rb_node;
 
        mutex_lock(&dcc->cmd_lock);
 
-       list_for_each_entry_safe(dc, tmp, pend_list, list) {
-               if (dc->lstart <= blkaddr && blkaddr < dc->lstart + dc->len) {
+       while (node) {
+               dc = rb_entry_safe(node, struct discard_cmd, rb_node);
+
+               if (blkaddr < dc->lstart) {
+                       node = node->rb_left;
+               } else if (blkaddr >= dc->lstart + dc->len) {
+                       node = node->rb_right;
+               } else {
                        if (dc->state == D_SUBMIT)
                                wait_for_completion_io(&dc->wait);
                        __punch_discard_cmd(sbi, dc, blkaddr);
+                       break;
                }
        }
 
@@ -1165,6 +1189,7 @@ static int create_discard_cmd_control(struct f2fs_sb_info 
*sbi)
        INIT_LIST_HEAD(&dcc->discard_entry_list);
        INIT_LIST_HEAD(&dcc->discard_pend_list);
        INIT_LIST_HEAD(&dcc->discard_wait_list);
+       dcc->root = RB_ROOT;
        mutex_init(&dcc->cmd_lock);
        atomic_set(&dcc->issued_discard, 0);
        atomic_set(&dcc->issing_discard, 0);
-- 
2.10.1


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to