diff options
author | Christoph Hellwig <hch@infradead.org> | 2009-09-30 07:52:12 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-10-01 15:19:30 -0400 |
commit | c15227de132f1295f3db6b7df9079956b1020fd8 (patch) | |
tree | ad06f119f283cf8a6313681055e8132ba2851ddb /block/blk-core.c | |
parent | 3bd0f0c763e497c8674b28e3df2732f48683dabd (diff) |
block: use normal I/O path for discard requests
prepare_discard_fn() was being called in a place where memory allocation
was effectively impossible. This makes it inappropriate for all but
the most trivial translations of Linux's DISCARD operation to the block
command set. Additionally adding a payload there makes the ownership
of the bio backing unclear as it's now allocated by the device driver
and not the submitter as usual.
It is replaced with QUEUE_FLAG_DISCARD which is used to indicate whether
the queue supports discard operations or not. blkdev_issue_discard now
allocates a one-page, sector-length payload which is the right thing
for the common ATA and SCSI implementations.
The mtd implementation of prepare_discard_fn() is replaced with simply
checking for the request being a discard.
Largely based on a previous patch from Matthew Wilcox <matthew@wil.cx>
which did the prepare_discard_fn but not the different payload allocation
yet.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/blk-core.c')
-rw-r--r-- | block/blk-core.c | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 8135228e4b29..80a020dd1580 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -1124,7 +1124,6 @@ void init_request_from_bio(struct request *req, struct bio *bio) | |||
1124 | req->cmd_flags |= REQ_DISCARD; | 1124 | req->cmd_flags |= REQ_DISCARD; |
1125 | if (bio_rw_flagged(bio, BIO_RW_BARRIER)) | 1125 | if (bio_rw_flagged(bio, BIO_RW_BARRIER)) |
1126 | req->cmd_flags |= REQ_SOFTBARRIER; | 1126 | req->cmd_flags |= REQ_SOFTBARRIER; |
1127 | req->q->prepare_discard_fn(req->q, req); | ||
1128 | } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) | 1127 | } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) |
1129 | req->cmd_flags |= REQ_HARDBARRIER; | 1128 | req->cmd_flags |= REQ_HARDBARRIER; |
1130 | 1129 | ||
@@ -1470,7 +1469,7 @@ static inline void __generic_make_request(struct bio *bio) | |||
1470 | goto end_io; | 1469 | goto end_io; |
1471 | 1470 | ||
1472 | if (bio_rw_flagged(bio, BIO_RW_DISCARD) && | 1471 | if (bio_rw_flagged(bio, BIO_RW_DISCARD) && |
1473 | !q->prepare_discard_fn) { | 1472 | !blk_queue_discard(q)) { |
1474 | err = -EOPNOTSUPP; | 1473 | err = -EOPNOTSUPP; |
1475 | goto end_io; | 1474 | goto end_io; |
1476 | } | 1475 | } |