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>
This commit is contained in:
Jens Axboe 2014-04-16 21:37:30 -06:00
parent fb1be43301
commit dc4a93078b
2 changed files with 5 additions and 6 deletions

View File

@ -743,6 +743,7 @@ static void skd_request_fn(struct request_queue *q)
break; break;
} }
skreq->discard_page = 1; skreq->discard_page = 1;
req->completion_data = page;
skd_prep_discard_cdb(scsi_req, skreq, page, lba, count); skd_prep_discard_cdb(scsi_req, skreq, page, lba, count);
} else if (flush == SKD_FLUSH_ZERO_SIZE_FIRST) { } else if (flush == SKD_FLUSH_ZERO_SIZE_FIRST) {
@ -855,10 +856,9 @@ static void skd_end_request(struct skd_device *skdev,
if ((io_flags & REQ_DISCARD) && if ((io_flags & REQ_DISCARD) &&
(skreq->discard_page == 1)) { (skreq->discard_page == 1)) {
struct bio *bio = req->bio;
pr_debug("%s:%s:%d, free the page!", pr_debug("%s:%s:%d, free the page!",
skdev->name, __func__, __LINE__); skdev->name, __func__, __LINE__);
__free_page(bio->bi_io_vec->bv_page); __free_page(req->completion_data);
} }
if (unlikely(error)) { if (unlikely(error)) {

View File

@ -737,6 +737,7 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
goto out; goto out;
} }
rq->completion_data = page;
blk_add_request_payload(rq, page, len); blk_add_request_payload(rq, page, len);
ret = scsi_setup_blk_pc_cmnd(sdp, rq); ret = scsi_setup_blk_pc_cmnd(sdp, rq);
rq->__data_len = nr_bytes; 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; struct scsi_cmnd *SCpnt = rq->special;
if (rq->cmd_flags & REQ_DISCARD) { if (rq->cmd_flags & REQ_DISCARD)
struct bio *bio = rq->bio; __free_page(rq->completion_data);
__free_page(bio->bi_io_vec->bv_page);
}
if (SCpnt->cmnd != rq->cmd) { if (SCpnt->cmnd != rq->cmd) {
mempool_free(SCpnt->cmnd, sd_cdb_pool); mempool_free(SCpnt->cmnd, sd_cdb_pool);
SCpnt->cmnd = NULL; SCpnt->cmnd = NULL;