mirror of https://gitee.com/openkylin/linux.git
[SCSI] block: make blk_rq_map_user take a NULL user-space buffer for WRITE
The commit 818827669d
(block: make
blk_rq_map_user take a NULL user-space buffer) extended
blk_rq_map_user to accept a NULL user-space buffer with a READ
command. It was necessary to convert sg to use the block layer mapping
API.
This patch extends blk_rq_map_user again for a WRITE command. It is
necessary to convert st and osst drivers to use the block layer
apping API.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
56c451f4b5
commit
97ae77a1cd
|
@ -42,7 +42,7 @@ static int __blk_rq_unmap_user(struct bio *bio)
|
||||||
|
|
||||||
static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
|
static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
|
||||||
struct rq_map_data *map_data, void __user *ubuf,
|
struct rq_map_data *map_data, void __user *ubuf,
|
||||||
unsigned int len, int null_mapped, gfp_t gfp_mask)
|
unsigned int len, gfp_t gfp_mask)
|
||||||
{
|
{
|
||||||
unsigned long uaddr;
|
unsigned long uaddr;
|
||||||
struct bio *bio, *orig_bio;
|
struct bio *bio, *orig_bio;
|
||||||
|
@ -63,7 +63,7 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
|
||||||
if (IS_ERR(bio))
|
if (IS_ERR(bio))
|
||||||
return PTR_ERR(bio);
|
return PTR_ERR(bio);
|
||||||
|
|
||||||
if (null_mapped)
|
if (map_data && map_data->null_mapped)
|
||||||
bio->bi_flags |= (1 << BIO_NULL_MAPPED);
|
bio->bi_flags |= (1 << BIO_NULL_MAPPED);
|
||||||
|
|
||||||
orig_bio = bio;
|
orig_bio = bio;
|
||||||
|
@ -114,17 +114,15 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
|
||||||
{
|
{
|
||||||
unsigned long bytes_read = 0;
|
unsigned long bytes_read = 0;
|
||||||
struct bio *bio = NULL;
|
struct bio *bio = NULL;
|
||||||
int ret, null_mapped = 0;
|
int ret;
|
||||||
|
|
||||||
if (len > (q->max_hw_sectors << 9))
|
if (len > (q->max_hw_sectors << 9))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!len)
|
if (!len)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!ubuf) {
|
|
||||||
if (!map_data || rq_data_dir(rq) != READ)
|
if (!ubuf && (!map_data || !map_data->null_mapped))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
null_mapped = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (bytes_read != len) {
|
while (bytes_read != len) {
|
||||||
unsigned long map_len, end, start;
|
unsigned long map_len, end, start;
|
||||||
|
@ -143,7 +141,7 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
|
||||||
map_len -= PAGE_SIZE;
|
map_len -= PAGE_SIZE;
|
||||||
|
|
||||||
ret = __blk_rq_map_user(q, rq, map_data, ubuf, map_len,
|
ret = __blk_rq_map_user(q, rq, map_data, ubuf, map_len,
|
||||||
null_mapped, gfp_mask);
|
gfp_mask);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto unmap_rq;
|
goto unmap_rq;
|
||||||
if (!bio)
|
if (!bio)
|
||||||
|
|
|
@ -1670,6 +1670,7 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd)
|
||||||
md->page_order = req_schp->page_order;
|
md->page_order = req_schp->page_order;
|
||||||
md->nr_entries = req_schp->k_use_sg;
|
md->nr_entries = req_schp->k_use_sg;
|
||||||
md->offset = 0;
|
md->offset = 0;
|
||||||
|
md->null_mapped = hp->dxferp ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iov_count)
|
if (iov_count)
|
||||||
|
|
2
fs/bio.c
2
fs/bio.c
|
@ -859,7 +859,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
|
||||||
/*
|
/*
|
||||||
* success
|
* success
|
||||||
*/
|
*/
|
||||||
if (!write_to_vm) {
|
if (!write_to_vm && (!map_data || !map_data->null_mapped)) {
|
||||||
ret = __bio_copy_iov(bio, bio->bi_io_vec, iov, iov_count, 0, 0);
|
ret = __bio_copy_iov(bio, bio->bi_io_vec, iov, iov_count, 0, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
|
@ -691,6 +691,7 @@ struct rq_map_data {
|
||||||
int page_order;
|
int page_order;
|
||||||
int nr_entries;
|
int nr_entries;
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
|
int null_mapped;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct req_iterator {
|
struct req_iterator {
|
||||||
|
|
Loading…
Reference in New Issue