diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-28 19:06:48 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-28 19:06:48 -0400 |
| commit | 2d04f6b9bc91540b8e931a0700440118161092e0 (patch) | |
| tree | 465e71032f1494af5548204871d623dc00a59018 | |
| parent | 8b86bd7a4a82157d386aebafbe1bdf26bdf3d713 (diff) | |
| parent | 69838727bcd819a8fd73a88447801221788b0c6d (diff) | |
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
bio: fix memcpy corruption in bio_copy_user_iov()
hd: fix locking
mg_disk: fix CONFIG_LBD=y warning
mg_disk: fix locking
| -rw-r--r-- | drivers/block/hd.c | 17 | ||||
| -rw-r--r-- | drivers/block/mg_disk.c | 19 | ||||
| -rw-r--r-- | fs/bio.c | 3 |
3 files changed, 24 insertions, 15 deletions
diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 3c11f062a18c..baaa9e486e50 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c | |||
| @@ -509,7 +509,6 @@ ok_to_write: | |||
| 509 | if (i > 0) { | 509 | if (i > 0) { |
| 510 | SET_HANDLER(&write_intr); | 510 | SET_HANDLER(&write_intr); |
| 511 | outsw(HD_DATA, req->buffer, 256); | 511 | outsw(HD_DATA, req->buffer, 256); |
| 512 | local_irq_enable(); | ||
| 513 | } else { | 512 | } else { |
| 514 | #if (HD_DELAY > 0) | 513 | #if (HD_DELAY > 0) |
| 515 | last_req = read_timer(); | 514 | last_req = read_timer(); |
| @@ -541,8 +540,7 @@ static void hd_times_out(unsigned long dummy) | |||
| 541 | if (!CURRENT) | 540 | if (!CURRENT) |
| 542 | return; | 541 | return; |
| 543 | 542 | ||
| 544 | disable_irq(HD_IRQ); | 543 | spin_lock_irq(hd_queue->queue_lock); |
| 545 | local_irq_enable(); | ||
| 546 | reset = 1; | 544 | reset = 1; |
| 547 | name = CURRENT->rq_disk->disk_name; | 545 | name = CURRENT->rq_disk->disk_name; |
| 548 | printk("%s: timeout\n", name); | 546 | printk("%s: timeout\n", name); |
| @@ -552,9 +550,8 @@ static void hd_times_out(unsigned long dummy) | |||
| 552 | #endif | 550 | #endif |
| 553 | end_request(CURRENT, 0); | 551 | end_request(CURRENT, 0); |
| 554 | } | 552 | } |
| 555 | local_irq_disable(); | ||
| 556 | hd_request(); | 553 | hd_request(); |
| 557 | enable_irq(HD_IRQ); | 554 | spin_unlock_irq(hd_queue->queue_lock); |
| 558 | } | 555 | } |
| 559 | 556 | ||
| 560 | static int do_special_op(struct hd_i_struct *disk, struct request *req) | 557 | static int do_special_op(struct hd_i_struct *disk, struct request *req) |
| @@ -592,7 +589,6 @@ static void hd_request(void) | |||
| 592 | return; | 589 | return; |
| 593 | repeat: | 590 | repeat: |
| 594 | del_timer(&device_timer); | 591 | del_timer(&device_timer); |
| 595 | local_irq_enable(); | ||
| 596 | 592 | ||
| 597 | req = CURRENT; | 593 | req = CURRENT; |
| 598 | if (!req) { | 594 | if (!req) { |
| @@ -601,7 +597,6 @@ repeat: | |||
| 601 | } | 597 | } |
| 602 | 598 | ||
| 603 | if (reset) { | 599 | if (reset) { |
| 604 | local_irq_disable(); | ||
| 605 | reset_hd(); | 600 | reset_hd(); |
| 606 | return; | 601 | return; |
| 607 | } | 602 | } |
| @@ -660,9 +655,7 @@ repeat: | |||
| 660 | 655 | ||
| 661 | static void do_hd_request(struct request_queue *q) | 656 | static void do_hd_request(struct request_queue *q) |
| 662 | { | 657 | { |
| 663 | disable_irq(HD_IRQ); | ||
| 664 | hd_request(); | 658 | hd_request(); |
| 665 | enable_irq(HD_IRQ); | ||
| 666 | } | 659 | } |
| 667 | 660 | ||
| 668 | static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | 661 | static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
| @@ -684,12 +677,16 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id) | |||
| 684 | { | 677 | { |
| 685 | void (*handler)(void) = do_hd; | 678 | void (*handler)(void) = do_hd; |
| 686 | 679 | ||
| 680 | spin_lock(hd_queue->queue_lock); | ||
| 681 | |||
| 687 | do_hd = NULL; | 682 | do_hd = NULL; |
| 688 | del_timer(&device_timer); | 683 | del_timer(&device_timer); |
| 689 | if (!handler) | 684 | if (!handler) |
| 690 | handler = unexpected_hd_interrupt; | 685 | handler = unexpected_hd_interrupt; |
| 691 | handler(); | 686 | handler(); |
| 692 | local_irq_enable(); | 687 | |
| 688 | spin_unlock(hd_queue->queue_lock); | ||
| 689 | |||
| 693 | return IRQ_HANDLED; | 690 | return IRQ_HANDLED; |
| 694 | } | 691 | } |
| 695 | 692 | ||
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index fb39d9aa3cdc..f3898353d0a8 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c | |||
| @@ -79,7 +79,7 @@ static void mg_dump_status(const char *msg, unsigned int stat, | |||
| 79 | if (host->breq) { | 79 | if (host->breq) { |
| 80 | req = elv_next_request(host->breq); | 80 | req = elv_next_request(host->breq); |
| 81 | if (req) | 81 | if (req) |
| 82 | printk(", sector=%ld", req->sector); | 82 | printk(", sector=%u", (u32)req->sector); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | } | 85 | } |
| @@ -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) |
| @@ -817,6 +817,9 @@ struct bio *bio_copy_user_iov(struct request_queue *q, | |||
| 817 | len += iov[i].iov_len; | 817 | len += iov[i].iov_len; |
| 818 | } | 818 | } |
| 819 | 819 | ||
| 820 | if (offset) | ||
| 821 | nr_pages++; | ||
| 822 | |||
| 820 | bmd = bio_alloc_map_data(nr_pages, iov_count, gfp_mask); | 823 | bmd = bio_alloc_map_data(nr_pages, iov_count, gfp_mask); |
| 821 | if (!bmd) | 824 | if (!bmd) |
| 822 | return ERR_PTR(-ENOMEM); | 825 | return ERR_PTR(-ENOMEM); |
