]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.36.4/fix-medium-error-problems-with-some-arrays-which-can-cause-data-corruption.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.36.4 / fix-medium-error-problems-with-some-arrays-which-can-cause-data-corruption.patch
CommitLineData
e2b52abc
GKH
1From a8733c7baf457b071528e385a0b7d4aaec79287c Mon Sep 17 00:00:00 2001
2From: James Bottomley <James.Bottomley@suse.de>
3Date: Fri, 17 Dec 2010 15:36:34 -0500
4Subject: [SCSI] fix medium error problems with some arrays which can cause data corruption
5
6From: James Bottomley <James.Bottomley@suse.de>
7
8commit a8733c7baf457b071528e385a0b7d4aaec79287c upstream.
9
10Our current handling of medium error assumes that data is returned up
11to the bad sector. This assumption holds good for all disk devices,
12all DIF arrays and most ordinary arrays. However, an LSI array engine
13was recently discovered which reports a medium error without returning
14any data. This means that when we report good data up to the medium
15error, we've reported junk originally in the buffer as good. Worse,
16if the read consists of requested data plus a readahead, and the error
17occurs in readahead, we'll just strip off the readahead and report
18junk up to userspace as good data with no error.
19
20The fix for this is to have the error position computation take into
21account the amount of data returned by the driver using the scsi
22residual data. Unfortunately, not every driver fills in this data,
23but for those who don't, it's set to zero, which means we'll think a
24full set of data was transferred and the behaviour will be identical
25to the prior behaviour of the code (believe the buffer up to the error
26sector). All modern drivers seem to set the residual, so that should
27fix up the LSI failure/corruption case.
28
29Reported-by: Douglas Gilbert <dgilbert@interlog.com>
30Signed-off-by: James Bottomley <James.Bottomley@suse.de>
31Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
32
33---
34 drivers/scsi/sd.c | 9 ++++++++-
35 1 file changed, 8 insertions(+), 1 deletion(-)
36
37--- a/drivers/scsi/sd.c
38+++ b/drivers/scsi/sd.c
39@@ -1153,6 +1153,12 @@ static unsigned int sd_completed_bytes(s
40 u64 end_lba = blk_rq_pos(scmd->request) + (scsi_bufflen(scmd) / 512);
41 u64 bad_lba;
42 int info_valid;
43+ /*
44+ * resid is optional but mostly filled in. When it's unused,
45+ * its value is zero, so we assume the whole buffer transferred
46+ */
47+ unsigned int transferred = scsi_bufflen(scmd) - scsi_get_resid(scmd);
48+ unsigned int good_bytes;
49
50 if (scmd->request->cmd_type != REQ_TYPE_FS)
51 return 0;
52@@ -1186,7 +1192,8 @@ static unsigned int sd_completed_bytes(s
53 /* This computation should always be done in terms of
54 * the resolution of the device's medium.
55 */
56- return (bad_lba - start_lba) * scmd->device->sector_size;
57+ good_bytes = (bad_lba - start_lba) * scmd->device->sector_size;
58+ return min(good_bytes, transferred);
59 }
60
61 /**