diff mbox

[2/3] dm: release _hash_lock when removing device in remove_all

Message ID 4C0E1ADA.2030003@ct.jp.nec.com (mailing list archive)
State Accepted, archived
Delegated to: Alasdair Kergon
Headers show

Commit Message

Kiyoshi Ueda June 8, 2010, 10:26 a.m. UTC
None
diff mbox

Patch

Index: 2.6.35-rc1/drivers/md/dm-ioctl.c
===================================================================
--- 2.6.35-rc1.orig/drivers/md/dm-ioctl.c
+++ 2.6.35-rc1/drivers/md/dm-ioctl.c
@@ -249,40 +249,42 @@  static void __hash_remove(struct hash_ce
 
 static void dm_hash_remove_all(int keep_open_devices)
 {
-	int i, dev_skipped, dev_removed;
+	int i, dev_skipped;
 	struct hash_cell *hc;
-	struct list_head *tmp, *n;
-
-	down_write(&_hash_lock);
+	struct mapped_device *md;
 
 retry:
-	dev_skipped = dev_removed = 0;
-	for (i = 0; i < NUM_BUCKETS; i++) {
-		list_for_each_safe (tmp, n, _name_buckets + i) {
-			hc = list_entry(tmp, struct hash_cell, name_list);
+	down_write(&_hash_lock);
+	for (dev_skipped = 0, i = 0; i < NUM_BUCKETS; i++) {
+		list_for_each_entry(hc, _name_buckets + i, name_list) {
+			md = hc->md;
+			dm_get(md);
 
-			if (keep_open_devices &&
-			    dm_lock_for_deletion(hc->md)) {
+			if (keep_open_devices && dm_lock_for_deletion(md)) {
+				dm_put(md);
 				dev_skipped++;
 				continue;
 			}
+
 			__hash_remove(hc);
-			dev_removed = 1;
-		}
-	}
+			up_write(&_hash_lock);
 
-	/*
-	 * Some mapped devices may be using other mapped devices, so if any
-	 * still exist, repeat until we make no further progress.
-	 */
-	if (dev_skipped) {
-		if (dev_removed)
-			goto retry;
+			dm_put(md);
 
-		DMWARN("remove_all left %d open device(s)", dev_skipped);
+			/*
+			 * Some mapped devices may be using other mapped
+			 * devices, so repeat until we make no further
+			 * progress.
+			 * If a new mapped device is created here, it will be
+			 * also removed.
+			 */
+			goto retry;
+		}
 	}
-
 	up_write(&_hash_lock);
+
+	if (dev_skipped)
+		DMWARN("remove_all left %d open device(s)", dev_skipped);
 }
 
 static struct mapped_device *dm_hash_rename(struct dm_ioctl *param,