diff options
author | Christoph Hellwig <hch@lst.de> | 2014-06-28 06:35:13 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-07-17 16:16:26 -0400 |
commit | 6a7b43985daa4f42b6d6f0186594c3a68f84a1d8 (patch) | |
tree | e6eb9a0fde65de834d2693ca6f0e108f87d34b06 | |
parent | 59b1134c5a2aab2c70725af83d2e2d1c71c509ca (diff) |
sd: don't use scsi_setup_blk_pc_cmnd for discard requests
Simplify handling of discard requests by setting up the command directly
instead of initializing request fields and then calling
scsi_setup_blk_pc_cmnd to propagate the information into the command.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
-rw-r--r-- | drivers/scsi/sd.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index aefedf4fbb2b..03bed86b9fc9 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -691,8 +691,10 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) | |||
691 | * Will issue either UNMAP or WRITE SAME(16) depending on preference | 691 | * Will issue either UNMAP or WRITE SAME(16) depending on preference |
692 | * indicated by target device. | 692 | * indicated by target device. |
693 | **/ | 693 | **/ |
694 | static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | 694 | static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd) |
695 | { | 695 | { |
696 | struct request *rq = cmd->request; | ||
697 | struct scsi_device *sdp = cmd->device; | ||
696 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); | 698 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); |
697 | sector_t sector = blk_rq_pos(rq); | 699 | sector_t sector = blk_rq_pos(rq); |
698 | unsigned int nr_sectors = blk_rq_sectors(rq); | 700 | unsigned int nr_sectors = blk_rq_sectors(rq); |
@@ -704,9 +706,6 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
704 | 706 | ||
705 | sector >>= ilog2(sdp->sector_size) - 9; | 707 | sector >>= ilog2(sdp->sector_size) - 9; |
706 | nr_sectors >>= ilog2(sdp->sector_size) - 9; | 708 | nr_sectors >>= ilog2(sdp->sector_size) - 9; |
707 | rq->timeout = SD_TIMEOUT; | ||
708 | |||
709 | memset(rq->cmd, 0, rq->cmd_len); | ||
710 | 709 | ||
711 | page = alloc_page(GFP_ATOMIC | __GFP_ZERO); | 710 | page = alloc_page(GFP_ATOMIC | __GFP_ZERO); |
712 | if (!page) | 711 | if (!page) |
@@ -716,9 +715,9 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
716 | case SD_LBP_UNMAP: | 715 | case SD_LBP_UNMAP: |
717 | buf = page_address(page); | 716 | buf = page_address(page); |
718 | 717 | ||
719 | rq->cmd_len = 10; | 718 | cmd->cmd_len = 10; |
720 | rq->cmd[0] = UNMAP; | 719 | cmd->cmnd[0] = UNMAP; |
721 | rq->cmd[8] = 24; | 720 | cmd->cmnd[8] = 24; |
722 | 721 | ||
723 | put_unaligned_be16(6 + 16, &buf[0]); | 722 | put_unaligned_be16(6 + 16, &buf[0]); |
724 | put_unaligned_be16(16, &buf[2]); | 723 | put_unaligned_be16(16, &buf[2]); |
@@ -729,23 +728,23 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
729 | break; | 728 | break; |
730 | 729 | ||
731 | case SD_LBP_WS16: | 730 | case SD_LBP_WS16: |
732 | rq->cmd_len = 16; | 731 | cmd->cmd_len = 16; |
733 | rq->cmd[0] = WRITE_SAME_16; | 732 | cmd->cmnd[0] = WRITE_SAME_16; |
734 | rq->cmd[1] = 0x8; /* UNMAP */ | 733 | cmd->cmnd[1] = 0x8; /* UNMAP */ |
735 | put_unaligned_be64(sector, &rq->cmd[2]); | 734 | put_unaligned_be64(sector, &cmd->cmnd[2]); |
736 | put_unaligned_be32(nr_sectors, &rq->cmd[10]); | 735 | put_unaligned_be32(nr_sectors, &cmd->cmnd[10]); |
737 | 736 | ||
738 | len = sdkp->device->sector_size; | 737 | len = sdkp->device->sector_size; |
739 | break; | 738 | break; |
740 | 739 | ||
741 | case SD_LBP_WS10: | 740 | case SD_LBP_WS10: |
742 | case SD_LBP_ZERO: | 741 | case SD_LBP_ZERO: |
743 | rq->cmd_len = 10; | 742 | cmd->cmd_len = 10; |
744 | rq->cmd[0] = WRITE_SAME; | 743 | cmd->cmnd[0] = WRITE_SAME; |
745 | if (sdkp->provisioning_mode == SD_LBP_WS10) | 744 | if (sdkp->provisioning_mode == SD_LBP_WS10) |
746 | rq->cmd[1] = 0x8; /* UNMAP */ | 745 | cmd->cmnd[1] = 0x8; /* UNMAP */ |
747 | put_unaligned_be32(sector, &rq->cmd[2]); | 746 | put_unaligned_be32(sector, &cmd->cmnd[2]); |
748 | put_unaligned_be16(nr_sectors, &rq->cmd[7]); | 747 | put_unaligned_be16(nr_sectors, &cmd->cmnd[7]); |
749 | 748 | ||
750 | len = sdkp->device->sector_size; | 749 | len = sdkp->device->sector_size; |
751 | break; | 750 | break; |
@@ -756,8 +755,21 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
756 | } | 755 | } |
757 | 756 | ||
758 | rq->completion_data = page; | 757 | rq->completion_data = page; |
758 | rq->timeout = SD_TIMEOUT; | ||
759 | |||
760 | cmd->transfersize = len; | ||
761 | cmd->allowed = rq->retries; | ||
762 | |||
763 | /* | ||
764 | * Initially __data_len is set to the amount of data that needs to be | ||
765 | * transferred to the target. This amount depends on whether WRITE SAME | ||
766 | * or UNMAP is being used. After the scatterlist has been mapped by | ||
767 | * scsi_init_io() we set __data_len to the size of the area to be | ||
768 | * discarded on disk. This allows us to report completion on the full | ||
769 | * amount of blocks described by the request. | ||
770 | */ | ||
759 | blk_add_request_payload(rq, page, len); | 771 | blk_add_request_payload(rq, page, len); |
760 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | 772 | ret = scsi_init_io(cmd, GFP_ATOMIC); |
761 | rq->__data_len = nr_bytes; | 773 | rq->__data_len = nr_bytes; |
762 | 774 | ||
763 | out: | 775 | out: |
@@ -903,7 +915,7 @@ static int sd_init_command(struct scsi_cmnd *SCpnt) | |||
903 | * block PC requests to make life easier. | 915 | * block PC requests to make life easier. |
904 | */ | 916 | */ |
905 | if (rq->cmd_flags & REQ_DISCARD) { | 917 | if (rq->cmd_flags & REQ_DISCARD) { |
906 | ret = sd_setup_discard_cmnd(sdp, rq); | 918 | ret = sd_setup_discard_cmnd(SCpnt); |
907 | goto out; | 919 | goto out; |
908 | } else if (rq->cmd_flags & REQ_WRITE_SAME) { | 920 | } else if (rq->cmd_flags & REQ_WRITE_SAME) { |
909 | ret = sd_setup_write_same_cmnd(SCpnt); | 921 | ret = sd_setup_write_same_cmnd(SCpnt); |