linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jakub Radtke <jakub.radtke@linux.intel.com>
To: jes@trained-monkey.org
Cc: linux-raid@vger.kernel.org
Subject: [PATCH 3/8] imsm: Write-intent bitmap support
Date: Thu, 24 Sep 2020 20:02:59 -0400	[thread overview]
Message-ID: <20200925000304.169728-4-jakub.radtke@linux.intel.com> (raw)
In-Reply-To: <20200925000304.169728-1-jakub.radtke@linux.intel.com>

From: Jakub Radtke <jakub.radtke@intel.com>

This patch enables the bitmap functionality with the IMSM metadata format.
The functionality covers "internal" bitmap.

There are the following limitation to "internal" metadata:
- creating the bitmap using --grow is not supported
- parameter --bitmap-chunk is ignored (default value 64MiB is used)

Change-Id: I22826f736bc013aa5516239e1e0c38d4eec32f62
Signed-off-by: Jakub Radtke <jakub.radtke@intel.com>
---
 super-intel.c | 619 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 617 insertions(+), 2 deletions(-)

diff --git a/super-intel.c b/super-intel.c
index 715febf7..edb1c60e 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -96,6 +96,23 @@
 						   * mutliple PPL area
 						   */
 
+/*
+ * Internal Write-intent bitmap is stored in the same area where PPL.
+ * Both features are mutually exclusive, so it is not an issue.
+ * The first 8KiB of the area are reserved and shall not be used.
+ */
+#define IMSM_BITMAP_AREA_RESERVED_SIZE 8192
+
+#define IMSM_BITMAP_HEADER_OFFSET (IMSM_BITMAP_AREA_RESERVED_SIZE)
+#define IMSM_BITMAP_HEADER_SIZE MAX_SECTOR_SIZE
+
+#define IMSM_BITMAP_START_OFFSET (IMSM_BITMAP_HEADER_OFFSET + IMSM_BITMAP_HEADER_SIZE)
+#define IMSM_BITMAP_AREA_SIZE (MULTIPLE_PPL_AREA_SIZE_IMSM - IMSM_BITMAP_START_OFFSET)
+#define IMSM_BITMAP_AND_HEADER_SIZE (IMSM_BITMAP_AREA_SIZE + IMSM_BITMAP_HEADER_SIZE)
+
+#define IMSM_DEFAULT_BITMAP_CHUNKSIZE (64 * 1024 * 1024)
+#define IMSM_DEFAULT_BITMAP_DAEMON_SLEEP 5
+
 /*
  * This macro let's us ensure that no-one accidentally
  * changes the size of a struct
@@ -229,6 +246,7 @@ struct imsm_dev {
 #define RWH_MULTIPLE_DISTRIBUTED 3
 #define RWH_MULTIPLE_PPLS_JOURNALING_DRIVE 4
 #define RWH_MULTIPLE_OFF 5
+#define RWH_BITMAP 6
 	__u8  rwh_policy; /* Raid Write Hole Policy */
 	__u8  jd_serial[MAX_RAID_SERIAL_LEN]; /* Journal Drive serial number */
 	__u8  filler1;
