From: Yu Kuai <yuku...@huawei.com>

A new config MD_LLBITMAP is added, user can now using llbitmap to
replace the old bitmap.

Signed-off-by: Yu Kuai <yuku...@huawei.com>
---
 drivers/md/Kconfig       | 12 ++++++
 drivers/md/Makefile      |  1 +
 drivers/md/md-bitmap.h   | 16 ++++++++
 drivers/md/md-llbitmap.c | 80 ++++++++++++++++++++++++++++++++++++++++
 drivers/md/md.c          |  6 +++
 5 files changed, 115 insertions(+)

diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index f913579e731c..655c4e381f7d 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -52,6 +52,18 @@ config MD_BITMAP
 
          If unsure, say Y.
 
+config MD_LLBITMAP
+       bool "MD RAID lockless bitmap support"
+       default n
+       depends on BLK_DEV_MD
+       help
+         If you say Y here, support for the lockless write intent bitmap will
+         be enabled.
+
+         Note, this is an experimental feature.
+
+         If unsure, say N.
+
 config MD_AUTODETECT
        bool "Autodetect RAID arrays during kernel boot"
        depends on BLK_DEV_MD=y
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index 811731840a5c..e70e4d3cbe29 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -39,6 +39,7 @@ linear-y       += md-linear.o
 obj-$(CONFIG_MD_LINEAR)                += linear.o
 obj-$(CONFIG_MD_RAID0)         += raid0.o
 obj-$(CONFIG_MD_BITMAP)                += md-bitmap.o
+obj-$(CONFIG_MD_LLBITMAP)      += md-llbitmap.o
 obj-$(CONFIG_MD_RAID1)         += raid1.o
 obj-$(CONFIG_MD_RAID10)                += raid10.o
 obj-$(CONFIG_MD_RAID456)       += raid456.o
diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
index 4e27f5f793b7..dd23b6fedb70 100644
--- a/drivers/md/md-bitmap.h
+++ b/drivers/md/md-bitmap.h
@@ -22,6 +22,9 @@ typedef __u16 bitmap_counter_t;
 enum bitmap_state {
        BITMAP_STALE       = 1,  /* the bitmap file is out of date or had -EIO 
*/
        BITMAP_WRITE_ERROR = 2, /* A write error has occurred */
+       BITMAP_FIRST_USE   = 3, /* llbitmap is just created */
+       BITMAP_CLEAN       = 4, /* llbitmap is created with assume_clean */
+       BITMAP_DAEMON_BUSY = 5, /* llbitmap daemon is not finished after 
daemon_sleep */
        BITMAP_HOSTENDIAN  =15,
 };
 
@@ -176,4 +179,17 @@ static inline void md_bitmap_exit(void)
 }
 #endif
 
+#ifdef CONFIG_MD_LLBITMAP
+int md_llbitmap_init(void);
+void md_llbitmap_exit(void);
+#else
+static inline int md_llbitmap_init(void)
+{
+       return 0;
+}
+static inline void md_llbitmap_exit(void)
+{
+}
+#endif
+
 #endif
diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
index 6993be132127..5bb60340c7e2 100644
--- a/drivers/md/md-llbitmap.c
+++ b/drivers/md/md-llbitmap.c
@@ -1383,3 +1383,83 @@ static struct attribute *md_llbitmap_attrs[] = {
        &llbitmap_daemon_sleep.attr,
        NULL
 };
+
+static struct attribute_group md_llbitmap_group = {
+       .name = "llbitmap",
+       .attrs = md_llbitmap_attrs,
+};
+
+static struct bitmap_operations llbitmap_ops = {
+       .head = {
+               .type   = MD_BITMAP,
+               .id     = ID_LLBITMAP,
+               .name   = "llbitmap",
+       },
+
+       .enabled                = llbitmap_enabled,
+       .create                 = llbitmap_create,
+       .resize                 = llbitmap_resize,
+       .load                   = llbitmap_load,
+       .destroy                = llbitmap_destroy,
+
+       .startwrite             = llbitmap_startwrite,
+       .endwrite               = llbitmap_endwrite,
+       .start_discard          = llbitmap_start_discard,
+       .end_discard            = llbitmap_end_discard,
+       .unplug                 = llbitmap_unplug,
+       .flush                  = llbitmap_flush,
+
+       .blocks_synced          = llbitmap_blocks_synced,
+       .skip_sync_blocks       = llbitmap_skip_sync_blocks,
+       .start_sync             = llbitmap_start_sync,
+       .end_sync               = llbitmap_end_sync,
+       .close_sync             = llbitmap_close_sync,
+
+       .update_sb              = llbitmap_update_sb,
+       .get_stats              = llbitmap_get_stats,
+       .dirty_bits             = llbitmap_dirty_bits,
+
+       /* not needed */
+       .write_all              = llbitmap_write_all,
+       .daemon_work            = llbitmap_daemon_work,
+       .cond_end_sync          = llbitmap_cond_end_sync,
+
+       /* not supported */
+       .start_behind_write     = llbitmap_start_behind_write,
+       .end_behind_write       = llbitmap_end_behind_write,
+       .wait_behind_writes     = llbitmap_wait_behind_writes,
+       .sync_with_cluster      = llbitmap_sync_with_cluster,
+       .get_from_slot          = llbitmap_get_from_slot,
+       .copy_from_slot         = llbitmap_copy_from_slot,
+       .set_pages              = llbitmap_set_pages,
+       .free                   = llbitmap_free,
+
+       .group                  = &md_llbitmap_group,
+};
+
+int md_llbitmap_init(void)
+{
+       md_llbitmap_io_wq = alloc_workqueue("md_llbitmap_io",
+                                        WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
+       if (!md_llbitmap_io_wq)
+               return -ENOMEM;
+
+       md_llbitmap_unplug_wq = alloc_workqueue("md_llbitmap_unplug",
+                                        WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
+       if (!md_llbitmap_unplug_wq) {
+               destroy_workqueue(md_llbitmap_io_wq);
+               md_llbitmap_io_wq = NULL;
+               return -ENOMEM;
+       }
+
+       return register_md_submodule(&llbitmap_ops.head);
+}
+
+void md_llbitmap_exit(void)
+{
+       destroy_workqueue(md_llbitmap_io_wq);
+       md_llbitmap_io_wq = NULL;
+       destroy_workqueue(md_llbitmap_unplug_wq);
+       md_llbitmap_unplug_wq = NULL;
+       unregister_md_submodule(&llbitmap_ops.head);
+}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index a5dd7a403ea5..6ac5747738dd 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -10191,6 +10191,10 @@ static int __init md_init(void)
        if (ret)
                return ret;
 
+       ret = md_llbitmap_init();
+       if (ret)
+               goto err_bitmap;
+
        ret = -ENOMEM;
        md_wq = alloc_workqueue("md", WQ_MEM_RECLAIM, 0);
        if (!md_wq)
@@ -10222,6 +10226,8 @@ static int __init md_init(void)
 err_misc_wq:
        destroy_workqueue(md_wq);
 err_wq:
+       md_llbitmap_exit();
+err_bitmap:
        md_bitmap_exit();
        return ret;
 }
-- 
2.39.2


Reply via email to