@@ -831,6 +831,19 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
blk_queue_max_discard_sectors(q, max_blocks * (logical_block_size >> 9));
}
+static void *sd_set_special_bvec(struct request *rq, unsigned int data_len)
+{
+ struct page *page;
+
+ page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
+ if (!page)
+ return NULL;
+ clear_highpage(page);
+ bvec_set_page(&rq->special_vec, page, data_len, 0);
+ rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
+ return bvec_virt(&rq->special_vec);
+}
+
static blk_status_t sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
{
struct scsi_device *sdp = cmd->device;
@@ -841,19 +854,14 @@ static blk_status_t sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
unsigned int data_len = 24;
char *buf;
- rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
- if (!rq->special_vec.bv_page)
+ buf = sd_set_special_bvec(rq, data_len);
+ if (!buf)
return BLK_STS_RESOURCE;
- clear_highpage(rq->special_vec.bv_page);
- rq->special_vec.bv_offset = 0;
- rq->special_vec.bv_len = data_len;
- rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
cmd->cmd_len = 10;
cmd->cmnd[0] = UNMAP;
cmd->cmnd[8] = 24;
- buf = bvec_virt(&rq->special_vec);
put_unaligned_be16(6 + 16, &buf[0]);
put_unaligned_be16(16, &buf[2]);
put_unaligned_be64(lba, &buf[8]);
@@ -876,13 +884,8 @@ static blk_status_t sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd,
u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
u32 data_len = sdp->sector_size;
- rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
- if (!rq->special_vec.bv_page)
+ if (!sd_set_special_bvec(rq, data_len))
return BLK_STS_RESOURCE;
- clear_highpage(rq->special_vec.bv_page);
- rq->special_vec.bv_offset = 0;
- rq->special_vec.bv_len = data_len;
- rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
cmd->cmd_len = 16;
cmd->cmnd[0] = WRITE_SAME_16;
@@ -908,13 +911,8 @@ static blk_status_t sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd,
u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
u32 data_len = sdp->sector_size;
- rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
- if (!rq->special_vec.bv_page)
+ if (!sd_set_special_bvec(rq, data_len))
return BLK_STS_RESOURCE;
- clear_highpage(rq->special_vec.bv_page);
- rq->special_vec.bv_offset = 0;
- rq->special_vec.bv_len = data_len;
- rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
cmd->cmd_len = 10;
cmd->cmnd[0] = WRITE_SAME;
Add a helper for setting up the special_bvec instead of open coding it in three place, and use the new bvec_set_page helper to initialize special_vec. Signed-off-by: Christoph Hellwig <hch@lst.de> --- drivers/scsi/sd.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-)