@@ -1682,6 +1700,8 @@ static void print_imsm_dev(struct intel_super *super,
 		printf("Multiple distributed PPLs\n");
 	else if (dev->rwh_policy == RWH_MULTIPLE_PPLS_JOURNALING_DRIVE)
 		printf("Multiple PPLs on journaling drive\n");
+	else if (dev->rwh_policy == RWH_BITMAP)
+		printf("Write-intent bitmap\n");
 	else
 		printf("<unknown:%d>\n", dev->rwh_policy);
 
@@ -3310,6 +3330,53 @@ static unsigned long long imsm_component_size_alignment_check(int level,
 	return component_size;
 }
 
+/*******************************************************************************
+ * Function:	get_bitmap_header_sector
+ * Description:	Returns the sector where the bitmap header is placed.
+ * Parameters:
+ *	st		: supertype information
+ *	dev_idx		: index of the device with bitmap
+ *
+ * Returns:
+ *	 The sector where the bitmap header is placed
+ ******************************************************************************/
+static unsigned long long get_bitmap_header_sector(struct intel_super *super,
+						   int dev_idx)
+{
+	struct imsm_dev *dev = get_imsm_dev(super, dev_idx);
+	struct imsm_map *map = get_imsm_map(dev, MAP_0);
+
+	if (!super->sector_size) {
+		dprintf("sector size is not set\n");
+		return 0;
+	}
+
+	return pba_of_lba0(map) + calc_component_size(map, dev) +
+	       (IMSM_BITMAP_HEADER_OFFSET / super->sector_size);
+}
+
+/*******************************************************************************
+ * Function:	get_bitmap_sector
+ * Description:	Returns the sector where the bitmap is placed.
+ * Parameters:
+ *	st		: supertype information
+ *	dev_idx		: index of the device with bitmap
+ *
+ * Returns:
+ *	 The sector where the bitmap is placed
+ ******************************************************************************/
+static unsigned long long get_bitmap_sector(struct intel_super *super,
+					    int dev_idx)
+{
+	if (!super->sector_size) {
+		dprintf("sector size is not set\n");
+		return 0;
+	}
+
+	return get_bitmap_header_sector(super, dev_idx) +
+	       (IMSM_BITMAP_HEADER_SIZE / super->sector_size);
+}
+
 static unsigned long long get_ppl_sector(struct intel_super *super, int dev_idx)
 {
 	struct imsm_dev *dev = get_imsm_dev(super, dev_idx);
@@ -3430,7 +3497,12 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
 	} else if (info->array.level <= 0) {
 		info->consistency_policy = CONSISTENCY_POLICY_NONE;
 	} else {
-		info->consistency_policy = CONSISTENCY_POLICY_RESYNC;
+		if (dev->rwh_policy == RWH_BITMAP) {
+			info->bitmap_offset = get_bitmap_sector(super, super->current_vol);
+			info->consistency_policy = CONSISTENCY_POLICY_BITMAP;
+		} else {
+			info->consistency_policy = CONSISTENCY_POLICY_RESYNC;
+		}
 	}
 
 	info->reshape_progress = 0;
@@ -6465,6 +6537,60 @@ static int write_init_ppl_imsm_all(struct supertype *st, struct mdinfo *info)
 	return ret;
 }
 
+/*******************************************************************************
+ * Function:	write_init_bitmap_imsm_vol
+ * Description:	Write a bitmap header and prepares the area for the bitmap.
+ * Parameters:
+ *	st	: supertype information
+ *	vol_idx	: the volume index to use
+ *
+ * Returns:
+ *	 0 : success
+ *	-1 : fail
+ ******************************************************************************/
+static int write_init_bitmap_imsm_vol(struct supertype *st, int vol_idx)
+{
+	struct intel_super *super = st->sb;
+	int prev_current_vol = super->current_vol;
+	struct dl *d;
+	int ret = 0;
+
+	super->current_vol = vol_idx;
+	for (d = super->disks; d; d = d->next) {
+		if (d->index < 0 || is_failed(&d->disk))
+			continue;
+		ret = st->ss->write_bitmap(st, d->fd, NoUpdate);
+		if (ret)
+			break;
+	}
+	super->current_vol = prev_current_vol;
+	return ret;
+}
+
+/*******************************************************************************
+ * Function:	write_init_bitmap_imsm_all
+ * Description:	Write a bitmap header and prepares the area for the bitmap.
+ *		Operation is executed for volumes with CONSISTENCY_POLICY_BITMAP.
+ * Parameters:
+ *	st	: supertype information
+ *	info	: info about the volume where the bitmap should be written
+ *	vol_idx	: the volume index to use
+ *
+ * Returns:
+ *	 0 : success
+ *	-1 : fail
+ ******************************************************************************/
+static int write_init_bitmap_imsm_all(struct supertype *st, struct mdinfo *info,
+				      int vol_idx)
+{
+	int ret = 0;
+
+	if (info && (info->consistency_policy == CONSISTENCY_POLICY_BITMAP))
+		ret = write_init_bitmap_imsm_vol(st, vol_idx);
+
+	return ret;
+}
+
 static int write_init_super_imsm(struct supertype *st)
 {
 	struct intel_super *super = st->sb;
@@ -6488,7 +6614,10 @@ static int write_init_super_imsm(struct supertype *st)
 			 */
 			rv = mgmt_disk(st);
 		} else {
+			/* adding the second volume to the array */
 			rv = write_init_ppl_imsm_all(st, &info);
+			if (!rv)
+				rv = write_init_bitmap_imsm_all(st, &info, current_vol);
 			if (!rv)
 				rv = create_array(st, current_vol);
 		}
