aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
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 /drivers/scsi/sd.c
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>
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c28
1 files changed, 18 insertions, 10 deletions
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,