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

Joe Thornber thornber at sistina.com
Fri Jan 2 05:08:02 UTC 2004


Mike,

On Fri, Dec 26, 2003 at 10:01:52PM -0800, Mike Christie wrote:
> 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 

I've committed a slight variant, which will go out in todays udm.

Thanks,

- Joe

multipath_endio(): the call to __resubmit_io() wasn't within the lock.

Renamed __resubmit_io() -> __remap_io()

Lifted the submit code into multipath_endio() after a successful remap.

[Mike Christie]
--- diff/drivers/md/dm-mpath.c	2003-12-29 10:17:21.000000000 +0000
+++ source/drivers/md/dm-mpath.c	2004-01-02 11:03:56.000000000 +0000
@@ -650,10 +650,9 @@
 	return NULL;
 }
 
-static int __resubmit_io(struct multipath *m, struct bio *bio)
+static int __remap_io(struct multipath *m, struct bio *bio)
 {
 	int r;
-	unsigned long flags;
 
 	r = __choose_path(m);
 	if (r)
@@ -661,21 +660,14 @@
 
 	/* 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;
-	m->failed_ios = bio;
-	spin_unlock_irqrestore(&m->failed_lock, flags);
-
-	dm_daemon_wake(&_kmpathd);
-	return 1;	/* io not complete */
+	return 0;
 }
 
 static int multipath_end_io(struct dm_target *ti, struct bio *bio,
 			    int error, union map_info *map_context)
 {
 	int r = 0;
+	unsigned long flags;
 	struct multipath *m = (struct multipath *) ti->private;
 
 	if (error) {
@@ -684,9 +676,19 @@
 		spin_lock(&m->path_lock);
 		path = __find_path(m, bio->bi_bdev);
 		__fail_path(path);
+		r = __remap_io(m, bio);
 		spin_unlock(&m->path_lock);
 
-		r = __resubmit_io(m, bio);
+		if (!r) {
+			/* queue for the daemon to resubmit */
+			spin_lock_irqsave(&m->failed_lock, flags);
+			bio->bi_next = m->failed_ios;
+			m->failed_ios = bio;
+			spin_unlock_irqrestore(&m->failed_lock, flags);
+
+			dm_daemon_wake(&_kmpathd);
+			r = 1;	/* io not complete */
+		}
 	}
 
 	return r;




More information about the dm-devel mailing list