aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2017-04-05 13:21:02 -0400
committerJens Axboe <axboe@fb.com>2017-04-08 13:25:38 -0400
commit02d261034f1c90ac8b052406bd7b18d2564b0b3c (patch)
tree430a04c1096eae066f99997953f7aefed4d668f5
parent885fa13f655940c73787b7fcd4c78813943ece8a (diff)
sd: implement REQ_OP_WRITE_ZEROES
Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/scsi/sd.c31
-rw-r--r--drivers/scsi/sd_zbc.c1
2 files changed, 27 insertions, 5 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b853f91fb3da..d8d9c0bdd93c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -735,7 +735,7 @@ static int sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
735 return scsi_init_io(cmd); 735 return scsi_init_io(cmd);
736} 736}
737 737
738static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd) 738static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd, bool unmap)
739{ 739{
740 struct scsi_device *sdp = cmd->device; 740 struct scsi_device *sdp = cmd->device;
741 struct request *rq = cmd->request; 741 struct request *rq = cmd->request;
@@ -752,13 +752,14 @@ static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd)
752 752
753 cmd->cmd_len = 16; 753 cmd->cmd_len = 16;
754 cmd->cmnd[0] = WRITE_SAME_16; 754 cmd->cmnd[0] = WRITE_SAME_16;
755 cmd->cmnd[1] = 0x8; /* UNMAP */ 755 if (unmap)
756 cmd->cmnd[1] = 0x8; /* UNMAP */
756 put_unaligned_be64(sector, &cmd->cmnd[2]); 757 put_unaligned_be64(sector, &cmd->cmnd[2]);
757 put_unaligned_be32(nr_sectors, &cmd->cmnd[10]); 758 put_unaligned_be32(nr_sectors, &cmd->cmnd[10]);
758 759
759 cmd->allowed = SD_MAX_RETRIES; 760 cmd->allowed = SD_MAX_RETRIES;
760 cmd->transfersize = data_len; 761 cmd->transfersize = data_len;
761 rq->timeout = SD_TIMEOUT; 762 rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT;
762 scsi_req(rq)->resid_len = data_len; 763 scsi_req(rq)->resid_len = data_len;
763 764
764 return scsi_init_io(cmd); 765 return scsi_init_io(cmd);
@@ -788,12 +789,27 @@ static int sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd, bool unmap)
788 789
789 cmd->allowed = SD_MAX_RETRIES; 790 cmd->allowed = SD_MAX_RETRIES;
790 cmd->transfersize = data_len; 791 cmd->transfersize = data_len;
791 rq->timeout = SD_TIMEOUT; 792 rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT;
792 scsi_req(rq)->resid_len = data_len; 793 scsi_req(rq)->resid_len = data_len;
793 794
794 return scsi_init_io(cmd); 795 return scsi_init_io(cmd);
795} 796}
796 797
798static int sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd)
799{
800 struct request *rq = cmd->request;
801 struct scsi_device *sdp = cmd->device;
802 struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
803 u64 sector = blk_rq_pos(rq) >> (ilog2(sdp->sector_size) - 9);
804 u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
805
806 if (sdp->no_write_same)
807 return BLKPREP_INVALID;
808 if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff)
809 return sd_setup_write_same16_cmnd(cmd, false);
810 return sd_setup_write_same10_cmnd(cmd, false);
811}
812
797static void sd_config_write_same(struct scsi_disk *sdkp) 813static void sd_config_write_same(struct scsi_disk *sdkp)
798{ 814{
799 struct request_queue *q = sdkp->disk->queue; 815 struct request_queue *q = sdkp->disk->queue;
@@ -823,6 +839,8 @@ static void sd_config_write_same(struct scsi_disk *sdkp)
823out: 839out:
824 blk_queue_max_write_same_sectors(q, sdkp->max_ws_blocks * 840 blk_queue_max_write_same_sectors(q, sdkp->max_ws_blocks *
825 (logical_block_size >> 9)); 841 (logical_block_size >> 9));
842 blk_queue_max_write_zeroes_sectors(q, sdkp->max_ws_blocks *
843 (logical_block_size >> 9));
826} 844}
827 845
828/** 846/**
@@ -1163,7 +1181,7 @@ static int sd_init_command(struct scsi_cmnd *cmd)
1163 case SD_LBP_UNMAP: 1181 case SD_LBP_UNMAP:
1164 return sd_setup_unmap_cmnd(cmd); 1182 return sd_setup_unmap_cmnd(cmd);
1165 case SD_LBP_WS16: 1183 case SD_LBP_WS16:
1166 return sd_setup_write_same16_cmnd(cmd); 1184 return sd_setup_write_same16_cmnd(cmd, true);
1167 case SD_LBP_WS10: 1185 case SD_LBP_WS10:
1168 return sd_setup_write_same10_cmnd(cmd, true); 1186 return sd_setup_write_same10_cmnd(cmd, true);
1169 case SD_LBP_ZERO: 1187 case SD_LBP_ZERO:
@@ -1171,6 +1189,8 @@ static int sd_init_command(struct scsi_cmnd *cmd)
1171 default: 1189 default:
1172 return BLKPREP_INVALID; 1190 return BLKPREP_INVALID;
1173 } 1191 }
1192 case REQ_OP_WRITE_ZEROES:
1193 return sd_setup_write_zeroes_cmnd(cmd);
1174 case REQ_OP_WRITE_SAME: 1194 case REQ_OP_WRITE_SAME:
1175 return sd_setup_write_same_cmnd(cmd); 1195 return sd_setup_write_same_cmnd(cmd);
1176 case REQ_OP_FLUSH: 1196 case REQ_OP_FLUSH:
@@ -1810,6 +1830,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
1810 1830
1811 switch (req_op(req)) { 1831 switch (req_op(req)) {
1812 case REQ_OP_DISCARD: 1832 case REQ_OP_DISCARD:
1833 case REQ_OP_WRITE_ZEROES:
1813 case REQ_OP_WRITE_SAME: 1834 case REQ_OP_WRITE_SAME:
1814 case REQ_OP_ZONE_RESET: 1835 case REQ_OP_ZONE_RESET:
1815 if (!result) { 1836 if (!result) {
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index 92620c8ea8ad..1994f7799fce 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -329,6 +329,7 @@ void sd_zbc_complete(struct scsi_cmnd *cmd,
329 329
330 switch (req_op(rq)) { 330 switch (req_op(rq)) {
331 case REQ_OP_WRITE: 331 case REQ_OP_WRITE:
332 case REQ_OP_WRITE_ZEROES:
332 case REQ_OP_WRITE_SAME: 333 case REQ_OP_WRITE_SAME:
333 case REQ_OP_ZONE_RESET: 334 case REQ_OP_ZONE_RESET:
334 335