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

Prepare to store the bitmap id selected by user, also refactor
mddev_set_bitmap_ops a bit in case the value is invalid.

Signed-off-by: Yu Kuai <yuku...@huawei.com>
Reviewed-by: Hannes Reinecke <h...@suse.de>
---
 drivers/md/md.c | 37 +++++++++++++++++++++++++++++++------
 drivers/md/md.h |  2 ++
 2 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index b3af0172f4e2..48537577caf8 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -672,13 +672,33 @@ static void active_io_release(struct percpu_ref *ref)
 
 static void no_op(struct percpu_ref *r) {}
 
-static void mddev_set_bitmap_ops(struct mddev *mddev, enum md_submodule_id id)
+static bool mddev_set_bitmap_ops(struct mddev *mddev)
 {
+       struct md_submodule_head *head;
+
+       if (mddev->bitmap_id == ID_BITMAP_NONE)
+               return true;
+
        xa_lock(&md_submodule);
-       mddev->bitmap_ops = xa_load(&md_submodule, id);
+       head = xa_load(&md_submodule, mddev->bitmap_id);
+
+       if (!head) {
+               pr_warn("md: can't find bitmap id %d\n", mddev->bitmap_id);
+               goto err;
+       }
+
+       if (head->type != MD_BITMAP) {
+               pr_warn("md: invalid bitmap id %d\n", mddev->bitmap_id);
+               goto err;
+       }
+
+       mddev->bitmap_ops = (void *)head;
        xa_unlock(&md_submodule);
-       if (!mddev->bitmap_ops)
-               pr_warn_once("md: can't find bitmap id %d\n", id);
+       return true;
+
+err:
+       xa_unlock(&md_submodule);
+       return false;
 }
 
 static void mddev_clear_bitmap_ops(struct mddev *mddev)
@@ -688,8 +708,13 @@ static void mddev_clear_bitmap_ops(struct mddev *mddev)
 
 int mddev_init(struct mddev *mddev)
 {
-       /* TODO: support more versions */
-       mddev_set_bitmap_ops(mddev, ID_BITMAP);
+       if (!IS_ENABLED(CONFIG_MD_BITMAP)) {
+               mddev->bitmap_id = ID_BITMAP_NONE;
+       } else {
+               mddev->bitmap_id = ID_BITMAP;
+               if (!mddev_set_bitmap_ops(mddev))
+                       return -EINVAL;
+       }
 
        if (percpu_ref_init(&mddev->active_io, active_io_release,
                            PERCPU_REF_ALLOW_REINIT, GFP_KERNEL)) {
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 5c1da47fe73b..c7661e01212f 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -40,6 +40,7 @@ enum md_submodule_id {
        ID_CLUSTER,
        ID_BITMAP,
        ID_LLBITMAP,    /* TODO */
+       ID_BITMAP_NONE,
 };
 
 struct md_submodule_head {
@@ -565,6 +566,7 @@ struct mddev {
        struct percpu_ref               writes_pending;
        int                             sync_checkers;  /* # of threads 
checking writes_pending */
 
+       enum md_submodule_id            bitmap_id;
        void                            *bitmap; /* the bitmap for the device */
        struct bitmap_operations        *bitmap_ops;
        struct {
-- 
2.39.2


Reply via email to