@@ -6454,15 +6454,124 @@ static void md_safemode_timeout(struct timer_list *t)
64546454
64556455static int start_dirty_degraded ;
64566456
6457+ /*
6458+ * Read bitmap superblock and return the bitmap_id based on disk version.
6459+ * This is used as fallback when default bitmap version and on-disk version
6460+ * doesn't match, and mdadm is not the latest version to set bitmap_type.
6461+ */
6462+ static enum md_submodule_id md_bitmap_get_id_from_sb (struct mddev * mddev )
6463+ {
6464+ struct md_rdev * rdev ;
6465+ struct page * sb_page ;
6466+ bitmap_super_t * sb ;
6467+ enum md_submodule_id id = ID_BITMAP_NONE ;
6468+ sector_t sector ;
6469+ u32 version ;
6470+
6471+ if (!mddev -> bitmap_info .offset )
6472+ return ID_BITMAP_NONE ;
6473+
6474+ sb_page = alloc_page (GFP_KERNEL );
6475+ if (!sb_page ) {
6476+ pr_warn ("md: %s: failed to allocate memory for bitmap\n" ,
6477+ mdname (mddev ));
6478+ return ID_BITMAP_NONE ;
6479+ }
6480+
6481+ sector = mddev -> bitmap_info .offset ;
6482+
6483+ rdev_for_each (rdev , mddev ) {
6484+ u32 iosize ;
6485+
6486+ if (!test_bit (In_sync , & rdev -> flags ) ||
6487+ test_bit (Faulty , & rdev -> flags ) ||
6488+ test_bit (Bitmap_sync , & rdev -> flags ))
6489+ continue ;
6490+
6491+ iosize = roundup (sizeof (bitmap_super_t ),
6492+ bdev_logical_block_size (rdev -> bdev ));
6493+ if (sync_page_io (rdev , sector , iosize , sb_page , REQ_OP_READ ,
6494+ true))
6495+ goto read_ok ;
6496+ }
6497+ pr_warn ("md: %s: failed to read bitmap from any device\n" ,
6498+ mdname (mddev ));
6499+ goto out ;
6500+
6501+ read_ok :
6502+ sb = kmap_local_page (sb_page );
6503+ if (sb -> magic != cpu_to_le32 (BITMAP_MAGIC )) {
6504+ pr_warn ("md: %s: invalid bitmap magic 0x%x\n" ,
6505+ mdname (mddev ), le32_to_cpu (sb -> magic ));
6506+ goto out_unmap ;
6507+ }
6508+
6509+ version = le32_to_cpu (sb -> version );
6510+ switch (version ) {
6511+ case BITMAP_MAJOR_LO :
6512+ case BITMAP_MAJOR_HI :
6513+ case BITMAP_MAJOR_CLUSTERED :
6514+ id = ID_BITMAP ;
6515+ break ;
6516+ case BITMAP_MAJOR_LOCKLESS :
6517+ id = ID_LLBITMAP ;
6518+ break ;
6519+ default :
6520+ pr_warn ("md: %s: unknown bitmap version %u\n" ,
6521+ mdname (mddev ), version );
6522+ break ;
6523+ }
6524+
6525+ out_unmap :
6526+ kunmap_local (sb );
6527+ out :
6528+ __free_page (sb_page );
6529+ return id ;
6530+ }
6531+
64576532static int md_bitmap_create (struct mddev * mddev )
64586533{
6534+ enum md_submodule_id orig_id = mddev -> bitmap_id ;
6535+ enum md_submodule_id sb_id ;
6536+ int err ;
6537+
64596538 if (mddev -> bitmap_id == ID_BITMAP_NONE )
64606539 return - EINVAL ;
64616540
64626541 if (!mddev_set_bitmap_ops (mddev ))
64636542 return - ENOENT ;
64646543
6465- return mddev -> bitmap_ops -> create (mddev );
6544+ err = mddev -> bitmap_ops -> create (mddev );
6545+ if (!err )
6546+ return 0 ;
6547+
6548+ /*
6549+ * Create failed, if default bitmap version and on-disk version
6550+ * doesn't match, and mdadm is not the latest version to set
6551+ * bitmap_type, set bitmap_ops based on the disk version.
6552+ */
6553+ mddev_clear_bitmap_ops (mddev );
6554+
6555+ sb_id = md_bitmap_get_id_from_sb (mddev );
6556+ if (sb_id == ID_BITMAP_NONE || sb_id == orig_id )
6557+ return err ;
6558+
6559+ pr_info ("md: %s: bitmap version mismatch, switching from %d to %d\n" ,
6560+ mdname (mddev ), orig_id , sb_id );
6561+
6562+ mddev -> bitmap_id = sb_id ;
6563+ if (!mddev_set_bitmap_ops (mddev )) {
6564+ mddev -> bitmap_id = orig_id ;
6565+ return - ENOENT ;
6566+ }
6567+
6568+ err = mddev -> bitmap_ops -> create (mddev );
6569+ if (err ) {
6570+ mddev_clear_bitmap_ops (mddev );
6571+ mddev -> bitmap_id = orig_id ;
6572+ }
6573+
6574+ return err ;
64666575}
64676576
64686577static void md_bitmap_destroy (struct mddev * mddev )
0 commit comments