Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.0:Ports
mdadm
0017-Retry-HOT_REMOVE_DISK-a-few-times.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0017-Retry-HOT_REMOVE_DISK-a-few-times.patch of Package mdadm
From 2dd271fe7041c2f7036939cf6917c0578b92fefe Mon Sep 17 00:00:00 2001 From: NeilBrown <neilb@suse.com> Date: Mon, 27 Mar 2017 12:50:16 +1100 Subject: [PATCH] Retry HOT_REMOVE_DISK a few times. References: bsc#808647 HOT_REMOVE_DISK can fail with EBUSY if there are outstanding IO request that have not completed yet. It can sometimes be helpful to wait a little while for these to complete. We already do this in impose_level() when reshaping a device, but not in Manage.c in response to an explicit --remove request. So create hot_remove_disk() to central this code, and call it where-ever it makes sense to wait for a HOT_REMOVE_DISK to succeed. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com> --- Grow.c | 9 +-------- Manage.c | 4 ++-- mdadm.h | 1 + util.c | 18 ++++++++++++++++++ 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Grow.c b/Grow.c index 455c5f9..218a706 100755 --- a/Grow.c +++ b/Grow.c @@ -2736,7 +2736,6 @@ static int impose_level(int fd, int level, char *devname, int verbose) for (d = 0, found = 0; d < MAX_DISKS && found < array.nr_disks; d++) { - int cnt; mdu_disk_info_t disk; disk.number = d; if (ioctl(fd, GET_DISK_INFO, &disk) < 0) @@ -2750,13 +2749,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) continue; ioctl(fd, SET_DISK_FAULTY, makedev(disk.major, disk.minor)); - cnt = 5; - while (ioctl(fd, HOT_REMOVE_DISK, - makedev(disk.major, disk.minor)) < 0 - && errno == EBUSY - && cnt--) { - usleep(10000); - } + hot_remove_disk(fd, makedev(disk.major, disk.minor)); } } c = map_num(pers, level); diff --git a/Manage.c b/Manage.c index 5c3d2b9..9139f96 100644 --- a/Manage.c +++ b/Manage.c @@ -1183,7 +1183,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, else err = 0; } else { - err = ioctl(fd, HOT_REMOVE_DISK, rdev); + err = hot_remove_disk(fd, rdev); if (err && errno == ENODEV) { /* Old kernels rejected this if no personality * is registered */ @@ -1607,7 +1607,7 @@ int Manage_subdevs(char *devname, int fd, if (dv->disposition == 'F') /* Need to remove first */ - ioctl(fd, HOT_REMOVE_DISK, rdev); + hot_remove_disk(fd, rdev); /* Make sure it isn't in use (in 2.6 or later) */ tfd = dev_open(dv->devname, O_RDONLY|O_EXCL); if (tfd >= 0) { diff --git a/mdadm.h b/mdadm.h index 91fd9eb..5bcfb86 100644 --- a/mdadm.h +++ b/mdadm.h @@ -1476,6 +1476,7 @@ extern int add_disk(int mdfd, struct supertype *st, struct mdinfo *sra, struct mdinfo *info); extern int remove_disk(int mdfd, struct supertype *st, struct mdinfo *sra, struct mdinfo *info); +extern int hot_remove_disk(int mdfd, unsigned long dev); extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info); unsigned long long min_recovery_start(struct mdinfo *array); diff --git a/util.c b/util.c index 32bd909..d09a7e2 100644 --- a/util.c +++ b/util.c @@ -1795,6 +1795,24 @@ int remove_disk(int mdfd, struct supertype *st, return rv; } +int hot_remove_disk(int mdfd, unsigned long dev) +{ + int cnt = 5; + int ret; + + /* HOT_REMOVE_DISK can fail with EBUSY if there are + * outstanding IO requests to the device. + * In this case, it can be helpful to wait a little while, + * up to half a second, for that IO to flush. + */ + while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 && + errno == EBUSY && + cnt-- > 0) + usleep(10000); + + return ret; +} + int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) { /* Initialise kernel's knowledge of array. -- 2.10.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor