[PATCH] md/raid5: add exact old and new llbitmap mapping helpers

Yu Kuai posted 1 patch 1 month, 4 weeks ago
There is a newer version of this series
drivers/md/raid5.c | 70 ++++++++++++++++++++++++++++++++++------------
1 file changed, 52 insertions(+), 18 deletions(-)
[PATCH] md/raid5: add exact old and new llbitmap mapping helpers
Posted by Yu Kuai 1 month, 4 weeks ago
Teach RAID5 to export exact old and new llbitmap mappings and the
corresponding sync and array sizes for reshape-aware bitmap users.

Signed-off-by: Yu Kuai <yukuai@fnnas.com>
---
 drivers/md/raid5.c | 70 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 52 insertions(+), 18 deletions(-)

diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 1f8360d4cdb7..0c58c175bad9 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5898,25 +5898,43 @@ static enum reshape_loc get_reshape_loc(struct mddev *mddev,
 	return LOC_BEHIND_RESHAPE;
 }
 
-static void raid5_bitmap_sector(struct mddev *mddev, sector_t *offset,
-				unsigned long *sectors)
+static void raid5_bitmap_sector_map(struct mddev *mddev, sector_t *offset,
+				    unsigned long *sectors,
+				    bool previous)
 {
 	struct r5conf *conf = mddev->private;
 	sector_t start = *offset;
 	sector_t end = start + *sectors;
-	sector_t prev_start = start;
-	sector_t prev_end = end;
 	int sectors_per_chunk;
-	enum reshape_loc loc;
 	int dd_idx;
 
-	sectors_per_chunk = conf->chunk_sectors *
-		(conf->raid_disks - conf->max_degraded);
+	if (previous)
+		sectors_per_chunk = conf->prev_chunk_sectors *
+			(conf->previous_raid_disks - conf->max_degraded);
+	else
+		sectors_per_chunk = conf->chunk_sectors *
+			(conf->raid_disks - conf->max_degraded);
 	start = round_down(start, sectors_per_chunk);
 	end = round_up(end, sectors_per_chunk);
 
-	start = raid5_compute_sector(conf, start, 0, &dd_idx, NULL);
-	end = raid5_compute_sector(conf, end, 0, &dd_idx, NULL);
+	start = raid5_compute_sector(conf, start, previous, &dd_idx, NULL);
+	end = raid5_compute_sector(conf, end, previous, &dd_idx, NULL);
+	*offset = start;
+	*sectors = end - start;
+}
+
+static void raid5_bitmap_sector(struct mddev *mddev, sector_t *offset,
+				unsigned long *sectors)
+{
+	struct r5conf *conf = mddev->private;
+	sector_t start = *offset;
+	sector_t end = start + *sectors;
+	sector_t prev_start = start;
+	unsigned long prev_sectors = end - start;
+	enum reshape_loc loc;
+
+	raid5_bitmap_sector_map(mddev, &start, sectors, false);
+	end = start + *sectors;
 
 	/*
 	 * For LOC_INSIDE_RESHAPE, this IO will wait for reshape to make
@@ -5925,17 +5943,10 @@ static void raid5_bitmap_sector(struct mddev *mddev, sector_t *offset,
 	loc = get_reshape_loc(mddev, conf, prev_start);
 	if (likely(loc != LOC_AHEAD_OF_RESHAPE)) {
 		*offset = start;
-		*sectors = end - start;
 		return;
 	}
 
-	sectors_per_chunk = conf->prev_chunk_sectors *
-		(conf->previous_raid_disks - conf->max_degraded);
-	prev_start = round_down(prev_start, sectors_per_chunk);
-	prev_end = round_down(prev_end, sectors_per_chunk);
-
-	prev_start = raid5_compute_sector(conf, prev_start, 1, &dd_idx, NULL);
-	prev_end = raid5_compute_sector(conf, prev_end, 1, &dd_idx, NULL);
+	raid5_bitmap_sector_map(mddev, &prev_start, &prev_sectors, true);
 
 	/*
 	 * for LOC_AHEAD_OF_RESHAPE, reshape can make progress before this IO
@@ -5943,7 +5954,7 @@ static void raid5_bitmap_sector(struct mddev *mddev, sector_t *offset,
 	 * we set bits for both.
 	 */
 	*offset = min(start, prev_start);
-	*sectors = max(end, prev_end) - *offset;
+	*sectors = max(end, prev_start + prev_sectors) - *offset;
 }
 
 static enum stripe_result make_stripe_request(struct mddev *mddev,
@@ -9002,6 +9013,20 @@ static void raid5_prepare_suspend(struct mddev *mddev)
 	wake_up(&conf->wait_for_reshape);
 }
 
