aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2005-09-02 13:13:54 +1000
committerJames Bottomley <jejb@mulgrave.(none)>2005-09-09 10:29:22 -0500
commit286f3e13a1dc7f32407629fbd7aabc8ea78c62b5 (patch)
tree2ccc7b80111e1aac738ac67528ea3d53ac54ff0a
parent903f4fed858a7b56b260cbd55d174fe54d188fb7 (diff)
downloadkernel_samsung_espresso10-286f3e13a1dc7f32407629fbd7aabc8ea78c62b5.zip
kernel_samsung_espresso10-286f3e13a1dc7f32407629fbd7aabc8ea78c62b5.tar.gz
kernel_samsung_espresso10-286f3e13a1dc7f32407629fbd7aabc8ea78c62b5.tar.bz2
[SCSI] fix possible deadlock in scsi_lib.c
If a filesystem, while writing out data, decides that it is good to issue a cache flush on a SCSI drive (or other 'sd' device), it will call blkdev_issue_flush which calls ->issue_flush_fn which is scsi_issue_flush_fn. This calls sd_issue_flush which calls sd_sync_cache, which calls scsi_execute_request. This will (as sshdr != NULL) call kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL) If memory is tight, the presence of GFP_KERNEL may cause write requests to be sent to some filesystem to free up memory, however if that filesystem is waiting for the issue_flush_fn to complete, you could get a deadlock. I wonder if it might be more appropriate to use GFP_NOIO as in the following patch. I wonder if it might be even more appropriate to cope better with a kmalloc failure, especially as in this use, sd_sync_cache only will use the sense information to print out a more informative error message. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/scsi_lib.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 77f2d44..2ad60f1 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -339,7 +339,7 @@ int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
int result;
if (sshdr) {
- sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
+ sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
if (!sense)
return DRIVER_ERROR << 24;
memset(sense, 0, SCSI_SENSE_BUFFERSIZE);