@@ -6496,8 +6625,12 @@ static int write_init_super_imsm(struct supertype *st)
 		struct dl *d;
 		for (d = super->disks; d; d = d->next)
 			Kill(d->devname, NULL, 0, -1, 1);
-		if (current_vol >= 0)
+		if (current_vol >= 0) {
 			rv = write_init_ppl_imsm_all(st, &info);
+			if (!rv)
+				rv = write_init_bitmap_imsm_all(st, &info, current_vol);
+		}
+
 		if (!rv)
 			rv = write_super_imsm(st, 1);
 	}
@@ -12306,6 +12439,483 @@ abort:
 	return ret_val;
 }
 
+/*******************************************************************************
+ * Function:	calculate_bitmap_min_chunksize
+ * Description:	Calculates the minimal valid bitmap chunk size
+ * Parameters:
+ *	max_bits	: indicate how many bits can be used for the bitmap
+ *	data_area_size	: the size of the data area covered by the bitmap
+ *
+ * Returns:
+ *	 The bitmap chunk size
+ ******************************************************************************/
+static unsigned long long
+calculate_bitmap_min_chunksize(unsigned long long max_bits,
+			       unsigned long long data_area_size)
+{
+	unsigned long long min_chunk =
+		4096; /* sub-page chunks don't work yet.. */
+	unsigned long long bits = data_area_size / min_chunk + 1;
+
+	while (bits > max_bits) {
+		min_chunk *= 2;
+		bits = (bits + 1) / 2;
+	}
+	return min_chunk;
+}
+
+/*******************************************************************************
+ * Function:	calculate_bitmap_chunksize
+ * Description:	Calculates the bitmap chunk size for the given device
+ * Parameters:
+ *	st	: supertype information
+ *	dev	: device for the bitmap
+ *
+ * Returns:
+ *	 The bitmap chunk size
+ ******************************************************************************/
+static unsigned long long calculate_bitmap_chunksize(struct supertype *st,
+						     struct imsm_dev *dev)
+{
+	struct intel_super *super = st->sb;
+	unsigned long long min_chunksize;
+	unsigned long long result = IMSM_DEFAULT_BITMAP_CHUNKSIZE;
+	size_t dev_size = imsm_dev_size(dev);
+
+	min_chunksize = calculate_bitmap_min_chunksize(
+		IMSM_BITMAP_AREA_SIZE * super->sector_size, dev_size);
+
+	if (result < min_chunksize)
+		result = min_chunksize;
+
+	return result;
+}
+
+/*******************************************************************************
+ * Function:	init_bitmap_header
+ * Description:	Initialize the bitmap header structure
+ * Parameters:
+ *	st	: supertype information
+ *	bms	: bitmap header struct to initialize
+ *	dev	: device for the bitmap
+ *
+ * Returns:
+ *	 0 : success
+ *	-1 : fail
+ ******************************************************************************/
+static int init_bitmap_header(struct supertype *st, struct bitmap_super_s *bms,
+			      struct imsm_dev *dev)
+{
+	int vol_uuid[4];
+
+	if (!bms || !dev)
+		return -1;
+
+	bms->magic = __cpu_to_le32(BITMAP_MAGIC);
+	bms->version = __cpu_to_le32(BITMAP_MAJOR_HI);
+	bms->daemon_sleep = __cpu_to_le32(IMSM_DEFAULT_BITMAP_DAEMON_SLEEP);
+	bms->sync_size = __cpu_to_le64(IMSM_BITMAP_AREA_SIZE);
+	bms->write_behind = __cpu_to_le32(0);
+
+	uuid_from_super_imsm(st, vol_uuid);
+	memcpy(bms->uuid, vol_uuid, 16);
+
+	bms->chunksize = calculate_bitmap_chunksize(st, dev);
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Function:	validate_internal_bitmap_for_drive
+ * Description:	Verify if the bitmap header for a given drive.
+ * Parameters:
+ *	st	: supertype information
+ *	offset	: The offset from the beginning of the drive where to look for
+ *		  the bitmap header.
+ *	d	: the drive info
+ *
+ * Returns:
+ *	 0 : success
+ *	-1 : fail
+ ******************************************************************************/
+static int validate_internal_bitmap_for_drive(struct supertype *st,
+					      unsigned long long offset,
+					      struct dl *d)
+{
+	struct intel_super *super = st->sb;
+	int ret = -1;
+	int vol_uuid[4];
+	bitmap_super_t *bms;
+	int fd;
+
+	if (!d)
+		return -1;
+
+	void *read_buf;
+
+	if (posix_memalign(&read_buf, MAX_SECTOR_SIZE, IMSM_BITMAP_HEADER_SIZE))
+		return -1;
+
+	fd = d->fd;
+	if (fd < 0) {
+		fd = open(d->devname, O_RDONLY, 0);
+		if (fd < 0) {
+			dprintf("cannot open the device %s\n", d->devname);
+			goto abort;
+		}
+	}
+
+	if (lseek64(fd, offset * super->sector_size, SEEK_SET) < 0)
+		goto abort;
+	if (read(fd, read_buf, IMSM_BITMAP_HEADER_SIZE) !=
+	    IMSM_BITMAP_HEADER_SIZE)
+		goto abort;
+
+	uuid_from_super_imsm(st, vol_uuid);
+
+	bms = read_buf;
+	if ((bms->magic != __cpu_to_le32(BITMAP_MAGIC)) ||
+	    (bms->version != __cpu_to_le32(BITMAP_MAJOR_HI)) ||
+	    (!same_uuid((int *)bms->uuid, vol_uuid, st->ss->swapuuid))) {
+		dprintf("wrong bitmap header detected\n");
+		goto abort;
+	}
+
+	ret = 0;
+abort:
+	if ((d->fd < 0) && (fd >= 0))
+		close(fd);
+	if (read_buf)
+		free(read_buf);
+
+	return ret;
+}
+
+/*******************************************************************************
+ * Function:	validate_internal_bitmap_imsm
+ * Description:	Verify if the bitmap header is in place and with proper data.
+ * Parameters:
+ *	st	: supertype information
+ *
+ * Returns:
+ *	 0 : success or device w/o RWH_BITMAP
+ *	-1 : fail
+ ******************************************************************************/
+static int validate_internal_bitmap_imsm(struct supertype *st)
+{
+	struct intel_super *super = st->sb;
+	struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
+	unsigned long long offset;
+	struct dl *d;
+
+	if (!dev)
+		return -1;
+
+	if (dev->rwh_policy != RWH_BITMAP)
+		return 0;
+
+	offset = get_bitmap_header_sector(super, super->current_vol);
+	for (d = super->disks; d; d = d->next) {
+		if (d->index < 0 || is_failed(&d->disk))
+			continue;
+
+		if (validate_internal_bitmap_for_drive(st, offset, d)) {
+			pr_err("imsm: bitmap validation failed\n");
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/*******************************************************************************
+ * Function:	add_internal_bitmap_imsm
+ * Description:	Mark the volume to use the bitmap and updates the chunk size value.
+ * Parameters:
+ *	st		: supertype information
+ *	chunkp		: bitmap chunk size
+ *	delay		: not used for imsm
+ *	write_behind	: not used for imsm
+ *	size		: not used for imsm
+ *	may_change	: not used for imsm
+ *	amajor		: not used for imsm
+ *
+ * Returns:
+ *	 0 : success
+ *	-1 : fail
+ ******************************************************************************/
+static int add_internal_bitmap_imsm(struct supertype *st, int *chunkp,
+				    int delay, int write_behind,
+				    unsigned long long size, int may_change,
+				    int amajor)
+{
+	struct intel_super *super = st->sb;
+	int vol_idx = super->current_vol;
+	struct imsm_dev *dev;
+
+	if (!super->devlist || vol_idx == -1 || !chunkp)
+		return -1;
+
+	dev = get_imsm_dev(super, vol_idx);
+
+	if (!dev) {
+		dprintf("cannot find the device for volume index %d\n",
+			vol_idx);
+		return -1;
+	}
+	dev->rwh_policy = RWH_BITMAP;
+
+	*chunkp = calculate_bitmap_chunksize(st, dev);
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Function:	locate_bitmap_imsm
+ * Description:	Seek 'fd' to start of write-intent-bitmap.
+ * Parameters:
+ *	st		: supertype information
+ *	fd		: file descriptor for the device
+ *	node_num	: not used for imsm
+ *
+ * Returns:
+ *	 0 : success
+ *	-1 : fail
+ ******************************************************************************/
+static int locate_bitmap_imsm(struct supertype *st, int fd, int node_num)
+{
+	struct intel_super *super = st->sb;
+	unsigned long long offset;
+	int vol_idx = super->current_vol;
+
+	if (!super->devlist || vol_idx == -1)
+		return -1;
+
+	offset = get_bitmap_header_sector(super, super->current_vol);
+	dprintf("bitmap header offset is %llu\n", offset);
+
+	lseek64(fd, offset << 9, 0);
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Function:	write_init_bitmap_imsm
+ * Description:	Write a bitmap header and prepares the area for the bitmap.
+ * Parameters:
+ *	st	: supertype information
+ *	fd	: file descriptor for the device
+ *	update	: not used for imsm
+ *
+ * Returns:
+ *	 0 : success
+ *	-1 : fail
+ ******************************************************************************/
+static int write_init_bitmap_imsm(struct supertype *st, int fd,
+				  enum bitmap_update update)
+{
+	struct intel_super *super = st->sb;
+	int vol_idx = super->current_vol;
+	int ret = 0;
+	unsigned long long offset;
+	bitmap_super_t bms = { 0 };
+	size_t written = 0;
+	size_t to_write;
+	ssize_t rv_num;
+	void *buf;
+
+	if (!super->devlist || !super->sector_size || vol_idx == -1)
+		return -1;
+
+	struct imsm_dev *dev = get_imsm_dev(super, vol_idx);
+
+	/* first clear the space for bitmap header */
+	unsigned long long bitmap_area_start =
+		get_bitmap_header_sector(super, vol_idx);
+
+	dprintf("zeroing area start (%llu) and size (%u)\n", bitmap_area_start,
+		IMSM_BITMAP_AND_HEADER_SIZE / super->sector_size);
+	if (zero_disk_range(fd, bitmap_area_start,
+			    IMSM_BITMAP_HEADER_SIZE / super->sector_size)) {
+		pr_err("imsm: cannot zeroing the space for the bitmap\n");
+		return -1;
+	}
+
+	/* The bitmap area should be filled with "1"s to perform initial
+	 * synchronization.
+	 */
+	if (posix_memalign(&buf, MAX_SECTOR_SIZE, MAX_SECTOR_SIZE))
+		return -1;
+	memset(buf, 0xFF, MAX_SECTOR_SIZE);
+	offset = get_bitmap_sector(super, vol_idx);
+	lseek64(fd, offset << 9, 0);
+	while (written < IMSM_BITMAP_AREA_SIZE) {
+		to_write = IMSM_BITMAP_AREA_SIZE - written;
+		if (to_write > MAX_SECTOR_SIZE)
+			to_write = MAX_SECTOR_SIZE;
+		rv_num = write(fd, buf, MAX_SECTOR_SIZE);
+		if (rv_num != MAX_SECTOR_SIZE) {
+			ret = -1;
+			dprintf("cannot initialize bitmap area\n");
+			goto abort;
+		}
+		written += rv_num;
+	}
+
+	/* write a bitmap header */
+	init_bitmap_header(st, &bms, dev);
+	memset(buf, 0, MAX_SECTOR_SIZE);
+	memcpy(buf, &bms, sizeof(bitmap_super_t));
+	if (locate_bitmap_imsm(st, fd, 0)) {
+		ret = -1;
+		dprintf("cannot locate the bitmap\n");
+		goto abort;
+	}
+	if (write(fd, buf, MAX_SECTOR_SIZE) != MAX_SECTOR_SIZE) {
+		ret = -1;
+		dprintf("cannot write the bitmap header\n");
+		goto abort;
+	}
+	fsync(fd);
+
+abort:
+	free(buf);
+
+	return ret;
+}
+
+/*******************************************************************************
+ * Function:	is_vol_to_setup_bitmap
+ * Description:	Checks if a bitmap should be activated on the dev.
+ * Parameters:
+ *	info	: info about the volume to setup the bitmap
+ *	dev	: the device to check against bitmap creation
+ *
+ * Returns:
+ *	 0 : bitmap should be set up on the device
+ *	-1 : otherwise
+ ******************************************************************************/
+static int is_vol_to_setup_bitmap(struct mdinfo *info, struct imsm_dev *dev)
+{
+	if (!dev || !info)
+		return -1;
+
+	if ((strcmp((char *)dev->volume, info->name) == 0) &&
+	    (dev->rwh_policy == RWH_BITMAP))
+		return -1;
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Function:	set_bitmap_sysfs
+ * Description:	Set the sysfs atributes of a given volume to activate the bitmap.
+ * Parameters:
+ *	info		: info about the volume where the bitmap should be setup
+ *	chunksize	: bitmap chunk size
+ *	location	: location of the bitmap
+ *
+ * Returns:
+ *	 0 : success
+ *	-1 : fail
+ ******************************************************************************/
+static int set_bitmap_sysfs(struct mdinfo *info, unsigned long long chunksize,
+			    char *location)
+{
+	/* The bitmap/metadata is set to external to allow changing of value for
+	 * bitmap/location. When external is used, the kernel will treat an offset
+	 * related to the device's first lba (in opposition to the "internal" case
+	 * when this value is related to the beginning of the superblock).
+	 */
+	if (sysfs_set_str(info, NULL, "bitmap/metadata", "external")) {
+		dprintf("failed to set bitmap/metadata\n");
+		return -1;
+	}
+
+	/* It can only be changed when no bitmap is active.
+	 * Should be bigger than 512 and must be power of 2.
+	 * It is expecting the value in bytes.
+	 */
+	if (sysfs_set_num(info, NULL, "bitmap/chunksize",
+					  __cpu_to_le32(chunksize))) {
+		dprintf("failed to set bitmap/chunksize\n");
+		return -1;
+	}
+
+	/* It is expecting the value in sectors. */
+	if (sysfs_set_num(info, NULL, "bitmap/space",
+					  __cpu_to_le64(IMSM_BITMAP_AREA_SIZE))) {
+		dprintf("failed to set bitmap/space\n");
+		return -1;
+	}
+
+	/* Determines the delay between the bitmap updates.
+	 * It is expecting the value in seconds.
+	 */
+	if (sysfs_set_num(info, NULL, "bitmap/time_base",
+					  __cpu_to_le64(IMSM_DEFAULT_BITMAP_DAEMON_SLEEP))) {
+		dprintf("failed to set bitmap/time_base\n");
+		return -1;
+	}
+
+	/* It is expecting the value in sectors with a sign at the beginning. */
+	if (sysfs_set_str(info, NULL, "bitmap/location", location)) {
+		dprintf("failed to set bitmap/location\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Function:	set_bitmap_imsm
+ * Description:	Setup the bitmap for the given volume
+ * Parameters:
+ *	st	: supertype information
+ *	info	: info about the volume where the bitmap should be setup
+ *
+ * Returns:
+ *	 0 : success
+ *	-1 : fail
+ ******************************************************************************/
+static int set_bitmap_imsm(struct supertype *st, struct mdinfo *info)
+{
+	struct intel_super *super = st->sb;
+	int prev_current_vol = super->current_vol;
+	struct imsm_dev *dev;
+	int ret = -1;
+	char location[16] = "";
+	unsigned long long chunksize;
+	struct intel_dev *dev_it;
+
+	for (dev_it = super->devlist; dev_it; dev_it = dev_it->next) {
+		super->current_vol = dev_it->index;
+		dev = get_imsm_dev(super, super->current_vol);
+
+		if (is_vol_to_setup_bitmap(info, dev)) {
+			if (validate_internal_bitmap_imsm(st)) {
+				dprintf("bitmap header validation failed\n");
+				goto abort;
+			}
+
+			chunksize = calculate_bitmap_chunksize(st, dev);
+			dprintf("chunk size is %llu\n", chunksize);
+
+			snprintf(location, sizeof(location), "+%llu",
+				 get_bitmap_sector(super, super->current_vol));
+			dprintf("bitmap offset is %s\n", location);
+
+			if (set_bitmap_sysfs(info, chunksize, location)) {
+				dprintf("cannot setup the bitmap\n");
+				goto abort;
+			}
+		}
+	}
+	ret = 0;
+abort:
+	super->current_vol = prev_current_vol;
+	return ret;
+}
+
 struct superswitch super_imsm = {
 	.examine_super	= examine_super_imsm,
 	.brief_examine_super = brief_examine_super_imsm,
@@ -12347,6 +12957,11 @@ struct superswitch super_imsm = {
 	.container_content = container_content_imsm,
 	.validate_container = validate_container_imsm,
 
+	.add_internal_bitmap = add_internal_bitmap_imsm,
+	.locate_bitmap = locate_bitmap_imsm,
+	.write_bitmap = write_init_bitmap_imsm,
+	.set_bitmap = set_bitmap_imsm,
+
 	.write_init_ppl = write_init_ppl_imsm,
 	.validate_ppl	= validate_ppl_imsm,
 
-- 
2.26.2


  parent reply	other threads:[~2021-03-05 12:02 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-25  0:02 [PATCH 0/8] Write-intent bitmap support for IMSM metadata Jakub Radtke
2020-09-25  0:02 ` [PATCH 1/8] Modify mdstat parsing for volumes with the bitmap Jakub Radtke
2020-09-25  0:02 ` [PATCH 2/8] Enable bitmap support for external metadata Jakub Radtke
2020-09-25  0:02 ` Jakub Radtke [this message]
2020-09-25  0:03 ` [PATCH 4/8] imsm: Adding a spare to an existing array with bitmap Jakub Radtke
2020-09-25  0:03 ` [PATCH 5/8] Add "bitmap" to allowed command-line values Jakub Radtke
2020-09-25  0:03 ` [PATCH 6/8] imsm: Update-subarray for write-intent bitmap Jakub Radtke
2020-09-25  0:03 ` [PATCH 7/8] Create: Block automatic enabling bitmap for external metadata Jakub Radtke
2020-09-25  0:03 ` [PATCH 8/8] Grow: Block reshape when external metadata and write-intent bitmap Jakub Radtke
2021-01-15  5:46 [PATCH 0/8] Write-intent bitmap support for IMSM metadata Jakub Radtke
2021-01-15  5:46 ` [PATCH 3/8] imsm: Write-intent bitmap support Jakub Radtke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200925000304.169728-4-jakub.radtke@linux.intel.com \
    --to=jakub.radtke@linux.intel.com \
    --cc=jes@trained-monkey.org \
    --cc=linux-raid@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).