diff options
author | Christoph Hellwig <hch@lst.de> | 2017-04-05 13:21:02 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-04-08 13:25:38 -0400 |
commit | 02d261034f1c90ac8b052406bd7b18d2564b0b3c (patch) | |
tree | 430a04c1096eae066f99997953f7aefed4d668f5 | |
parent | 885fa13f655940c73787b7fcd4c78813943ece8a (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.c | 31 | ||||
-rw-r--r-- | drivers/scsi/sd_zbc.c | 1 |
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 | ||
738 | static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd) | 738 | static 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 | ||
798 | static 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 | |||
797 | static void sd_config_write_same(struct scsi_disk *sdkp) | 813 | static 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) | |||
823 | out: | 839 | out: |
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 | ||