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

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

 



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@xxxxxxxxxx
--- 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);}

[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux