[BLOCK] scsi: add FUA support to sd
Add FUA support for barriers to SCSI disk. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jens Axboe <axboe@suse.de>
This commit is contained in:
Родитель
461d4e90c8
Коммит
007365ad60
|
@ -102,6 +102,7 @@ struct scsi_disk {
|
|||
u8 write_prot;
|
||||
unsigned WCE : 1; /* state of disk WCE bit */
|
||||
unsigned RCD : 1; /* state of disk RCD bit, unused */
|
||||
unsigned DPOFUA : 1; /* state of disk DPOFUA bit */
|
||||
};
|
||||
|
||||
static DEFINE_IDR(sd_index_idr);
|
||||
|
@ -343,6 +344,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|||
|
||||
if (block > 0xffffffff) {
|
||||
SCpnt->cmnd[0] += READ_16 - READ_6;
|
||||
SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0;
|
||||
SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0;
|
||||
SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0;
|
||||
SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0;
|
||||
|
@ -362,6 +364,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|||
this_count = 0xffff;
|
||||
|
||||
SCpnt->cmnd[0] += READ_10 - READ_6;
|
||||
SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0;
|
||||
SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
|
||||
SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff;
|
||||
SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff;
|
||||
|
@ -370,6 +373,17 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|||
SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff;
|
||||
SCpnt->cmnd[8] = (unsigned char) this_count & 0xff;
|
||||
} else {
|
||||
if (unlikely(blk_fua_rq(rq))) {
|
||||
/*
|
||||
* This happens only if this drive failed
|
||||
* 10byte rw command with ILLEGAL_REQUEST
|
||||
* during operation and thus turned off
|
||||
* use_10_for_rw.
|
||||
*/
|
||||
printk(KERN_ERR "sd: FUA write on READ/WRITE(6) drive\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f);
|
||||
SCpnt->cmnd[2] = (unsigned char) ((block >> 8) & 0xff);
|
||||
SCpnt->cmnd[3] = (unsigned char) block & 0xff;
|
||||
|
@ -1395,10 +1409,18 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
|
|||
sdkp->RCD = 0;
|
||||
}
|
||||
|
||||
sdkp->DPOFUA = (data.device_specific & 0x10) != 0;
|
||||
if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) {
|
||||
printk(KERN_NOTICE "SCSI device %s: uses "
|
||||
"READ/WRITE(6), disabling FUA\n", diskname);
|
||||
sdkp->DPOFUA = 0;
|
||||
}
|
||||
|
||||
ct = sdkp->RCD + 2*sdkp->WCE;
|
||||
|
||||
printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n",
|
||||
diskname, types[ct]);
|
||||
printk(KERN_NOTICE "SCSI device %s: drive cache: %s%s\n",
|
||||
diskname, types[ct],
|
||||
sdkp->DPOFUA ? " w/ FUA" : "");
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1475,7 +1497,8 @@ static int sd_revalidate_disk(struct gendisk *disk)
|
|||
* QUEUE_ORDERED_TAG_* even when ordered tag is supported.
|
||||
*/
|
||||
if (sdkp->WCE)
|
||||
ordered = QUEUE_ORDERED_DRAIN_FLUSH;
|
||||
ordered = sdkp->DPOFUA
|
||||
? QUEUE_ORDERED_DRAIN_FUA : QUEUE_ORDERED_DRAIN_FLUSH;
|
||||
else
|
||||
ordered = QUEUE_ORDERED_DRAIN;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче