[PATCH v2 1/5] md/md-bitmap: call md_bitmap_create,destroy in location_store
Su Yue <[email protected]>
| Newsgroups | gmane.linux.raid |
|---|---|
| Message-ID | <[email protected]> |
If bitmap/location is present, mdadm will call update_array_info()
while growing bitmap from none to internal via location_store().
md_bitmap_create() is needed to set mddev->bitmap_ops otherwise
mddev->bitmap_ops->get_stats() in update_array_info() will trigger
kernel NULL pointer dereference.
Fixes: fb8cc3b0d9db ("md/md-bitmap: delay registration of bitmap_ops until creating bitmap")
Signed-off-by: Su Yue <[email protected]>
---
drivers/md/md-bitmap.c | 11 ++++++++---
drivers/md/md.c | 4 ++--
drivers/md/md.h | 2 ++
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index 83378c033c72..2f24aae05552 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -2618,7 +2618,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
goto out;
}
- bitmap_destroy(mddev);
+ md_bitmap_destroy(mddev);
mddev->bitmap_info.offset = 0;
if (mddev->bitmap_info.file) {
struct file *f = mddev->bitmap_info.file;
@@ -2653,15 +2653,20 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
goto out;
}
+ /*
+ * lockless bitmap shoudle have set bitmap_id
+ * using bitmap_type, so always ID_BITMAP.
+ */
+ mddev->bitmap_id = ID_BITMAP;
mddev->bitmap_info.offset = offset;
- rv = bitmap_create(mddev);
+ rv = md_bitmap_create(mddev);
if (rv)
goto out;
rv = bitmap_load(mddev);
if (rv) {
mddev->bitmap_info.offset = 0;
- bitmap_destroy(mddev);
+ md_bitmap_destroy(mddev);
goto out;
}
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3ce6f9e9d38e..8b1ecc370ad6 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6447,7 +6447,7 @@ static void md_safemode_timeout(struct timer_list *t)
static int start_dirty_degraded;
-static int md_bitmap_create(struct mddev *mddev)
+int md_bitmap_create(struct mddev *mddev)
{
if (mddev->bitmap_id == ID_BITMAP_NONE)
return -EINVAL;
@@ -6458,7 +6458,7 @@ static int md_bitmap_create(struct mddev *mddev)
return mddev->bitmap_ops->create(mddev);
}
-static void md_bitmap_destroy(struct mddev *mddev)
+void md_bitmap_destroy(struct mddev *mddev)
{
if (!md_bitmap_registered(mddev))
return;
diff --git a/drivers/md/md.h b/drivers/md/md.h
index ac84289664cd..ed69244af00d 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -895,6 +895,8 @@ static inline void safe_put_page(struct page *p)
int register_md_submodule(struct md_submodule_head *msh);
void unregister_md_submodule(struct md_submodule_head *msh);
+int md_bitmap_create(struct mddev *mddev);
+void md_bitmap_destroy(struct mddev *mddev);
extern struct md_thread *md_register_thread(
void (*run)(struct md_thread *thread),
--
2.53.0