+static sector_t raid5_bitmap_sync_size(struct mddev *mddev, bool previous)
+{
+	return mddev->dev_sectors;
+}
+
+static sector_t raid5_bitmap_array_sectors(struct mddev *mddev, bool previous)
+{
+	struct r5conf *conf = mddev->private;
+
+	if (previous)
+		return raid5_size(mddev, 0, 0);
+	return raid5_size(mddev, mddev->dev_sectors, conf->raid_disks);
+}
+
 static struct md_personality raid6_personality =
 {
 	.head = {
@@ -9031,6 +9056,9 @@ static struct md_personality raid6_personality =
 	.change_consistency_policy = raid5_change_consistency_policy,
 	.prepare_suspend = raid5_prepare_suspend,
 	.bitmap_sector	= raid5_bitmap_sector,
+	.bitmap_sector_map = raid5_bitmap_sector_map,
+	.bitmap_sync_size = raid5_bitmap_sync_size,
+	.bitmap_array_sectors = raid5_bitmap_array_sectors,
 };
 static struct md_personality raid5_personality =
 {
@@ -9061,6 +9089,9 @@ static struct md_personality raid5_personality =
 	.change_consistency_policy = raid5_change_consistency_policy,
 	.prepare_suspend = raid5_prepare_suspend,
 	.bitmap_sector	= raid5_bitmap_sector,
+	.bitmap_sector_map = raid5_bitmap_sector_map,
+	.bitmap_sync_size = raid5_bitmap_sync_size,
+	.bitmap_array_sectors = raid5_bitmap_array_sectors,
 };
 
 static struct md_personality raid4_personality =
@@ -9092,6 +9123,9 @@ static struct md_personality raid4_personality =
 	.change_consistency_policy = raid5_change_consistency_policy,
 	.prepare_suspend = raid5_prepare_suspend,
 	.bitmap_sector	= raid5_bitmap_sector,
+	.bitmap_sector_map = raid5_bitmap_sector_map,
+	.bitmap_sync_size = raid5_bitmap_sync_size,
+	.bitmap_array_sectors = raid5_bitmap_array_sectors,
 };
 
 static int __init raid5_init(void)
-- 
2.51.0
Re: [PATCH] md/raid5: add exact old and new llbitmap mapping helpers
Posted by kernel test robot 1 month, 2 weeks ago
Hi Yu,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v7.1-rc1 next-20260430]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Yu-Kuai/md-raid5-add-exact-old-and-new-llbitmap-mapping-helpers/20260421-233709
base:   linus/master
patch link:    https://lore.kernel.org/r/20260419030942.824195-17-yukuai%40fnnas.com
patch subject: [PATCH] md/raid5: add exact old and new llbitmap mapping helpers
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20260502/202605020242.1lRKHrkP-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260502/202605020242.1lRKHrkP-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605020242.1lRKHrkP-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/md/raid5.c:9065:3: error: field designator 'bitmap_sector_map' does not refer to any field in type 'struct md_personality'; did you mean 'bitmap_sector'?
    9065 |         .bitmap_sector_map = raid5_bitmap_sector_map,
         |          ^~~~~~~~~~~~~~~~~
         |          bitmap_sector
   drivers/md/md.h:797:9: note: 'bitmap_sector' declared here
     797 |         void (*bitmap_sector)(struct mddev *mddev, sector_t *offset,
         |                ^
>> drivers/md/raid5.c:9065:23: error: incompatible function pointer types initializing 'void (*)(struct mddev *, sector_t *, unsigned long *)' (aka 'void (*)(struct mddev *, unsigned long long *, unsigned long *)') with an expression of type 'void (struct mddev *, sector_t *, unsigned long *, bool)' (aka 'void (struct mddev *, unsigned long long *, unsigned long *, _Bool)') [-Wincompatible-function-pointer-types]
    9065 |         .bitmap_sector_map = raid5_bitmap_sector_map,
         |                              ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9065:23: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides]
    9065 |         .bitmap_sector_map = raid5_bitmap_sector_map,
         |                              ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9064:19: note: previous initialization is here
    9064 |         .bitmap_sector  = raid5_bitmap_sector,
         |                           ^~~~~~~~~~~~~~~~~~~
