All of lore.kernel.org
 help / color / mirror / Atom feed
From: michaelc@cs.wisc.edu
To: linux-scsi@vger.kernel.org, jens.axboe@oracle.com, dougg@torque.net
Cc: Mike Christie <michaelc@cs.wisc.edu>
Subject: [PATCH 5/7] Add sg io mmap helper
Date: Sun, 04 Mar 2007 12:31:22 -0600	[thread overview]
Message-ID: <11730330881574-git-send-email-michaelc@cs.wisc.edu> (raw)
In-Reply-To: <11730330872229-git-send-email-michaelc@cs.wisc.edu>

From: Mike Christie <michaelc@cs.wisc.edu>

sg.c supports mmap, so this patch just move the code
to the block layer for others to share and converts it
to the bio reserved buffer.

The helpers are:
- blk_rq_mmap - does some checks to makre sure the reserved buf is
large enough.
- blk_rq_vma_nopage - traverses the reserved buffer and does get_page()

To setup and teardown the request and bio reserved buffer mappings for
the sg mmap operation you call blk_rq_setup_buffer() and
blk_rq_destroy_buffer().
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
 block/ll_rw_blk.c      |   68 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/blkdev.h |    4 +++
 2 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 4d6c2bd..35b66ed 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -2431,6 +2431,74 @@ unmap_rq:
 EXPORT_SYMBOL(blk_rq_setup_buffer);
 
 /**
+ * blk_rq_mmap - alloc and setup buffers for REQ_BLOCK_PC mmap
+ * @rbuf:	reserve buffer
+ * @vma:	vm struct
+ *
+ * Description:
+ *    A the caller must also call blk_rq_setup_buffer on the request and
+ *    blk_rq_destroy_buffer() must be issued at the end of io.
+ *    It's the callers responsibility to make sure this happens. The
+ *    original bio must be passed back in to blk_rq_destroy_buffer() for
+ *    proper unmapping.
+ *
+ *    The block layer mmap functions implement the old sg.c behavior
+ *    where they can be only one sg mmap command outstanding.
+ */
+int blk_rq_mmap(struct bio_reserve_buf *rbuf, struct vm_area_struct *vma)
+{
+	unsigned long len;
+
+	if (vma->vm_pgoff)
+		return -EINVAL; /* want no offset */
+
+	if (!rbuf)
+		return -ENOMEM;
+
+	len = vma->vm_end - vma->vm_start;
+	if (len > rbuf->buf_size)
+		return -ENOMEM;
+
+	vma->vm_flags |= VM_RESERVED;
+	return 0;
+}
+EXPORT_SYMBOL(blk_rq_mmap);
+
+struct page *blk_rq_vma_nopage(struct bio_reserve_buf *rbuf,
+			       struct vm_area_struct *vma, unsigned long addr,
+			       int *type)
+{
+	struct page *pg = NOPAGE_SIGBUS;
+	unsigned long offset, bytes = 0, sg_offset;
+	struct scatterlist *sg;
+	int i;
+
+	if (!rbuf)
+		return pg;
+
+	offset = addr - vma->vm_start;
+	if (offset >= rbuf->buf_size)
+		return pg;
+
+	for (i = 0; i < rbuf->sg_count; i++) {
+		sg = &rbuf->sg[i];
+
+		bytes += sg->length;
+		if (bytes > offset) {
+			sg_offset = sg->length - (bytes - offset);
+			pg = &sg->page[sg_offset >> PAGE_SHIFT];
+			get_page(pg);
+			break;
+		}
+	}
+
+	if (type)
+		*type = VM_FAULT_MINOR;
+	return pg;
+}
+EXPORT_SYMBOL(blk_rq_vma_nopage);
+
+/**
  * blk_rq_map_user - map user data to a request.
  * @q:		request queue where request should be inserted
  * @rq:		request structure to fill
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 755f0b4..04c1b09 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -670,6 +670,10 @@ extern void blk_sync_queue(struct reques
 extern void __blk_stop_queue(request_queue_t *q);
 extern void blk_run_queue(request_queue_t *);
 extern void blk_start_queueing(request_queue_t *);
+extern struct page *blk_rq_vma_nopage(struct bio_reserve_buf *,
+				      struct vm_area_struct *, unsigned long,
+				      int *);
+extern int blk_rq_mmap(struct bio_reserve_buf *, struct vm_area_struct *);
 extern int blk_rq_init_transfer(request_queue_t *, struct request *, void __user *, unsigned long);
 extern int blk_rq_map_user(request_queue_t *, struct request *,
 			   void __user *, unsigned long);
-- 
1.4.1.1


  reply	other threads:[~2007-03-04 18:31 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-03-04 18:31 convert sg to block layer helpers - v5 michaelc
2007-03-04 18:31 ` [PATCH 1/7] rm bio hacks in scsi tgt michaelc
2007-03-04 18:31   ` [PATCH 2/7] rm block device arg from bio map user michaelc
2007-03-04 18:31     ` [PATCH 3/7] Support large sg io segments michaelc
2007-03-04 18:31       ` [PATCH 4/7] Add reserve buffer for sg io michaelc
2007-03-04 18:31         ` michaelc [this message]
2007-03-04 18:31           ` [PATCH 6/7] Convert sg to block layer helpers michaelc
2007-03-04 18:31             ` [PATCH 7/7] mv user buffer copy access_ok test to block helper michaelc
2007-03-04 22:56               ` Mike Christie
2007-03-04 19:32 ` convert sg to block layer helpers - v5 Douglas Gilbert
2007-03-04 19:56   ` Mike Christie
2007-03-04 20:17     ` Douglas Gilbert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11730330881574-git-send-email-michaelc@cs.wisc.edu \
    --to=michaelc@cs.wisc.edu \
    --cc=dougg@torque.net \
    --cc=jens.axboe@oracle.com \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.