]> git.ipfire.org Git - thirdparty/linux.git/blobdiff - drivers/scsi/sd.c
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[thirdparty/linux.git] / drivers / scsi / sd.c
index 2aa3b0393b96a6ac937d2404629154e44a4db712..a38c71511bc94b7a8637eb4a2d81471edc3b2ce3 100644 (file)
@@ -834,6 +834,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;
@@ -844,19 +857,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]);
@@ -879,13 +887,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;
@@ -911,13 +914,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;