|
|
8e8941 |
From 12724c018c964596aa277489fd287d5c3506361a Mon Sep 17 00:00:00 2001
|
|
|
8e8941 |
From: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
|
|
|
8e8941 |
Date: Fri, 17 Apr 2020 13:55:55 +0200
|
|
|
8e8941 |
Subject: [RHEL7.9 PATCH 73/77] Manage, imsm: Write metadata before add
|
|
|
8e8941 |
|
|
|
8e8941 |
New drive in container always appears as spare. Manager is able to
|
|
|
8e8941 |
handle that, and queues appropriative update to monitor.
|
|
|
8e8941 |
No update from mdadm side has to be processed, just insert the drive and
|
|
|
8e8941 |
ping the mdmon. Metadata has to be written if no mdmon is running (case
|
|
|
8e8941 |
for Raid0 or container without arrays).
|
|
|
8e8941 |
|
|
|
8e8941 |
If bare drive is added very early on startup (by custom bare rule),
|
|
|
8e8941 |
there is possiblity that mdmon was not restarted after switch root. Old
|
|
|
8e8941 |
one is not able to handle new drive. New one fails because there is
|
|
|
8e8941 |
drive without metadata in container and metadata cannot be loaded.
|
|
|
8e8941 |
|
|
|
8e8941 |
To prevent this, write spare metadata before adding device
|
|
|
8e8941 |
to container. Mdmon will overwrite it (same case as spare migration,
|
|
|
8e8941 |
if drive appears it writes the most recent metadata).
|
|
|
8e8941 |
Metadata has to be written only on new drive before sysfs_add_disk(),
|
|
|
8e8941 |
don't race with mdmon if running.
|
|
|
8e8941 |
|
|
|
8e8941 |
Signed-off-by: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
|
|
|
8e8941 |
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
|
|
|
8e8941 |
---
|
|
|
8e8941 |
Manage.c | 6 +-----
|
|
|
8e8941 |
super-intel.c | 66 ++++++++++++++++++++++++++++++++++++++---------------------
|
|
|
8e8941 |
2 files changed, 44 insertions(+), 28 deletions(-)
|
|
|
8e8941 |
|
|
|
8e8941 |
diff --git a/Manage.c b/Manage.c
|
|
|
8e8941 |
index b22c396..0a5f09b 100644
|
|
|
8e8941 |
--- a/Manage.c
|
|
|
8e8941 |
+++ b/Manage.c
|
|
|
8e8941 |
@@ -994,17 +994,13 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
|
|
8e8941 |
|
|
|
8e8941 |
Kill(dv->devname, NULL, 0, -1, 0);
|
|
|
8e8941 |
dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
|
|
|
8e8941 |
- if (mdmon_running(tst->container_devnm))
|
|
|
8e8941 |
- tst->update_tail = &tst->updates;
|
|
|
8e8941 |
if (tst->ss->add_to_super(tst, &disc, dfd,
|
|
|
8e8941 |
dv->devname, INVALID_SECTORS)) {
|
|
|
8e8941 |
close(dfd);
|
|
|
8e8941 |
close(container_fd);
|
|
|
8e8941 |
return -1;
|
|
|
8e8941 |
}
|
|
|
8e8941 |
- if (tst->update_tail)
|
|
|
8e8941 |
- flush_metadata_updates(tst);
|
|
|
8e8941 |
- else
|
|
|
8e8941 |
+ if (!mdmon_running(tst->container_devnm))
|
|
|
8e8941 |
tst->ss->sync_metadata(tst);
|
|
|
8e8941 |
|
|
|
8e8941 |
sra = sysfs_read(container_fd, NULL, 0);
|
|
|
8e8941 |
diff --git a/super-intel.c b/super-intel.c
|
|
|
8e8941 |
index 562a58c..3a73d2b 100644
|
|
|
8e8941 |
--- a/super-intel.c
|
|
|
8e8941 |
+++ b/super-intel.c
|
|
|
8e8941 |
@@ -5809,6 +5809,9 @@ int mark_spare(struct dl *disk)
|
|
|
8e8941 |
return ret_val;
|
|
|
8e8941 |
}
|
|
|
8e8941 |
|
|
|
8e8941 |
+
|
|
|
8e8941 |
+static int write_super_imsm_spare(struct intel_super *super, struct dl *d);
|
|
|
8e8941 |
+
|
|
|
8e8941 |
static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
|
|
|
8e8941 |
int fd, char *devname,
|
|
|
8e8941 |
unsigned long long data_offset)
|
|
|
8e8941 |
@@ -5938,9 +5941,13 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
|
|
|
8e8941 |
dd->next = super->disk_mgmt_list;
|
|
|
8e8941 |
super->disk_mgmt_list = dd;
|
|
|
8e8941 |
} else {
|
|
|
8e8941 |
+ /* this is called outside of mdmon
|
|
|
8e8941 |
+ * write initial spare metadata
|
|
|
8e8941 |
+ * mdmon will overwrite it.
|
|
|
8e8941 |
+ */
|
|
|
8e8941 |
dd->next = super->disks;
|
|
|
8e8941 |
super->disks = dd;
|
|
|
8e8941 |
- super->updates_pending++;
|
|
|
8e8941 |
+ write_super_imsm_spare(super, dd);
|
|
|
8e8941 |
}
|
|
|
8e8941 |
|
|
|
8e8941 |
return 0;
|
|
|
8e8941 |
@@ -5979,15 +5986,15 @@ static union {
|
|
|
8e8941 |
struct imsm_super anchor;
|
|
|
8e8941 |
} spare_record __attribute__ ((aligned(MAX_SECTOR_SIZE)));
|
|
|
8e8941 |
|
|
|
8e8941 |
-/* spare records have their own family number and do not have any defined raid
|
|
|
8e8941 |
- * devices
|
|
|
8e8941 |
- */
|
|
|
8e8941 |
-static int write_super_imsm_spares(struct intel_super *super, int doclose)
|
|
|
8e8941 |
+
|
|
|
8e8941 |
+static int write_super_imsm_spare(struct intel_super *super, struct dl *d)
|
|
|
8e8941 |
{
|
|
|
8e8941 |
struct imsm_super *mpb = super->anchor;
|
|
|
8e8941 |
struct imsm_super *spare = &spare_record.anchor;
|
|
|
8e8941 |
__u32 sum;
|
|
|
8e8941 |
- struct dl *d;
|
|
|
8e8941 |
+
|
|
|
8e8941 |
+ if (d->index != -1)
|
|
|
8e8941 |
+ return 1;
|
|
|
8e8941 |
|
|
|
8e8941 |
spare->mpb_size = __cpu_to_le32(sizeof(struct imsm_super));
|
|
|
8e8941 |
spare->generation_num = __cpu_to_le32(1UL);
|
|
|
8e8941 |
@@ -6000,28 +6007,41 @@ static int write_super_imsm_spares(struct intel_super *super, int doclose)
|
|
|
8e8941 |
snprintf((char *) spare->sig, MAX_SIGNATURE_LENGTH,
|
|
|
8e8941 |
MPB_SIGNATURE MPB_VERSION_RAID0);
|
|
|
8e8941 |
|
|
|
8e8941 |
- for (d = super->disks; d; d = d->next) {
|
|
|
8e8941 |
- if (d->index != -1)
|
|
|
8e8941 |
- continue;
|
|
|
8e8941 |
+ spare->disk[0] = d->disk;
|
|
|
8e8941 |
+ if (__le32_to_cpu(d->disk.total_blocks_hi) > 0)
|
|
|
8e8941 |
+ spare->attributes |= MPB_ATTRIB_2TB_DISK;
|
|
|
8e8941 |
|
|
|
8e8941 |
- spare->disk[0] = d->disk;
|
|
|
8e8941 |
- if (__le32_to_cpu(d->disk.total_blocks_hi) > 0)
|
|
|
8e8941 |
- spare->attributes |= MPB_ATTRIB_2TB_DISK;
|
|
|
8e8941 |
+ if (super->sector_size == 4096)
|
|
|
8e8941 |
+ convert_to_4k_imsm_disk(&spare->disk[0]);
|
|
|
8e8941 |
|
|
|
8e8941 |
- if (super->sector_size == 4096)
|
|
|
8e8941 |
- convert_to_4k_imsm_disk(&spare->disk[0]);
|
|
|
8e8941 |
+ sum = __gen_imsm_checksum(spare);
|
|
|
8e8941 |
+ spare->family_num = __cpu_to_le32(sum);
|
|
|
8e8941 |
+ spare->orig_family_num = 0;
|
|
|
8e8941 |
+ sum = __gen_imsm_checksum(spare);
|
|
|
8e8941 |
+ spare->check_sum = __cpu_to_le32(sum);
|
|
|
8e8941 |
|
|
|
8e8941 |
- sum = __gen_imsm_checksum(spare);
|
|
|
8e8941 |
- spare->family_num = __cpu_to_le32(sum);
|
|
|
8e8941 |
- spare->orig_family_num = 0;
|
|
|
8e8941 |
- sum = __gen_imsm_checksum(spare);
|
|
|
8e8941 |
- spare->check_sum = __cpu_to_le32(sum);
|
|
|
8e8941 |
+ if (store_imsm_mpb(d->fd, spare)) {
|
|
|
8e8941 |
+ pr_err("failed for device %d:%d %s\n",
|
|
|
8e8941 |
+ d->major, d->minor, strerror(errno));
|
|
|
8e8941 |
+ return 1;
|
|
|
8e8941 |
+ }
|
|
|
8e8941 |
+
|
|
|
8e8941 |
+ return 0;
|
|
|
8e8941 |
+}
|
|
|
8e8941 |
+/* spare records have their own family number and do not have any defined raid
|
|
|
8e8941 |
+ * devices
|
|
|
8e8941 |
+ */
|
|
|
8e8941 |
+static int write_super_imsm_spares(struct intel_super *super, int doclose)
|
|
|
8e8941 |
+{
|
|
|
8e8941 |
+ struct dl *d;
|
|
|
8e8941 |
+
|
|
|
8e8941 |
+ for (d = super->disks; d; d = d->next) {
|
|
|
8e8941 |
+ if (d->index != -1)
|
|
|
8e8941 |
+ continue;
|
|
|
8e8941 |
|
|
|
8e8941 |
- if (store_imsm_mpb(d->fd, spare)) {
|
|
|
8e8941 |
- pr_err("failed for device %d:%d %s\n",
|
|
|
8e8941 |
- d->major, d->minor, strerror(errno));
|
|
|
8e8941 |
+ if (write_super_imsm_spare(super, d))
|
|
|
8e8941 |
return 1;
|
|
|
8e8941 |
- }
|
|
|
8e8941 |
+
|
|
|
8e8941 |
if (doclose) {
|
|
|
8e8941 |
close(d->fd);
|
|
|
8e8941 |
d->fd = -1;
|
|
|
8e8941 |
--
|
|
|
8e8941 |
2.7.5
|
|
|
8e8941 |
|