[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[dm-devel] [PATCH] fix resubmit/end_io bug in dm-mpath (take 2)



The attached patch should fix the race that could occur when an io is resubmitted and other io is being mapped at the same time. It should replace the patch here http://lists.sistina.com/pipermail/dm-devel/2003-December/000354.html because the current_path access needs to be performed under the path_lock too.

mike


Mike Christie mikenc us ibm com
--- linux-2.6.0-test10-udm3.orig/drivers/md/dm-mpath.c	2003-12-26 21:12:44.936116516 -0800
+++ linux-2.6.0-test10-udm3/drivers/md/dm-mpath.c	2003-12-26 21:37:56.127234374 -0800
@@ -650,18 +650,10 @@ static struct path *__find_path(struct m
 	return NULL;
 }
 
-static int __resubmit_io(struct multipath *m, struct bio *bio)
+static void __resubmit_io(struct multipath *m, struct bio *bio)
 {
-	int r;
 	unsigned long flags;
 
-	r = __choose_path(m);
-	if (r)
-		return r;
-
-	/* remap */
-	bio->bi_bdev = m->current_path->dev->bdev;
-
 	/* queue for the daemon to resubmit */
 	spin_lock_irqsave(&m->failed_lock, flags);
 	bio->bi_next = m->failed_ios;
@@ -669,27 +661,32 @@ static int __resubmit_io(struct multipat
 	spin_unlock_irqrestore(&m->failed_lock, flags);
 
 	dm_daemon_wake(&_kmpathd);
-	return 1;	/* io not complete */
 }
 
 static int multipath_end_io(struct dm_target *ti, struct bio *bio,
 			    int error, union map_info *map_context)
 {
-	int r = 0;
+	struct path *path;
 	struct multipath *m = (struct multipath *) ti->private;
 
-	if (error) {
-		struct path *path;
+	if (!error)
+		return 0;
 
-		spin_lock(&m->path_lock);
-		path = __find_path(m, bio->bi_bdev);
-		__fail_path(path);
+	spin_lock(&m->path_lock);
+	path = __find_path(m, bio->bi_bdev);
+	__fail_path(path);
+	if (__choose_path(m)) {
 		spin_unlock(&m->path_lock);
-
-		r = __resubmit_io(m, bio);
+		return -EIO;
 	}
 
-	return r;
+	/* remap */
+	bio->bi_bdev = m->current_path->dev->bdev;
+	spin_unlock(&m->path_lock);
+
+	__resubmit_io(m, bio);
+	/* io not complete */
+	return 1;
 }
 
 static void lock_path(struct path *p) {down(&p->test_lock);}

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]