aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-01-06 13:17:12 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-01-06 13:17:12 -0500
commit7b3d9545f9ac8b31528dd2d6d8ec8d19922917b8 (patch)
treee8af5ec41abf8ec3a678b5643de5580db417d16f
parent911833440b498e3e4fe2f12c1ae2bd44400c7004 (diff)
Revert "scsi: revert "[SCSI] Get rid of scsi_cmnd->done""
This reverts commit ac40532ef0b8649e6f7f83859ea0de1c4ed08a19, which gets us back the original cleanup of 6f5391c283d7fdcf24bf40786ea79061919d1e1d. It turns out that the bug that was triggered by that commit was apparently not actually triggered by that commit at all, and just the testing conditions had changed enough to make it appear to be due to it. The real problem seems to have been found by Peter Osterlund: "pktcdvd sets it [block device size] when opening the /dev/pktcdvd device, but when the drive is later opened as /dev/scd0, there is nothing that sets it back. (Btw, 40944 is possible if the disk is a CDRW that was formatted with "cdrwtool -m 10236".) The problem is that pktcdvd opens the cd device in non-blocking mode when pktsetup is run, and doesn't close it again until pktsetup -d is run. The effect is that if you meanwhile open the cd device, blkdev.c:do_open() doesn't call bd_set_size() because bdev->bd_openers is non-zero." In particular, to repeat the bug (regardless of whether commit 6f5391c283d7fdcf24bf40786ea79061919d1e1d is applied or not): " 1. Start with an empty drive. 2. pktsetup 0 /dev/scd0 3. Insert a CD containing an isofs filesystem. 4. mount /dev/pktcdvd/0 /mnt/tmp 5. umount /mnt/tmp 6. Press the eject button. 7. Insert a DVD containing a non-writable filesystem. 8. mount /dev/scd0 /mnt/tmp 9. find /mnt/tmp -type f -print0 | xargs -0 sha1sum >/dev/null 10. If the DVD contains data beyond the physical size of a CD, you get I/O errors in the terminal, and dmesg reports lots of "attempt to access beyond end of device" errors." which in turn is because the nested open after the media change won't cause the size to be set properly (because the original open still holds the block device, and we only do the bd_set_size() when we don't have other people holding the device open). The proper fix for that is probably to just do something like bdev->bd_inode->i_size = (loff_t)get_capacity(disk)<<9; in fs/block_dev.c:do_open() even for the cases where we're not the original opener (but *not* call bd_set_size(), since that will also change the block size of the device). Cc: Peter Osterlund <petero2@telia.com> Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Cc: Matthew Wilcox <matthew@wil.cx> Cc: Ingo Molnar <mingo@elte.hu> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/scsi/scsi.c20
-rw-r--r--drivers/scsi/scsi_error.c1
-rw-r--r--drivers/scsi/scsi_lib.c14
-rw-r--r--drivers/scsi/scsi_priv.h1
-rw-r--r--drivers/scsi/sd.c28
-rw-r--r--drivers/scsi/sr.c21
-rw-r--r--include/scsi/scsi_cmnd.h2
-rw-r--r--include/scsi/scsi_driver.h1
-rw-r--r--include/scsi/sd.h13
9 files changed, 43 insertions, 58 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 7ceb8209e5df..0fb1709ce5e3 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -59,6 +59,7 @@
59#include <scsi/scsi_cmnd.h> 59#include <scsi/scsi_cmnd.h>
60#include <scsi/scsi_dbg.h> 60#include <scsi/scsi_dbg.h>
61#include <scsi/scsi_device.h> 61#include <scsi/scsi_device.h>
62#include <scsi/scsi_driver.h>
62#include <scsi/scsi_eh.h> 63#include <scsi/scsi_eh.h>
63#include <scsi/scsi_host.h> 64#include <scsi/scsi_host.h>
64#include <scsi/scsi_tcq.h> 65#include <scsi/scsi_tcq.h>
@@ -367,9 +368,8 @@ void scsi_log_send(struct scsi_cmnd *cmd)
367 scsi_print_command(cmd); 368 scsi_print_command(cmd);
368 if (level > 3) { 369 if (level > 3) {
369 printk(KERN_INFO "buffer = 0x%p, bufflen = %d," 370 printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
370 " done = 0x%p, queuecommand 0x%p\n", 371 " queuecommand 0x%p\n",
371 scsi_sglist(cmd), scsi_bufflen(cmd), 372 scsi_sglist(cmd), scsi_bufflen(cmd),
372 cmd->done,
373 cmd->device->host->hostt->queuecommand); 373 cmd->device->host->hostt->queuecommand);
374 374
375 } 375 }
@@ -654,6 +654,12 @@ void __scsi_done(struct scsi_cmnd *cmd)
654 blk_complete_request(rq); 654 blk_complete_request(rq);
655} 655}
656 656
657/* Move this to a header if it becomes more generally useful */
658static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
659{
660 return *(struct scsi_driver **)cmd->request->rq_disk->private_data;
661}
662
657/* 663/*
658 * Function: scsi_finish_command 664 * Function: scsi_finish_command
659 * 665 *
@@ -665,6 +671,8 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
665{ 671{
666 struct scsi_device *sdev = cmd->device; 672 struct scsi_device *sdev = cmd->device;
667 struct Scsi_Host *shost = sdev->host; 673 struct Scsi_Host *shost = sdev->host;
674 struct scsi_driver *drv;
675 unsigned int good_bytes;
668 676
669 scsi_device_unbusy(sdev); 677 scsi_device_unbusy(sdev);
670 678
@@ -690,7 +698,13 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
690 "Notifying upper driver of completion " 698 "Notifying upper driver of completion "
691 "(result %x)\n", cmd->result)); 699 "(result %x)\n", cmd->result));
692 700
693 cmd->done(cmd); 701 good_bytes = cmd->request_bufflen;
702 if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) {
703 drv = scsi_cmd_to_driver(cmd);
704 if (drv->done)
705 good_bytes = drv->done(cmd);
706 }
707 scsi_io_completion(cmd, good_bytes);
694} 708}
695EXPORT_SYMBOL(scsi_finish_command); 709EXPORT_SYMBOL(scsi_finish_command);
696 710
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 70700b97c915..ebaca4ca4a13 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1699,7 +1699,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
1699 memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); 1699 memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd));
1700 1700
1701 scmd->scsi_done = scsi_reset_provider_done_command; 1701 scmd->scsi_done = scsi_reset_provider_done_command;
1702 scmd->done = NULL;
1703 scmd->request_buffer = NULL; 1702 scmd->request_buffer = NULL;
1704 scmd->request_bufflen = 0; 1703 scmd->request_bufflen = 0;
1705 1704
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 60f77c4b3946..a9ac5b1b1667 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1092,7 +1092,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
1092 } 1092 }
1093 scsi_end_request(cmd, 0, this_count, !result); 1093 scsi_end_request(cmd, 0, this_count, !result);
1094} 1094}
1095EXPORT_SYMBOL(scsi_io_completion);
1096 1095
1097/* 1096/*
1098 * Function: scsi_init_io() 1097 * Function: scsi_init_io()
@@ -1171,18 +1170,6 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev,
1171 return cmd; 1170 return cmd;
1172} 1171}
1173 1172
1174static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
1175{
1176 BUG_ON(!blk_pc_request(cmd->request));
1177 /*
1178 * This will complete the whole command with uptodate=1 so
1179 * as far as the block layer is concerned the command completed
1180 * successfully. Since this is a REQ_BLOCK_PC command the
1181 * caller should check the request's errors value
1182 */
1183 scsi_io_completion(cmd, cmd->request_bufflen);
1184}
1185
1186int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) 1173int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
1187{ 1174{
1188 struct scsi_cmnd *cmd; 1175 struct scsi_cmnd *cmd;
@@ -1232,7 +1219,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
1232 cmd->transfersize = req->data_len; 1219 cmd->transfersize = req->data_len;
1233 cmd->allowed = req->retries; 1220 cmd->allowed = req->retries;
1234 cmd->timeout_per_command = req->timeout; 1221 cmd->timeout_per_command = req->timeout;
1235 cmd->done = scsi_blk_pc_done;
1236 return BLKPREP_OK; 1222 return BLKPREP_OK;
1237} 1223}
1238EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); 1224EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd);
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 1de52b6ded40..3f34e9376b0a 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -68,6 +68,7 @@ extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
68extern void scsi_device_unbusy(struct scsi_device *sdev); 68extern void scsi_device_unbusy(struct scsi_device *sdev);
69extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); 69extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason);
70extern void scsi_next_command(struct scsi_cmnd *cmd); 70extern void scsi_next_command(struct scsi_cmnd *cmd);
71extern void scsi_io_completion(struct scsi_cmnd *, unsigned int);
71extern void scsi_run_host_queues(struct Scsi_Host *shost); 72extern void scsi_run_host_queues(struct Scsi_Host *shost);
72extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); 73extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev);
73extern void scsi_free_queue(struct request_queue *q); 74extern void scsi_free_queue(struct request_queue *q);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index cb85296d5384..a69b155f39a2 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -86,6 +86,19 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK);
86MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); 86MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD);
87MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); 87MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
88 88
89static int sd_revalidate_disk(struct gendisk *);
90static int sd_probe(struct device *);
91static int sd_remove(struct device *);
92static void sd_shutdown(struct device *);
93static int sd_suspend(struct device *, pm_message_t state);
94static int sd_resume(struct device *);
95static void sd_rescan(struct device *);
96static int sd_done(struct scsi_cmnd *);
97static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
98static void scsi_disk_release(struct class_device *cdev);
99static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
100static void sd_print_result(struct scsi_disk *, int);
101
89static DEFINE_IDR(sd_index_idr); 102static DEFINE_IDR(sd_index_idr);
90static DEFINE_SPINLOCK(sd_index_lock); 103static DEFINE_SPINLOCK(sd_index_lock);
91 104
@@ -240,6 +253,7 @@ static struct scsi_driver sd_template = {
240 .shutdown = sd_shutdown, 253 .shutdown = sd_shutdown,
241 }, 254 },
242 .rescan = sd_rescan, 255 .rescan = sd_rescan,
256 .done = sd_done,
243}; 257};
244 258
245/* 259/*
@@ -509,12 +523,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
509 SCpnt->timeout_per_command = timeout; 523 SCpnt->timeout_per_command = timeout;
510 524
511 /* 525 /*
512 * This is the completion routine we use. This is matched in terms
513 * of capability to this function.
514 */
515 SCpnt->done = sd_rw_intr;
516
517 /*
518 * This indicates that the command is ready from our end to be 526 * This indicates that the command is ready from our end to be
519 * queued. 527 * queued.
520 */ 528 */
@@ -887,13 +895,13 @@ static struct block_device_operations sd_fops = {
887}; 895};
888 896
889/** 897/**
890 * sd_rw_intr - bottom half handler: called when the lower level 898 * sd_done - bottom half handler: called when the lower level
891 * driver has completed (successfully or otherwise) a scsi command. 899 * driver has completed (successfully or otherwise) a scsi command.
892 * @SCpnt: mid-level's per command structure. 900 * @SCpnt: mid-level's per command structure.
893 * 901 *
894 * Note: potentially run from within an ISR. Must not block. 902 * Note: potentially run from within an ISR. Must not block.
895 **/ 903 **/
896static void sd_rw_intr(struct scsi_cmnd * SCpnt) 904static int sd_done(struct scsi_cmnd *SCpnt)
897{ 905{
898 int result = SCpnt->result; 906 int result = SCpnt->result;
899 unsigned int xfer_size = SCpnt->request_bufflen; 907 unsigned int xfer_size = SCpnt->request_bufflen;
@@ -914,7 +922,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
914 SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); 922 SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt));
915 if (sense_valid) { 923 if (sense_valid) {
916 SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, 924 SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt,
917 "sd_rw_intr: sb[respc,sk,asc," 925 "sd_done: sb[respc,sk,asc,"
918 "ascq]=%x,%x,%x,%x\n", 926 "ascq]=%x,%x,%x,%x\n",
919 sshdr.response_code, 927 sshdr.response_code,
920 sshdr.sense_key, sshdr.asc, 928 sshdr.sense_key, sshdr.asc,
@@ -986,7 +994,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
986 break; 994 break;
987 } 995 }
988 out: 996 out:
989 scsi_io_completion(SCpnt, good_bytes); 997 return good_bytes;
990} 998}
991 999
992static int media_not_present(struct scsi_disk *sdkp, 1000static int media_not_present(struct scsi_disk *sdkp,
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index a0c4e13d4dab..c61999031141 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -78,6 +78,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM);
78 78
79static int sr_probe(struct device *); 79static int sr_probe(struct device *);
80static int sr_remove(struct device *); 80static int sr_remove(struct device *);
81static int sr_done(struct scsi_cmnd *);
81 82
82static struct scsi_driver sr_template = { 83static struct scsi_driver sr_template = {
83 .owner = THIS_MODULE, 84 .owner = THIS_MODULE,
@@ -86,6 +87,7 @@ static struct scsi_driver sr_template = {
86 .probe = sr_probe, 87 .probe = sr_probe,
87 .remove = sr_remove, 88 .remove = sr_remove,
88 }, 89 },
90 .done = sr_done,
89}; 91};
90 92
91static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; 93static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG];
@@ -208,12 +210,12 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot)
208} 210}
209 211
210/* 212/*
211 * rw_intr is the interrupt routine for the device driver. 213 * sr_done is the interrupt routine for the device driver.
212 * 214 *
213 * It will be notified on the end of a SCSI read / write, and will take on 215 * It will be notified on the end of a SCSI read / write, and will take one
214 * of several actions based on success or failure. 216 * of several actions based on success or failure.
215 */ 217 */
216static void rw_intr(struct scsi_cmnd * SCpnt) 218static int sr_done(struct scsi_cmnd *SCpnt)
217{ 219{
218 int result = SCpnt->result; 220 int result = SCpnt->result;
219 int this_count = SCpnt->request_bufflen; 221 int this_count = SCpnt->request_bufflen;
@@ -286,12 +288,7 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
286 } 288 }
287 } 289 }
288 290
289 /* 291 return good_bytes;
290 * This calls the generic completion function, now that we know
291 * how many actual sectors finished, and how many sectors we need
292 * to say have failed.
293 */
294 scsi_io_completion(SCpnt, good_bytes);
295} 292}
296 293
297static int sr_prep_fn(struct request_queue *q, struct request *rq) 294static int sr_prep_fn(struct request_queue *q, struct request *rq)
@@ -428,12 +425,6 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
428 SCpnt->timeout_per_command = timeout; 425 SCpnt->timeout_per_command = timeout;
429 426
430 /* 427 /*
431 * This is the completion routine we use. This is matched in terms
432 * of capability to this function.
433 */
434 SCpnt->done = rw_intr;
435
436 /*
437 * This indicates that the command is ready from our end to be 428 * This indicates that the command is ready from our end to be
438 * queued. 429 * queued.
439 */ 430 */
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 7613c2989370..3f47e522a1ec 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -34,7 +34,6 @@ struct scsi_cmnd {
34 struct list_head list; /* scsi_cmnd participates in queue lists */ 34 struct list_head list; /* scsi_cmnd participates in queue lists */
35 struct list_head eh_entry; /* entry for the host eh_cmd_q */ 35 struct list_head eh_entry; /* entry for the host eh_cmd_q */
36 int eh_eflags; /* Used by error handlr */ 36 int eh_eflags; /* Used by error handlr */
37 void (*done) (struct scsi_cmnd *); /* Mid-level done function */
38 37
39 /* 38 /*
40 * A SCSI Command is assigned a nonzero serial_number before passed 39 * A SCSI Command is assigned a nonzero serial_number before passed
@@ -122,7 +121,6 @@ extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t);
122extern void scsi_put_command(struct scsi_cmnd *); 121extern void scsi_put_command(struct scsi_cmnd *);
123extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *, 122extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *,
124 struct device *); 123 struct device *);
125extern void scsi_io_completion(struct scsi_cmnd *, unsigned int);
126extern void scsi_finish_command(struct scsi_cmnd *cmd); 124extern void scsi_finish_command(struct scsi_cmnd *cmd);
127extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd); 125extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd);
128 126
diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h
index 56a304709fde..1f5ca7f62116 100644
--- a/include/scsi/scsi_driver.h
+++ b/include/scsi/scsi_driver.h
@@ -15,6 +15,7 @@ struct scsi_driver {
15 struct device_driver gendrv; 15 struct device_driver gendrv;
16 16
17 void (*rescan)(struct device *); 17 void (*rescan)(struct device *);
18 int (*done)(struct scsi_cmnd *);
18}; 19};
19#define to_scsi_driver(drv) \ 20#define to_scsi_driver(drv) \
20 container_of((drv), struct scsi_driver, gendrv) 21 container_of((drv), struct scsi_driver, gendrv)
diff --git a/include/scsi/sd.h b/include/scsi/sd.h
index aa1e71613010..f7513313ef0d 100644
--- a/include/scsi/sd.h
+++ b/include/scsi/sd.h
@@ -47,19 +47,6 @@ struct scsi_disk {
47}; 47};
48#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev) 48#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev)
49 49
50static int sd_revalidate_disk(struct gendisk *disk);
51static void sd_rw_intr(struct scsi_cmnd * SCpnt);
52static int sd_probe(struct device *);
53static int sd_remove(struct device *);
54static void sd_shutdown(struct device *dev);
55static int sd_suspend(struct device *dev, pm_message_t state);
56static int sd_resume(struct device *dev);
57static void sd_rescan(struct device *);
58static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
59static void scsi_disk_release(struct class_device *cdev);
60static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
61static void sd_print_result(struct scsi_disk *, int);
62
63#define sd_printk(prefix, sdsk, fmt, a...) \ 50#define sd_printk(prefix, sdsk, fmt, a...) \
64 (sdsk)->disk ? \ 51 (sdsk)->disk ? \
65 sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \ 52 sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \