summaryrefslogtreecommitdiff
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2014-04-16 21:37:30 -0600
committerJens Axboe <axboe@fb.com>2014-04-16 21:37:30 -0600
commitdc4a93078b8a6a10d2dcaba76ab488d6dbe73922 (patch)
treecee24991c2d4fa7d6ad6e2be790fde880c0223ed /drivers/scsi/sd.c
parentfb1be43301ce045b5e563416e701573464a2ed96 (diff)
sd/skd: stuff discard page in request->completion_data
Store the pointer to the page there, so we can always safely reference it from end_io context where ->bio may have been cleared. Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 06d154d20faa..96af195224f2 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -737,6 +737,7 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
goto out;
}
+ rq->completion_data = page;
blk_add_request_payload(rq, page, len);
ret = scsi_setup_blk_pc_cmnd(sdp, rq);
rq->__data_len = nr_bytes;
@@ -839,11 +840,9 @@ static void sd_unprep_fn(struct request_queue *q, struct request *rq)
{
struct scsi_cmnd *SCpnt = rq->special;
- if (rq->cmd_flags & REQ_DISCARD) {
- struct bio *bio = rq->bio;
+ if (rq->cmd_flags & REQ_DISCARD)
+ __free_page(rq->completion_data);
- __free_page(bio->bi_io_vec->bv_page);
- }
if (SCpnt->cmnd != rq->cmd) {
mempool_free(SCpnt->cmnd, sd_cdb_pool);
SCpnt->cmnd = NULL;