Re: [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]>
On Mon 20 Apr 2026 at 13:21, Xiao Ni <[email protected]> wrote:

> On Thu, Apr 16, 2026 at 10:09 PM Su Yue <[email protected]> wrote:
>>
>> On Wed 15 Apr 2026 at 18:34, Xiao Ni <[email protected]> wrote:
>>
>> > On Tue, Apr 7, 2026 at 6:26 PM Su Yue <[email protected]> 
>> > wrote:
>> >>
>> >> 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.
>> >
>> >
>> > Hi Su Yue
>> >
>> > How can bitmap/location be present when bitmap is none? Could
>> > you
>> > provide the test commands that reproduce this problem?
>> >
>> Sorry for the misleading commit message. It can only be 
>> reproduced
>> patch 3 is appiled.
>> I adjusted the sequence of this patch for easy review because
>> md_bitmap_create,destroy
>> are touched in patch1,2 and 3. Also if put the patch after 3rd
>> patch,
>> it will break ability to bisect.
>>
>> # mdadm --create --assume-clean /dev/md0 -f --bitmap=internal
>>   --raid-devices=2 --level=mirror --metadata=1.2 /dev/vdc 
>>   /dev/vdd
>> # mdadm --grow /dev/md0 --bitmap=none
>> # mdadm --grow /dev/md0 --bitmap=internal # step 3
>> # mdadm --grow /dev/md0 --bitmap=none # step 4
>> [1]    2325 killed     mdadm --grow /dev/md0 --bitmap=none
>>
>> When step 3 is called,
>> md_bitmap_destroy() is called in update_array_info() to set 
>> NULL
>> mddev->bitmap_ops
>> then in step 4 kernel Oops is triggered.
>>
>>
>> I am willing to amend commit message or move it after patch 3 
>> if
>> you would like.
>
> Hi Su
>
> Thanks for the detail explanation. After reading patch3, I 
> totoally
> understand. The sequence is good to me. And yes, it's better to
> explain that this is needed after patch3.
>
Sure. I will do it in next version.

--
Su
>
> Best Regards
> Xiao
>>
>> --
>> Su
>>
>> >
>> > mdadm -CR /dev/md0 -l1 -n2 /dev/loop0 /dev/loop1 
>> > --bitmap=none
>> > (There
>> > is not bitmap/location, because bitmap directory is not 
>> > created)
>> > mdadm /dev/md0 --grow --bitmap=internal
>> > Grow.c md_set_array_info runs
>> >  451             array.state |= (1 << MD_SB_BITMAP_PRESENT);
>> >  452             rv = md_set_array_info(fd, &array);
>> > In kernel space, it runs
>> >  8125             rv = md_bitmap_create(mddev);
>> >  8126             if (!rv)
>> >  8127                 rv = mddev->bitmap_ops->load(mddev);
>> >
>> > Best Regards
>> > Xiao
>> >
>> >>
>> >> 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
>> >>
>>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.