Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97ae77a1 authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by James Bottomley
Browse files

[SCSI] block: make blk_rq_map_user take a NULL user-space buffer for WRITE



The commit 81882766 (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: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: default avatarJens Axboe <jens.axboe@oracle.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 56c451f4
Loading
Loading
Loading
Loading
+7 −9
Original line number Original line Diff line number Diff line
@@ -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)
+1 −0
Original line number Original line Diff line number Diff line
@@ -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)
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;
+1 −0
Original line number Original line Diff line number Diff line
@@ -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 {