[mdadm/f15: 4/5] Make sure to retry in case a remove fails due to an array being busy

Jes Sorensen jsorensen at fedoraproject.org
Thu Jan 12 12:41:27 UTC 2012


commit 9d26a69f727aff6b4ff3ade3711b67862adbf48d
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Thu Jan 12 13:39:08 2012 +0100

    Make sure to retry in case a remove fails due to an array being busy
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>

 ...or-ensure-we-retry-soon-when-remove-fails.patch |   92 +++++++++++++++++
 ...ke-return-from-read_and_act-more-symbolic.patch |  109 ++++++++++++++++++++
 mdadm.spec                                         |    9 ++-
 3 files changed, 209 insertions(+), 1 deletions(-)
---
diff --git a/mdadm-3.2.3-monitor-ensure-we-retry-soon-when-remove-fails.patch b/mdadm-3.2.3-monitor-ensure-we-retry-soon-when-remove-fails.patch
new file mode 100644
index 0000000..a89bb5d
--- /dev/null
+++ b/mdadm-3.2.3-monitor-ensure-we-retry-soon-when-remove-fails.patch
@@ -0,0 +1,92 @@
+From 68226a80812cd9fce63dbd14d2225ffdf16a781b Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb at suse.de>
+Date: Tue, 3 Jan 2012 00:36:23 +1100
+Subject: [PATCH 2/2] monitor: ensure we retry soon when 'remove' fails.
+
+If a 'remove' fails there is no certainty that another event will
+happen soon, so make sure we retry soon anyway.
+
+Reported-by: Adam Kwolek <adam.kwolek at intel.com>
+Signed-off-by: NeilBrown <neilb at suse.de>
+---
+ mdadm.h   |    1 +
+ monitor.c |   16 ++++++++++------
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/mdadm.h b/mdadm.h
+index 3bcd052..381ef86 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -867,6 +867,7 @@ struct supertype {
+ 			*  external:/md0/12
+ 			*/
+ 	int devcnt;
++	int retry_soon;
+ 
+ 	struct mdinfo *devs;
+ 
+diff --git a/monitor.c b/monitor.c
+index cfe4178..c987d10 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -212,6 +212,7 @@ static void signal_manager(void)
+  */
+ 
+ #define ARRAY_DIRTY 1
++#define ARRAY_BUSY 2
+ static int read_and_act(struct active_array *a)
+ {
+ 	unsigned long long sync_completed;
+@@ -419,9 +420,9 @@ static int read_and_act(struct active_array *a)
+ 		if ((mdi->next_state & DS_REMOVE) && mdi->state_fd >= 0) {
+ 			int remove_result;
+ 
+-			/* the kernel may not be able to immediately remove the
+-			 * disk, we can simply wait until the next event to try
+-			 * again.
++			/* The kernel may not be able to immediately remove the
++			 * disk.  In that case we wait a little while and
++			 * try again.
+ 			 */
+ 			remove_result = write_attr("remove", mdi->state_fd);
+ 			if (remove_result > 0) {
+@@ -429,7 +430,8 @@ static int read_and_act(struct active_array *a)
+ 				close(mdi->state_fd);
+ 				close(mdi->recovery_fd);
+ 				mdi->state_fd = -1;
+-			}
++			} else
++				ret |= ARRAY_BUSY;
+ 		}
+ 		if (mdi->next_state & DS_INSYNC) {
+ 			write_attr("+in_sync", mdi->state_fd);
+@@ -597,7 +599,7 @@ static int wait_and_act(struct supertype *container, int nowait)
+ 		struct timespec ts;
+ 		ts.tv_sec = 24*3600;
+ 		ts.tv_nsec = 0;
+-		if (*aap == NULL) {
++		if (*aap == NULL || container->retry_soon) {
+ 			/* just waiting to get O_EXCL access */
+ 			ts.tv_sec = 0;
+ 			ts.tv_nsec = 20000000ULL;
+@@ -612,7 +614,7 @@ static int wait_and_act(struct supertype *container, int nowait)
+ 		#ifdef DEBUG
+ 		dprint_wake_reasons(&rfds);
+ 		#endif
+-
++		container->retry_soon = 0;
+ 	}
+ 
+ 	if (update_queue) {
+@@ -653,6 +655,8 @@ static int wait_and_act(struct supertype *container, int nowait)
+ 			 */
+ 			if (sigterm && !(ret & ARRAY_DIRTY))
+ 				a->container = NULL; /* stop touching this array */
++			if (ret & ARRAY_BUSY)
++				container->retry_soon = 1;
+ 		}
+ 	}
+ 
+-- 
+1.7.8.2
+
diff --git a/mdadm-3.2.3-monitor-make-return-from-read_and_act-more-symbolic.patch b/mdadm-3.2.3-monitor-make-return-from-read_and_act-more-symbolic.patch
new file mode 100644
index 0000000..edb85cb
--- /dev/null
+++ b/mdadm-3.2.3-monitor-make-return-from-read_and_act-more-symbolic.patch
@@ -0,0 +1,109 @@
+From 77b3ac8c6521d836dd3c6ef247c252293920fd52 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb at suse.de>
+Date: Tue, 3 Jan 2012 11:18:59 +1100
+Subject: [PATCH 1/2] monitor: make return from read_and_act more symbolic.
+
+Rather than just a number, use a named flag.
+
+This makes the code easier to understand and allows room for returning
+more flags later.
+
+Signed-off-by: NeilBrown <neilb at suse.de>
+---
+ monitor.c |   20 ++++++++++----------
+ 1 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/monitor.c b/monitor.c
+index 29bde18..cfe4178 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -211,6 +211,7 @@ static void signal_manager(void)
+  *
+  */
+ 
++#define ARRAY_DIRTY 1
+ static int read_and_act(struct active_array *a)
+ {
+ 	unsigned long long sync_completed;
+@@ -218,7 +219,7 @@ static int read_and_act(struct active_array *a)
+ 	int check_reshape = 0;
+ 	int deactivate = 0;
+ 	struct mdinfo *mdi;
+-	int dirty = 0;
++	int ret = 0;
+ 	int count = 0;
+ 
+ 	a->next_state = bad_word;
+@@ -254,14 +255,14 @@ static int read_and_act(struct active_array *a)
+ 	if (a->curr_state == write_pending) {
+ 		a->container->ss->set_array_state(a, 0);
+ 		a->next_state = active;
+-		dirty = 1;
++		ret |= ARRAY_DIRTY;
+ 	}
+ 	if (a->curr_state == active_idle) {
+ 		/* Set array to 'clean' FIRST, then mark clean
+ 		 * in the metadata
+ 		 */
+ 		a->next_state = clean;
+-		dirty = 1;
++		ret |= ARRAY_DIRTY;
+ 	}
+ 	if (a->curr_state == clean) {
+ 		a->container->ss->set_array_state(a, 1);
+@@ -269,7 +270,7 @@ static int read_and_act(struct active_array *a)
+ 	if (a->curr_state == active ||
+ 	    a->curr_state == suspended ||
+ 	    a->curr_state == bad_word)
+-		dirty = 1;
++		ret |= ARRAY_DIRTY;
+ 	if (a->curr_state == readonly) {
+ 		/* Well, I'm ready to handle things.  If readonly
+ 		 * wasn't requested, transition to read-auto.
+@@ -284,7 +285,7 @@ static int read_and_act(struct active_array *a)
+ 				a->next_state = read_auto; /* array is clean */
+ 			else {
+ 				a->next_state = active; /* Now active for recovery etc */
+-				dirty = 1;
++				ret |= ARRAY_DIRTY;
+ 			}
+ 		}
+ 	}
+@@ -459,7 +460,7 @@ static int read_and_act(struct active_array *a)
+ 	if (deactivate)
+ 		a->container = NULL;
+ 
+-	return dirty;
++	return ret;
+ }
+ 
+ static struct mdinfo *
+@@ -629,7 +630,6 @@ static int wait_and_act(struct supertype *container, int nowait)
+ 	rv = 0;
+ 	dirty_arrays = 0;
+ 	for (a = *aap; a ; a = a->next) {
+-		int is_dirty;
+ 
+ 		if (a->replaces && !discard_this) {
+ 			struct active_array **ap;
+@@ -644,14 +644,14 @@ static int wait_and_act(struct supertype *container, int nowait)
+ 			signal_manager();
+ 		}
+ 		if (a->container && !a->to_remove) {
+-			is_dirty = read_and_act(a);
++			int ret = read_and_act(a);
+ 			rv |= 1;
+-			dirty_arrays += is_dirty;
++			dirty_arrays += !!(ret & ARRAY_DIRTY);
+ 			/* when terminating stop manipulating the array after it
+ 			 * is clean, but make sure read_and_act() is given a
+ 			 * chance to handle 'active_idle'
+ 			 */
+-			if (sigterm && !is_dirty)
++			if (sigterm && !(ret & ARRAY_DIRTY))
+ 				a->container = NULL; /* stop touching this array */
+ 		}
+ 	}
+-- 
+1.7.8.2
+
diff --git a/mdadm.spec b/mdadm.spec
index 2d160af..b04c119 100644
--- a/mdadm.spec
+++ b/mdadm.spec
@@ -1,7 +1,7 @@
 Summary:     The mdadm program controls Linux md devices (software RAID arrays)
 Name:        mdadm
 Version:     3.2.3
-Release:     2%{?dist}
+Release:     3%{?dist}
 Source:      http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.bz2
 Source1:     mdmonitor.init
 Source2:     raid-check
@@ -12,6 +12,8 @@ Source6:     mdmonitor.service
 Source7:     mdmonitor-takeover.service
 Source8:     mdadm.conf
 Patch1:      mdadm-3.2.3-Work-around-gcc-4.7-s-strict-aliasing-checks.patch
+Patch2:      mdadm-3.2.3-monitor-make-return-from-read_and_act-more-symbolic.patch
+Patch3:      mdadm-3.2.3-monitor-ensure-we-retry-soon-when-remove-fails.patch
 Patch19:     mdadm-3.2.3-udev.patch
 Patch20:     mdadm-2.5.2-static.patch
 URL:         http://www.kernel.org/pub/linux/utils/raid/mdadm/
@@ -121,6 +123,11 @@ fi
 %{_initrddir}/*
 
 %changelog
+* Thu Jan 12 2012 Jes Sorensen <Jes.Sorensen at redhat.com> - 3.2.3-3
+- Fix case where we have to retry in case a remove fails due to an array
+  being busy
+- Resolves: bz773337 (rawhide) bz773340 (f16) bz773341 (f15)
+
 * Thu Jan 5 2012 Jes Sorensen <Jes.Sorensen at redhat.com> - 3.2.3-2
 - Workaround for gcc-4.7 strict aliasing breaking the build
 


More information about the scm-commits mailing list