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>
This commit is contained in:
parent
885fa13f65
commit
02d261034f
|
@ -735,7 +735,7 @@ static int sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
|
||||||
return scsi_init_io(cmd);
|
return scsi_init_io(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd)
|
static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd, bool unmap)
|
||||||
{
|
{
|
||||||
struct scsi_device *sdp = cmd->device;
|
struct scsi_device *sdp = cmd->device;
|
||||||
struct request *rq = cmd->request;
|
struct request *rq = cmd->request;
|
||||||
|
@ -752,13 +752,14 @@ static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd)
|
||||||
|
|
||||||
cmd->cmd_len = 16;
|
cmd->cmd_len = 16;
|
||||||
cmd->cmnd[0] = WRITE_SAME_16;
|
cmd->cmnd[0] = WRITE_SAME_16;
|
||||||
cmd->cmnd[1] = 0x8; /* UNMAP */
|
if (unmap)
|
||||||
|
cmd->cmnd[1] = 0x8; /* UNMAP */
|
||||||
put_unaligned_be64(sector, &cmd->cmnd[2]);
|
put_unaligned_be64(sector, &cmd->cmnd[2]);
|
||||||
put_unaligned_be32(nr_sectors, &cmd->cmnd[10]);
|
put_unaligned_be32(nr_sectors, &cmd->cmnd[10]);
|
||||||
|
|
||||||
cmd->allowed = SD_MAX_RETRIES;
|
cmd->allowed = SD_MAX_RETRIES;
|
||||||
cmd->transfersize = data_len;
|
cmd->transfersize = data_len;
|
||||||
rq->timeout = SD_TIMEOUT;
|
rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT;
|
||||||
scsi_req(rq)->resid_len = data_len;
|
scsi_req(rq)->resid_len = data_len;
|
||||||
|
|
||||||
return scsi_init_io(cmd);
|
return scsi_init_io(cmd);
|
||||||
|
@ -788,12 +789,27 @@ static int sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd, bool unmap)
|
||||||
|
|
||||||
cmd->allowed = SD_MAX_RETRIES;
|
cmd->allowed = SD_MAX_RETRIES;
|
||||||
cmd->transfersize = data_len;
|
cmd->transfersize = data_len;
|
||||||
rq->timeout = SD_TIMEOUT;
|
rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT;
|
||||||
scsi_req(rq)->resid_len = data_len;
|
scsi_req(rq)->resid_len = data_len;
|
||||||
|
|
||||||
return scsi_init_io(cmd);
|
return scsi_init_io(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd)
|
||||||
|
{
|
||||||
|
struct request *rq = cmd->request;
|
||||||
|
struct scsi_device *sdp = cmd->device;
|
||||||
|
struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
|
||||||
|
u64 sector = blk_rq_pos(rq) >> (ilog2(sdp->sector_size) - 9);
|
||||||
|
u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
|
||||||
|
|
||||||
|
if (sdp->no_write_same)
|
||||||
|
return BLKPREP_INVALID;
|
||||||
|
if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff)
|
||||||
|
return sd_setup_write_same16_cmnd(cmd, false);
|
||||||
|
return sd_setup_write_same10_cmnd(cmd, false);
|
||||||
|
}
|
||||||
|
|
||||||
static void sd_config_write_same(struct scsi_disk *sdkp)
|
static void sd_config_write_same(struct scsi_disk *sdkp)
|
||||||
{
|
{
|
||||||
struct request_queue *q = sdkp->disk->queue;
|
struct request_queue *q = sdkp->disk->queue;
|
||||||
|
@ -823,6 +839,8 @@ static void sd_config_write_same(struct scsi_disk *sdkp)
|
||||||
out:
|
out:
|
||||||
blk_queue_max_write_same_sectors(q, sdkp->max_ws_blocks *
|
blk_queue_max_write_same_sectors(q, sdkp->max_ws_blocks *
|
||||||
(logical_block_size >> 9));
|
(logical_block_size >> 9));
|
||||||
|
blk_queue_max_write_zeroes_sectors(q, sdkp->max_ws_blocks *
|
||||||
|
(logical_block_size >> 9));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1163,7 +1181,7 @@ static int sd_init_command(struct scsi_cmnd *cmd)
|
||||||
case SD_LBP_UNMAP:
|
case SD_LBP_UNMAP:
|
||||||
return sd_setup_unmap_cmnd(cmd);
|
return sd_setup_unmap_cmnd(cmd);
|
||||||
case SD_LBP_WS16:
|
case SD_LBP_WS16:
|
||||||
return sd_setup_write_same16_cmnd(cmd);
|
return sd_setup_write_same16_cmnd(cmd, true);
|
||||||
case SD_LBP_WS10:
|
case SD_LBP_WS10:
|
||||||
return sd_setup_write_same10_cmnd(cmd, true);
|
return sd_setup_write_same10_cmnd(cmd, true);
|
||||||
case SD_LBP_ZERO:
|
case SD_LBP_ZERO:
|
||||||
|
@ -1171,6 +1189,8 @@ static int sd_init_command(struct scsi_cmnd *cmd)
|
||||||
default:
|
default:
|
||||||
return BLKPREP_INVALID;
|
return BLKPREP_INVALID;
|
||||||
}
|
}
|
||||||
|
case REQ_OP_WRITE_ZEROES:
|
||||||
|
return sd_setup_write_zeroes_cmnd(cmd);
|
||||||
case REQ_OP_WRITE_SAME:
|
case REQ_OP_WRITE_SAME:
|
||||||
return sd_setup_write_same_cmnd(cmd);
|
return sd_setup_write_same_cmnd(cmd);
|
||||||
case REQ_OP_FLUSH:
|
case REQ_OP_FLUSH:
|
||||||
|
@ -1810,6 +1830,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
|
||||||
|
|
||||||
switch (req_op(req)) {
|
switch (req_op(req)) {
|
||||||
case REQ_OP_DISCARD:
|
case REQ_OP_DISCARD:
|
||||||
|
case REQ_OP_WRITE_ZEROES:
|
||||||
case REQ_OP_WRITE_SAME:
|
case REQ_OP_WRITE_SAME:
|
||||||
case REQ_OP_ZONE_RESET:
|
case REQ_OP_ZONE_RESET:
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|
|
@ -329,6 +329,7 @@ void sd_zbc_complete(struct scsi_cmnd *cmd,
|
||||||
|
|
||||||
switch (req_op(rq)) {
|
switch (req_op(rq)) {
|
||||||
case REQ_OP_WRITE:
|
case REQ_OP_WRITE:
|
||||||
|
case REQ_OP_WRITE_ZEROES:
|
||||||
case REQ_OP_WRITE_SAME:
|
case REQ_OP_WRITE_SAME:
|
||||||
case REQ_OP_ZONE_RESET:
|
case REQ_OP_ZONE_RESET:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue