diff options
author | Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com> | 2024-11-04 11:37:41 +0100 |
---|---|---|
committer | Mariusz Tkaczyk <mtkaczyk@kernel.org> | 2024-12-16 10:11:31 +0100 |
commit | 7de5dc53bfbc3bae7d43fc81e51c7c56638004f6 (patch) | |
tree | b0921135f346406b9acf730c1a5e897f2ea05ef8 | |
parent | Coverity fixes resources leaks (diff) | |
download | mdadm-7de5dc53bfbc3bae7d43fc81e51c7c56638004f6.tar.xz mdadm-7de5dc53bfbc3bae7d43fc81e51c7c56638004f6.zip |
Incremental: Document workaround
Keep it documented in code.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
-rw-r--r-- | Incremental.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/Incremental.c b/Incremental.c index 9b455a12..60d6f8cb 100644 --- a/Incremental.c +++ b/Incremental.c @@ -1693,15 +1693,30 @@ int Incremental_remove(char *devname, char *id_path, int verbose) mdfd = open_dev_excl(ent->devnm); if (is_fd_valid(mdfd)) { + char *array_state_file = "array_state"; + + /** + * This is a workaround for the old issue. + * Incremental_remove() triggered from udev rule when disk is removed from OS + * tries to set array in auto-read-only mode. This can interrupt rebuild + * process which is started automatically, e.g. if array is mounted and + * spare disk is available (I/O errors limit might be achieved faster than disk is + * removed by mdadm). Prevent Incremental_remove() from setting array + * into "auto-read-only", by requiring exclusive open to succeed. + */ close_fd(&mdfd); - if (sysfs_get_str(&mdi, NULL, "array_state", - buf, sizeof(buf)) > 0) { - if (strncmp(buf, "active", 6) == 0 || - strncmp(buf, "clean", 5) == 0) - sysfs_set_str(&mdi, NULL, - "array_state", "read-auto"); + + if (sysfs_get_str(&mdi, NULL, array_state_file, buf, sizeof(buf)) > 0) { + char *str_read_auto = map_num_s(sysfs_array_states, ARRAY_READ_AUTO); + char *str_active = map_num_s(sysfs_array_states, ARRAY_ACTIVE); + char *str_clean = map_num_s(sysfs_array_states, ARRAY_CLEAN); + + if (strncmp(buf, str_active, strlen(str_active)) == 0 || + strncmp(buf, str_clean, strlen(str_clean)) == 0) + sysfs_set_str(&mdi, NULL, array_state_file, str_read_auto); } } + mdfd = open_dev(ent->devnm); if (mdfd < 0) { if (verbose >= 0) @@ -1711,6 +1726,7 @@ int Incremental_remove(char *devname, char *id_path, int verbose) if (id_path) { struct map_ent *map = NULL, *me; + me = map_by_devnm(&map, ent->devnm); if (me) policy_save_path(id_path, me); |