Author: bryanv
Date: Sun May  4 00:43:00 2014
New Revision: 265299
URL: http://svnweb.freebsd.org/changeset/base/265299
Log:
  MFC r260581:
  
   - Add sglist_append_bio(9) to append a struct bio's data to a sglist

Modified:
  stable/9/sys/kern/subr_sglist.c
  stable/9/sys/sys/sglist.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/sys/   (props changed)

Modified: stable/9/sys/kern/subr_sglist.c
==============================================================================
--- stable/9/sys/kern/subr_sglist.c     Sun May  4 00:14:49 2014        
(r265298)
+++ stable/9/sys/kern/subr_sglist.c     Sun May  4 00:43:00 2014        
(r265299)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
+#include <sys/bio.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/proc.h>
@@ -40,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/uio.h>
 
 #include <vm/vm.h>
+#include <vm/vm_page.h>
 #include <vm/pmap.h>
 #include <vm/vm_map.h>
 
@@ -239,6 +241,44 @@ sglist_append(struct sglist *sg, void *b
 }
 
 /*
+ * Append the segments to describe a bio's data to a scatter/gather list.
+ * If there are insufficient segments, then this fails with EFBIG.
+ *
+ * NOTE: This function expects bio_bcount to be initialized.
+ */
+int
+sglist_append_bio(struct sglist *sg, struct bio *bp)
+{
+       struct sgsave save;
+       vm_paddr_t paddr;
+       size_t len, tlen;
+       int error, i, ma_offs;
+
+       if ((bp->bio_flags & BIO_UNMAPPED) == 0) {
+               error = sglist_append(sg, bp->bio_data, bp->bio_bcount);
+               return (error);
+       }
+
+       if (sg->sg_maxseg == 0)
+               return (EINVAL);
+
+       SGLIST_SAVE(sg, save);
+       tlen = bp->bio_bcount;
+       ma_offs = bp->bio_ma_offset;
+       for (i = 0; tlen > 0; i++, tlen -= len) {
+               len = min(PAGE_SIZE - ma_offs, tlen);
+               paddr = VM_PAGE_TO_PHYS(bp->bio_ma[i]) + ma_offs;
+               error = sglist_append_phys(sg, paddr, len);
+               if (error) {
+                       SGLIST_RESTORE(sg, save);
+                       return (error);
+               }
+               ma_offs = 0;
+       }
+       return (0);
+}
+
+/*
  * Append a single physical address range to a scatter/gather list.
  * If there are insufficient segments, then this fails with EFBIG.
  */

Modified: stable/9/sys/sys/sglist.h
==============================================================================
--- stable/9/sys/sys/sglist.h   Sun May  4 00:14:49 2014        (r265298)
+++ stable/9/sys/sys/sglist.h   Sun May  4 00:43:00 2014        (r265299)
@@ -53,6 +53,7 @@ struct sglist {
        u_short         sg_maxseg;
 };
 
+struct bio;
 struct mbuf;
 struct uio;
 
@@ -83,6 +84,7 @@ sglist_hold(struct sglist *sg)
 
 struct sglist *sglist_alloc(int nsegs, int mflags);
 int    sglist_append(struct sglist *sg, void *buf, size_t len);
+int    sglist_append_bio(struct sglist *sg, struct bio *bp);
 int    sglist_append_mbuf(struct sglist *sg, struct mbuf *m0);
 int    sglist_append_phys(struct sglist *sg, vm_paddr_t paddr,
            size_t len);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to