>> drivers/md/raid5.c:9066:3: error: field designator 'bitmap_sync_size' does not refer to any field in type 'struct md_personality'
    9066 |         .bitmap_sync_size = raid5_bitmap_sync_size,
         |         ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/md/raid5.c:9067:3: error: field designator 'bitmap_array_sectors' does not refer to any field in type 'struct md_personality'
    9067 |         .bitmap_array_sectors = raid5_bitmap_array_sectors,
         |         ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9098:3: error: field designator 'bitmap_sector_map' does not refer to any field in type 'struct md_personality'; did you mean 'bitmap_sector'?
    9098 |         .bitmap_sector_map = raid5_bitmap_sector_map,
         |          ^~~~~~~~~~~~~~~~~
         |          bitmap_sector
   drivers/md/md.h:797:9: note: 'bitmap_sector' declared here
     797 |         void (*bitmap_sector)(struct mddev *mddev, sector_t *offset,
         |                ^
   drivers/md/raid5.c:9098:23: error: incompatible function pointer types initializing 'void (*)(struct mddev *, sector_t *, unsigned long *)' (aka 'void (*)(struct mddev *, unsigned long long *, unsigned long *)') with an expression of type 'void (struct mddev *, sector_t *, unsigned long *, bool)' (aka 'void (struct mddev *, unsigned long long *, unsigned long *, _Bool)') [-Wincompatible-function-pointer-types]
    9098 |         .bitmap_sector_map = raid5_bitmap_sector_map,
         |                              ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9098:23: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides]
    9098 |         .bitmap_sector_map = raid5_bitmap_sector_map,
         |                              ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9097:19: note: previous initialization is here
    9097 |         .bitmap_sector  = raid5_bitmap_sector,
         |                           ^~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9099:3: error: field designator 'bitmap_sync_size' does not refer to any field in type 'struct md_personality'
    9099 |         .bitmap_sync_size = raid5_bitmap_sync_size,
         |         ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9100:3: error: field designator 'bitmap_array_sectors' does not refer to any field in type 'struct md_personality'
    9100 |         .bitmap_array_sectors = raid5_bitmap_array_sectors,
         |         ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9132:3: error: field designator 'bitmap_sector_map' does not refer to any field in type 'struct md_personality'; did you mean 'bitmap_sector'?
    9132 |         .bitmap_sector_map = raid5_bitmap_sector_map,
         |          ^~~~~~~~~~~~~~~~~
         |          bitmap_sector
   drivers/md/md.h:797:9: note: 'bitmap_sector' declared here
     797 |         void (*bitmap_sector)(struct mddev *mddev, sector_t *offset,
         |                ^
   drivers/md/raid5.c:9132:23: error: incompatible function pointer types initializing 'void (*)(struct mddev *, sector_t *, unsigned long *)' (aka 'void (*)(struct mddev *, unsigned long long *, unsigned long *)') with an expression of type 'void (struct mddev *, sector_t *, unsigned long *, bool)' (aka 'void (struct mddev *, unsigned long long *, unsigned long *, _Bool)') [-Wincompatible-function-pointer-types]
    9132 |         .bitmap_sector_map = raid5_bitmap_sector_map,
         |                              ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9132:23: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides]
    9132 |         .bitmap_sector_map = raid5_bitmap_sector_map,
         |                              ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9131:19: note: previous initialization is here
    9131 |         .bitmap_sector  = raid5_bitmap_sector,
         |                           ^~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9133:3: error: field designator 'bitmap_sync_size' does not refer to any field in type 'struct md_personality'
    9133 |         .bitmap_sync_size = raid5_bitmap_sync_size,
         |         ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/md/raid5.c:9134:3: error: field designator 'bitmap_array_sectors' does not refer to any field in type 'struct md_personality'
    9134 |         .bitmap_array_sectors = raid5_bitmap_array_sectors,
         |         ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   3 warnings and 12 errors generated.


