block: pass iov_iter to the BLOCK_PC mapping functions
Make use of a new interface provided by iov_iter, backed by scatter-gather list of iovec, instead of the old interface based on sg_iovec. Also use iov_iter_advance() instead of manual iteration. This commit should contain only literal replacements, without functional changes. Cc: Christoph Hellwig <hch@infradead.org> Cc: Jens Axboe <axboe@kernel.dk> Cc: Doug Gilbert <dgilbert@interlog.com> Cc: "James E.J. Bottomley" <JBottomley@parallels.com> Signed-off-by: Kent Overstreet <kmo@daterainc.com> [dpark: add more description in commit message] Signed-off-by: Dongsu Park <dongsu.park@profitbricks.com> [hch: fixed to do a deep clone of the iov_iter, and to properly use the iov_iter direction] Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Ming Lei <tom.leiming@gmail.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
committed by
Jens Axboe
parent
1dfa0f68c0
commit
26e49cfc7e
@@ -5,7 +5,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/bio.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <scsi/sg.h> /* for struct sg_iovec */
|
||||
#include <linux/uio.h>
|
||||
|
||||
#include "blk.h"
|
||||
|
||||
@@ -44,9 +44,7 @@ static int __blk_rq_unmap_user(struct bio *bio)
|
||||
* @q: request queue where request should be inserted
|
||||
* @rq: request to map data to
|
||||
* @map_data: pointer to the rq_map_data holding pages (if necessary)
|
||||
* @iov: pointer to the iovec
|
||||
* @iov_count: number of elements in the iovec
|
||||
* @len: I/O byte count
|
||||
* @iter: iovec iterator
|
||||
* @gfp_mask: memory allocation flags
|
||||
*
|
||||
* Description:
|
||||
@@ -63,20 +61,21 @@ static int __blk_rq_unmap_user(struct bio *bio)
|
||||
* unmapping.
|
||||
*/
|
||||
int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
|
||||
struct rq_map_data *map_data, const struct sg_iovec *iov,
|
||||
int iov_count, unsigned int len, gfp_t gfp_mask)
|
||||
struct rq_map_data *map_data,
|
||||
const struct iov_iter *iter, gfp_t gfp_mask)
|
||||
{
|
||||
struct bio *bio;
|
||||
int i, read = rq_data_dir(rq) == READ;
|
||||
int unaligned = 0;
|
||||
struct iov_iter i;
|
||||
struct iovec iov;
|
||||
|
||||
if (!iov || iov_count <= 0)
|
||||
if (!iter || !iter->count)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
unsigned long uaddr = (unsigned long)iov[i].iov_base;
|
||||
iov_for_each(iov, i, *iter) {
|
||||
unsigned long uaddr = (unsigned long) iov.iov_base;
|
||||
|
||||
if (!iov[i].iov_len)
|
||||
if (!iov.iov_len)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
@@ -86,16 +85,15 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
|
||||
unaligned = 1;
|
||||
}
|
||||
|
||||
if (unaligned || (q->dma_pad_mask & len) || map_data)
|
||||
bio = bio_copy_user_iov(q, map_data, iov, iov_count, read,
|
||||
gfp_mask);
|
||||
if (unaligned || (q->dma_pad_mask & iter->count) || map_data)
|
||||
bio = bio_copy_user_iov(q, map_data, iter, gfp_mask);
|
||||
else
|
||||
bio = bio_map_user_iov(q, NULL, iov, iov_count, read, gfp_mask);
|
||||
bio = bio_map_user_iov(q, NULL, iter, gfp_mask);
|
||||
|
||||
if (IS_ERR(bio))
|
||||
return PTR_ERR(bio);
|
||||
|
||||
if (bio->bi_iter.bi_size != len) {
|
||||
if (bio->bi_iter.bi_size != iter->count) {
|
||||
/*
|
||||
* Grab an extra reference to this bio, as bio_unmap_user()
|
||||
* expects to be able to drop it twice as it happens on the
|
||||
@@ -121,12 +119,14 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
|
||||
struct rq_map_data *map_data, void __user *ubuf,
|
||||
unsigned long len, gfp_t gfp_mask)
|
||||
{
|
||||
struct sg_iovec iov;
|
||||
struct iovec iov;
|
||||
struct iov_iter i;
|
||||
|
||||
iov.iov_base = (void __user *)ubuf;
|
||||
iov.iov_base = ubuf;
|
||||
iov.iov_len = len;
|
||||
iov_iter_init(&i, rq_data_dir(rq), &iov, 1, len);
|
||||
|
||||
return blk_rq_map_user_iov(q, rq, map_data, &iov, 1, len, gfp_mask);
|
||||
return blk_rq_map_user_iov(q, rq, map_data, &i, gfp_mask);
|
||||
}
|
||||
EXPORT_SYMBOL(blk_rq_map_user);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user