diff options
author | Tejun Heo <tj@kernel.org> | 2009-04-27 23:38:32 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-04-28 01:36:56 -0400 |
commit | ac2ff946a53e7bd0ae98f4e5d1d6c1b1dced82e5 (patch) | |
tree | ab50d2e1bcf5c76bb9e018839d77ff531e7e4c83 /drivers | |
parent | ce8a7424d23a36f043d0de8484f888971c831119 (diff) |
mg_disk: fix locking
IRQ and timeout handlers call functions which expect locked queue lock
without locking it. Fix it.
While at it, convert 0s used as null pointer constant to NULLs.
[ Impact: fix locking, cleanup ]
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: unsik Kim <donari75@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/mg_disk.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index fb39d9aa3cdc..d3e72ad08dbe 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c | |||
@@ -160,11 +160,16 @@ static irqreturn_t mg_irq(int irq, void *dev_id) | |||
160 | struct mg_host *host = dev_id; | 160 | struct mg_host *host = dev_id; |
161 | void (*handler)(struct mg_host *) = host->mg_do_intr; | 161 | void (*handler)(struct mg_host *) = host->mg_do_intr; |
162 | 162 | ||
163 | host->mg_do_intr = 0; | 163 | spin_lock(&host->lock); |
164 | |||
165 | host->mg_do_intr = NULL; | ||
164 | del_timer(&host->timer); | 166 | del_timer(&host->timer); |
165 | if (!handler) | 167 | if (!handler) |
166 | handler = mg_unexpected_intr; | 168 | handler = mg_unexpected_intr; |
167 | handler(host); | 169 | handler(host); |
170 | |||
171 | spin_unlock(&host->lock); | ||
172 | |||
168 | return IRQ_HANDLED; | 173 | return IRQ_HANDLED; |
169 | } | 174 | } |
170 | 175 | ||
@@ -319,7 +324,7 @@ static void mg_read(struct request *req) | |||
319 | 324 | ||
320 | remains = req->nr_sectors; | 325 | remains = req->nr_sectors; |
321 | 326 | ||
322 | if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, 0) != | 327 | if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, NULL) != |
323 | MG_ERR_NONE) | 328 | MG_ERR_NONE) |
324 | mg_bad_rw_intr(host); | 329 | mg_bad_rw_intr(host); |
325 | 330 | ||
@@ -363,7 +368,7 @@ static void mg_write(struct request *req) | |||
363 | 368 | ||
364 | remains = req->nr_sectors; | 369 | remains = req->nr_sectors; |
365 | 370 | ||
366 | if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, 0) != | 371 | if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, NULL) != |
367 | MG_ERR_NONE) { | 372 | MG_ERR_NONE) { |
368 | mg_bad_rw_intr(host); | 373 | mg_bad_rw_intr(host); |
369 | return; | 374 | return; |
@@ -521,9 +526,11 @@ void mg_times_out(unsigned long data) | |||
521 | char *name; | 526 | char *name; |
522 | struct request *req; | 527 | struct request *req; |
523 | 528 | ||
529 | spin_lock_irq(&host->lock); | ||
530 | |||
524 | req = elv_next_request(host->breq); | 531 | req = elv_next_request(host->breq); |
525 | if (!req) | 532 | if (!req) |
526 | return; | 533 | goto out_unlock; |
527 | 534 | ||
528 | host->mg_do_intr = NULL; | 535 | host->mg_do_intr = NULL; |
529 | 536 | ||
@@ -534,6 +541,8 @@ void mg_times_out(unsigned long data) | |||
534 | mg_bad_rw_intr(host); | 541 | mg_bad_rw_intr(host); |
535 | 542 | ||
536 | mg_request(host->breq); | 543 | mg_request(host->breq); |
544 | out_unlock: | ||
545 | spin_unlock_irq(&host->lock); | ||
537 | } | 546 | } |
538 | 547 | ||
539 | static void mg_request_poll(struct request_queue *q) | 548 | static void mg_request_poll(struct request_queue *q) |