vim +9065 drivers/md/raid5.c

  9035	
  9036	static struct md_personality raid6_personality =
  9037	{
  9038		.head = {
  9039			.type	= MD_PERSONALITY,
  9040			.id	= ID_RAID6,
  9041			.name	= "raid6",
  9042			.owner	= THIS_MODULE,
  9043		},
  9044	
  9045		.make_request	= raid5_make_request,
  9046		.run		= raid5_run,
  9047		.start		= raid5_start,
  9048		.free		= raid5_free,
  9049		.status		= raid5_status,
  9050		.error_handler	= raid5_error,
  9051		.hot_add_disk	= raid5_add_disk,
  9052		.hot_remove_disk= raid5_remove_disk,
  9053		.spare_active	= raid5_spare_active,
  9054		.sync_request	= raid5_sync_request,
  9055		.resize		= raid5_resize,
  9056		.size		= raid5_size,
  9057		.check_reshape	= raid6_check_reshape,
  9058		.start_reshape  = raid5_start_reshape,
  9059		.finish_reshape = raid5_finish_reshape,
  9060		.quiesce	= raid5_quiesce,
  9061		.takeover	= raid6_takeover,
  9062		.change_consistency_policy = raid5_change_consistency_policy,
  9063		.prepare_suspend = raid5_prepare_suspend,
  9064		.bitmap_sector	= raid5_bitmap_sector,
> 9065		.bitmap_sector_map = raid5_bitmap_sector_map,
> 9066		.bitmap_sync_size = raid5_bitmap_sync_size,
> 9067		.bitmap_array_sectors = raid5_bitmap_array_sectors,
  9068	};
  9069	static struct md_personality raid5_personality =
  9070	{
  9071		.head = {
  9072			.type	= MD_PERSONALITY,
  9073			.id	= ID_RAID5,
  9074			.name	= "raid5",
  9075			.owner	= THIS_MODULE,
  9076		},
  9077	
  9078		.make_request	= raid5_make_request,
  9079		.run		= raid5_run,
  9080		.start		= raid5_start,
  9081		.free		= raid5_free,
  9082		.status		= raid5_status,
  9083		.error_handler	= raid5_error,
  9084		.hot_add_disk	= raid5_add_disk,
  9085		.hot_remove_disk= raid5_remove_disk,
  9086		.spare_active	= raid5_spare_active,
  9087		.sync_request	= raid5_sync_request,
  9088		.resize		= raid5_resize,
  9089		.size		= raid5_size,
  9090		.check_reshape	= raid5_check_reshape,
  9091		.start_reshape  = raid5_start_reshape,
  9092		.finish_reshape = raid5_finish_reshape,
  9093		.quiesce	= raid5_quiesce,
  9094		.takeover	= raid5_takeover,
  9095		.change_consistency_policy = raid5_change_consistency_policy,
  9096		.prepare_suspend = raid5_prepare_suspend,
  9097		.bitmap_sector	= raid5_bitmap_sector,
  9098		.bitmap_sector_map = raid5_bitmap_sector_map,
  9099		.bitmap_sync_size = raid5_bitmap_sync_size,
  9100		.bitmap_array_sectors = raid5_bitmap_array_sectors,
  9101	};
  9102	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki