Module Name:    src
Committed By:   bouyer
Date:           Sun Aug 26 11:31:56 UTC 2018

Modified Files:
        src/sys/arch/xen/xen: xbd_xenbus.c

Log Message:
Add back non-512-byte aligned buffers support (reverting 1.84).
Userland users of raw devices don't have to use sector-aligned buffers,
and e.g. disklabel doesn't.
anita tests on Xen should at last complete the install phase again.


To generate a diff of this commit:
cvs rdiff -u -r1.86 -r1.87 src/sys/arch/xen/xen/xbd_xenbus.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/xen/xen/xbd_xenbus.c
diff -u src/sys/arch/xen/xen/xbd_xenbus.c:1.86 src/sys/arch/xen/xen/xbd_xenbus.c:1.87
--- src/sys/arch/xen/xen/xbd_xenbus.c:1.86	Tue Aug 21 18:55:08 2018
+++ src/sys/arch/xen/xen/xbd_xenbus.c	Sun Aug 26 11:31:56 2018
@@ -1,4 +1,4 @@
-/*      $NetBSD: xbd_xenbus.c,v 1.86 2018/08/21 18:55:08 jdolecek Exp $      */
+/*      $NetBSD: xbd_xenbus.c,v 1.87 2018/08/26 11:31:56 bouyer Exp $      */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xbd_xenbus.c,v 1.86 2018/08/21 18:55:08 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xbd_xenbus.c,v 1.87 2018/08/26 11:31:56 bouyer Exp $");
 
 #include "opt_xen.h"
 
@@ -105,6 +105,7 @@ struct xbd_req {
 		grant_ref_t req_gntref[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 		int req_nr_segments; /* number of segments in this request */
 		struct buf *req_bp; /* buffer associated with this request */
+		void *req_data; /* pointer to the data buffer */
 	    } req_rw;
 	    struct {
 		int s_error;
@@ -115,6 +116,7 @@ struct xbd_req {
 #define req_gntref	u.req_rw.req_gntref
 #define req_nr_segments	u.req_rw.req_nr_segments
 #define req_bp		u.req_rw.req_bp
+#define req_data	u.req_rw.req_data
 #define req_sync	u.req_sync
 
 struct xbd_xenbus_softc {
@@ -169,6 +171,9 @@ static int  xbd_diskstart(device_t, stru
 static void xbd_backend_changed(void *, XenbusState);
 static void xbd_connect(struct xbd_xenbus_softc *);
 
+static int  xbd_map_align(struct xbd_req *);
+static void xbd_unmap_align(struct xbd_req *);
+
 static void xbdminphys(struct buf *);
 
 CFATTACH_DECL3_NEW(xbd, sizeof(struct xbd_xenbus_softc),
@@ -694,7 +699,6 @@ again:
 
 		bp = xbdreq->req_bp;
 		KASSERT(bp != NULL);
-		xbdreq->req_bp = NULL;
 		DPRINTF(("%s(%p): b_bcount = %ld\n", __func__,
 		    bp, (long)bp->b_bcount));
 
@@ -704,7 +708,11 @@ again:
 			goto next;
 		}
 		/* b_resid was set in dk_start */
+		if (__predict_false(
+		    xbdreq->req_data != NULL && bp->b_data != xbdreq->req_data))
+			xbd_unmap_align(xbdreq);
 next:
+		xbdreq->req_bp = NULL;
 		dk_done(&sc->sc_dksc, bp);
 
 		SLIST_INSERT_HEAD(&sc->sc_xbdreq_head, xbdreq, req_next);
@@ -971,13 +979,15 @@ xbd_diskstart(device_t self, struct buf 
 		goto out;
 	}
 
-	if ((vaddr_t)bp->b_data & (XEN_BSIZE - 1)) {
-		DPRINTF(("xbd_diskstart: no align\n"));
-		error = EINVAL;
-		goto out;
-	}
-
 	xbdreq->req_bp = bp;
+	xbdreq->req_data = bp->b_data;
+	if (__predict_false((vaddr_t)bp->b_data & (XEN_BSIZE - 1))) {
+		if (__predict_false(xbd_map_align(xbdreq) != 0)) {
+			DPRINTF(("xbd_diskstart: no align\n"));
+			error = EAGAIN;
+			goto out;
+		}
+	}
 
 	SLIST_REMOVE_HEAD(&sc->sc_xbdreq_head, req_next);
 	req = RING_GET_REQUEST(&sc->sc_ring, sc->sc_ring.req_prod_pvt);
@@ -987,8 +997,8 @@ xbd_diskstart(device_t self, struct buf 
 	req->sector_number = bp->b_rawblkno;
 	req->handle = sc->sc_handle;
 
-	va = (vaddr_t)bp->b_data & ~PAGE_MASK;
-	off = (vaddr_t)bp->b_data & PAGE_MASK;
+	va = (vaddr_t)xbdreq->req_data & ~PAGE_MASK;
+	off = (vaddr_t)xbdreq->req_data & PAGE_MASK;
 	bcount = bp->b_bcount;
 	bp->b_resid = 0;
 	for (seg = 0; bcount > 0;) {
@@ -1028,3 +1038,33 @@ out:
 err:
 	return error;
 }
+
+static int
+xbd_map_align(struct xbd_req *req)
+{
+	int s = splvm(); /* XXXSMP - bogus? */
+	int rc;
+
+	rc = uvm_km_kmem_alloc(kmem_va_arena,
+	    req->req_bp->b_bcount, (VM_NOSLEEP | VM_INSTANTFIT),
+	    (vmem_addr_t *)&req->req_data);
+	splx(s);
+	if (__predict_false(rc != 0))
+		return ENOMEM;
+	if ((req->req_bp->b_flags & B_READ) == 0)
+		memcpy(req->req_data, req->req_bp->b_data,
+		    req->req_bp->b_bcount);
+	return 0;
+}
+
+static void
+xbd_unmap_align(struct xbd_req *req)
+{
+	int s;
+	if (req->req_bp->b_flags & B_READ)
+		memcpy(req->req_bp->b_data, req->req_data,
+		    req->req_bp->b_bcount);
+	s = splvm(); /* XXXSMP - bogus? */
+	uvm_km_kmem_free(kmem_va_arena, (vaddr_t)req->req_data, req->req_bp->b_bcount);
+	splx(s);
+}

Reply via email to