aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Bader <Stefan.Bader@de.ibm.com>2005-11-22 00:32:35 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-22 12:14:31 -0500
commit640eb3b0456f8273726d31160aa24568ae703eec (patch)
treef7c15ae433fb7bb57251c9496de4d3ba91b761e0
parent0e56822d30184d0da35a6ecc51f38c4ceb457a80 (diff)
[PATCH] device-mapper dm-mpath: endio spinlock fix
do_end_io() can be called without interrupts blocked. Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/md/dm-mpath.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index f9b7b32d5d5c..f72a82fb9434 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -1000,6 +1000,7 @@ static int do_end_io(struct multipath *m, struct bio *bio,
1000{ 1000{
1001 struct hw_handler *hwh = &m->hw_handler; 1001 struct hw_handler *hwh = &m->hw_handler;
1002 unsigned err_flags = MP_FAIL_PATH; /* Default behavior */ 1002 unsigned err_flags = MP_FAIL_PATH; /* Default behavior */
1003 unsigned long flags;
1003 1004
1004 if (!error) 1005 if (!error)
1005 return 0; /* I/O complete */ 1006 return 0; /* I/O complete */
@@ -1010,17 +1011,17 @@ static int do_end_io(struct multipath *m, struct bio *bio,
1010 if (error == -EOPNOTSUPP) 1011 if (error == -EOPNOTSUPP)
1011 return error; 1012 return error;
1012 1013
1013 spin_lock(&m->lock); 1014 spin_lock_irqsave(&m->lock, flags);
1014 if (!m->nr_valid_paths) { 1015 if (!m->nr_valid_paths) {
1015 if (!m->queue_if_no_path) { 1016 if (!m->queue_if_no_path) {
1016 spin_unlock(&m->lock); 1017 spin_unlock_irqrestore(&m->lock, flags);
1017 return -EIO; 1018 return -EIO;
1018 } else { 1019 } else {
1019 spin_unlock(&m->lock); 1020 spin_unlock_irqrestore(&m->lock, flags);
1020 goto requeue; 1021 goto requeue;
1021 } 1022 }
1022 } 1023 }
1023 spin_unlock(&m->lock); 1024 spin_unlock_irqrestore(&m->lock, flags);
1024 1025
1025 if (hwh->type && hwh->type->error) 1026 if (hwh->type && hwh->type->error)
1026 err_flags = hwh->type->error(hwh, bio); 1027 err_flags = hwh->type->error(hwh, bio);
@@ -1040,12 +1041,12 @@ static int do_end_io(struct multipath *m, struct bio *bio,
1040 dm_bio_restore(&mpio->details, bio); 1041 dm_bio_restore(&mpio->details, bio);
1041 1042
1042 /* queue for the daemon to resubmit or fail */ 1043 /* queue for the daemon to resubmit or fail */
1043 spin_lock(&m->lock); 1044 spin_lock_irqsave(&m->lock, flags);
1044 bio_list_add(&m->queued_ios, bio); 1045 bio_list_add(&m->queued_ios, bio);
1045 m->queue_size++; 1046 m->queue_size++;
1046 if (!m->queue_io) 1047 if (!m->queue_io)
1047 queue_work(kmultipathd, &m->process_queued_ios); 1048 queue_work(kmultipathd, &m->process_queued_ios);
1048 spin_unlock(&m->lock); 1049 spin_unlock_irqrestore(&m->lock, flags);
1049 1050
1050 return 1; /* io not complete */ 1051 return 1; /* io not complete */
1051} 1052}