[PATCH] floppy.c: get io_request_lock before calling end_request

From: Jonathan Corbet (corbet-lk@lwn.net)
Date: Mon Aug 28 2000 - 18:34:04 EST


The floppy driver does much of its work in response to soft and hard
interrupts. Part of that work is the finishing up of completed requests,
including calling end_request(). The calls to end_request() happen without
the io_request_lock held, leading to a race condition in
end_that_request_last(). It's obviously a small one, or people would have
noticed, but a race is a race...

This is a straightforward fix against -test7.

jon

Jonathan Corbet
Executive editor, LWN.net
corbet@eklektix.com

--- linux-2.4.0-test7/drivers/block/floppy.c Thu Aug 24 10:25:36 2000
+++ linux-jc/drivers/block/floppy.c Mon Aug 28 16:33:11 2000
@@ -2282,6 +2282,7 @@
 static void request_done(int uptodate)
 {
         int block;
+ unsigned long flags;
 
         probing = 0;
         reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
@@ -2300,6 +2301,7 @@
                         DRS->maxtrack = 1;
 
                 /* unlock chained buffers */
+ spin_lock_irqsave(&io_request_lock, flags);
                 while (current_count_sectors && !QUEUE_EMPTY &&
                        current_count_sectors >= CURRENT->current_nr_sectors){
                         current_count_sectors -= CURRENT->current_nr_sectors;
@@ -2307,6 +2309,8 @@
                         CURRENT->sector += CURRENT->current_nr_sectors;
                         end_request(1);
                 }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
                 if (current_count_sectors && !QUEUE_EMPTY){
                         /* "unlock" last subsector */
                         CURRENT->buffer += current_count_sectors <<9;
@@ -2330,7 +2334,9 @@
                         DRWE->last_error_sector = CURRENT->sector;
                         DRWE->last_error_generation = DRS->generation;
                 }
+ spin_lock_irqsave(&io_request_lock, flags);
                 end_request(0);
+ spin_unlock_irqrestore(&io_request_lock, flags);
         }
 }
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Aug 31 2000 - 21:00:22 EST