FBSD: build fix for FreeBSD 11 75/12575/5
authorTim Creech <tcreech@tcreech.com>
Sun, 5 Mar 2017 23:13:45 +0000 (18:13 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Wed, 3 May 2017 04:04:41 +0000 (00:04 -0400)
r285819 eliminated b_saveaddr from struct buf, while r292373 changed the
arguments to VOP_GETPAGES. The approach used by this patch to address
these changes was inspired by FreeBSD's nfs and samba clients.

Change-Id: Ibcf6b6fde6c86f96aa814af2bca08f1a8b286740
Reviewed-on: https://gerrit.openafs.org/12575
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/afs/FBSD/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_strategy.c
src/config/param.generic_fbsd.h

index b2f5956..df97f34 100644 (file)
@@ -781,20 +781,21 @@ afs_vop_read(ap)
  *     struct vnode *a_vp;
  *     vm_page_t *a_m;
  *     int a_count;
- *     int a_reqpage;
- *     vm_oofset_t a_offset;
+ *     int *a_rbehind;
+ *     int *a_rahead;
  * };
  */
 int
 afs_vop_getpages(struct vop_getpages_args *ap)
 {
     int code;
-    int i, nextoff, size, toff, npages;
+    int i, nextoff, size, toff, npages, count;
     struct uio uio;
     struct iovec iov;
     struct buf *bp;
     vm_offset_t kva;
     vm_object_t object;
+    vm_page_t *pages;
     struct vnode *vp;
     struct vcache *avc;
 
@@ -803,20 +804,40 @@ afs_vop_getpages(struct vop_getpages_args *ap)
 
     vp = ap->a_vp;
     avc = VTOAFS(vp);
+    pages = ap->a_m;
+#ifdef FBSD_VOP_GETPAGES_BUSIED
+    npages = ap->a_count;
+    if (ap->a_rbehind)
+        *ap->a_rbehind = 0;
+    if (ap->a_rahead)
+        *ap->a_rahead = 0;
+#else
+    npages = btoc(ap->a_count);
+#endif
+
     if ((object = vp->v_object) == NULL) {
        printf("afs_getpages: called with non-merged cache vnode??\n");
        return VM_PAGER_ERROR;
     }
-    npages = btoc(ap->a_count);
+
     /*
      * If the requested page is partially valid, just return it and
      * allow the pager to zero-out the blanks.  Partially valid pages
      * can only occur at the file EOF.
      */
-
     {
-       vm_page_t m = ap->a_m[ap->a_reqpage];
-
+#ifdef FBSD_VOP_GETPAGES_BUSIED
+       AFS_VM_OBJECT_WLOCK(object);
+       ma_vm_page_lock_queues();
+       if(pages[npages - 1]->valid != 0) {
+           if (--npages == 0) {
+               ma_vm_page_unlock_queues();
+               AFS_VM_OBJECT_WUNLOCK(object);
+               return (VM_PAGER_OK);
+           }
+       }
+#else
+       vm_page_t m = pages[ap->a_reqpage];
        AFS_VM_OBJECT_WLOCK(object);
        ma_vm_page_lock_queues();
        if (m->valid != 0) {
@@ -824,31 +845,37 @@ afs_vop_getpages(struct vop_getpages_args *ap)
            /* vm_page_zero_invalid(m, TRUE); */
            for (i = 0; i < npages; ++i) {
                if (i != ap->a_reqpage) {
-                   ma_vm_page_lock(ap->a_m[i]);
-                   vm_page_free(ap->a_m[i]);
-                   ma_vm_page_unlock(ap->a_m[i]);
+                   ma_vm_page_lock(pages[i]);
+                   vm_page_free(pages[i]);
+                   ma_vm_page_unlock(pages[i]);
                }
            }
            ma_vm_page_unlock_queues();
            AFS_VM_OBJECT_WUNLOCK(object);
            return (0);
        }
+#endif
        ma_vm_page_unlock_queues();
        AFS_VM_OBJECT_WUNLOCK(object);
     }
     bp = getpbuf(&afs_pbuf_freecnt);
 
     kva = (vm_offset_t) bp->b_data;
-    pmap_qenter(kva, ap->a_m, npages);
+    pmap_qenter(kva, pages, npages);
     MA_PCPU_INC(cnt.v_vnodein);
     MA_PCPU_ADD(cnt.v_vnodepgsin, npages);
 
+#ifdef FBSD_VOP_GETPAGES_BUSIED
+    count = ctob(npages);
+#else
+    count = ap->a_count;
+#endif
     iov.iov_base = (caddr_t) kva;
-    iov.iov_len = ap->a_count;
+    iov.iov_len = count;
     uio.uio_iov = &iov;
     uio.uio_iovcnt = 1;
-    uio.uio_offset = IDX_TO_OFF(ap->a_m[0]->pindex);
-    uio.uio_resid = ap->a_count;
+    uio.uio_offset = IDX_TO_OFF(pages[0]->pindex);
+    uio.uio_resid = count;
     uio.uio_segflg = UIO_SYSSPACE;
     uio.uio_rw = UIO_READ;
     uio.uio_td = curthread;
@@ -861,25 +888,27 @@ afs_vop_getpages(struct vop_getpages_args *ap)
 
     relpbuf(bp, &afs_pbuf_freecnt);
 
-    if (code && (uio.uio_resid == ap->a_count)) {
+    if (code && (uio.uio_resid == count)) {
+#ifndef FBSD_VOP_GETPAGES_BUSIED
        AFS_VM_OBJECT_WLOCK(object);
        ma_vm_page_lock_queues();
        for (i = 0; i < npages; ++i) {
            if (i != ap->a_reqpage)
-               vm_page_free(ap->a_m[i]);
+               vm_page_free(pages[i]);
        }
        ma_vm_page_unlock_queues();
        AFS_VM_OBJECT_WUNLOCK(object);
+#endif
        return VM_PAGER_ERROR;
     }
 
-    size = ap->a_count - uio.uio_resid;
+    size = count - uio.uio_resid;
     AFS_VM_OBJECT_WLOCK(object);
     ma_vm_page_lock_queues();
     for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
        vm_page_t m;
        nextoff = toff + PAGE_SIZE;
-       m = ap->a_m[i];
+       m = pages[i];
 
        /* XXX not in nfsclient? */
        m->flags &= ~PG_ZERO;
@@ -903,6 +932,7 @@ afs_vop_getpages(struct vop_getpages_args *ap)
            KASSERT(m->dirty == 0, ("afs_getpages: page %p is dirty", m));
        }
 
+#ifndef FBSD_VOP_GETPAGES_BUSIED
        if (i != ap->a_reqpage) {
 #if __FreeBSD_version >= 1000042
            vm_page_readahead_finish(m);
@@ -942,10 +972,11 @@ afs_vop_getpages(struct vop_getpages_args *ap)
            }
 #endif /* __FreeBSD_version 1000042 */
        }
+#endif   /* ndef FBSD_VOP_GETPAGES_BUSIED */
     }
     ma_vm_page_unlock_queues();
     AFS_VM_OBJECT_WUNLOCK(object);
-    return 0;
+    return VM_PAGER_OK;
 }
 
 int
index 6e2970c..97b6993 100644 (file)
@@ -98,7 +98,7 @@ int afs_ustrategy(struct buf *abp)
        tuio.afsio_fmode = 0;
 #endif
        tuio.afsio_resid = abp->b_bcount;
-#if defined(AFS_NBSD40_ENV)
+#if defined(AFS_NBSD40_ENV) || defined(FBSD_STRUCT_BUF_NO_SAVEADDR)
        tiovec[0].iov_base = abp->b_data;
 #elif defined(AFS_XBSD_ENV)
        tiovec[0].iov_base = abp->b_saveaddr;
@@ -115,7 +115,7 @@ int afs_ustrategy(struct buf *abp)
 #endif
        if (code == 0) {
            if (tuio.afsio_resid > 0)
-#if defined(AFS_NBSD40_ENV)
+#if defined(AFS_NBSD40_ENV) || defined(FBSD_STRUCT_BUF_NO_SAVEADDR)
                memset((char *)abp->b_data + (uintptr_t)abp->b_bcount - tuio.afsio_resid, 0,
                       tuio.afsio_resid);
 #elif defined(AFS_XBSD_ENV)
@@ -180,7 +180,7 @@ int afs_ustrategy(struct buf *abp)
        len = MIN(len, tvc->f.m.Length - dbtob(abp->b_blkno));
 #endif
        tuio.afsio_resid = len;
-#if defined(AFS_NBSD40_ENV)
+#if defined(AFS_NBSD40_ENV) || defined(FBSD_STRUCT_BUF_NO_SAVEADDR)
        tiovec[0].iov_base = abp->b_data;
 #elif defined(AFS_XBSD_ENV)
        tiovec[0].iov_base = abp->b_saveaddr;
index 9977eee..bc193bf 100644 (file)
@@ -126,6 +126,16 @@ enum vcexcl { NONEXCL, EXCL };
 #define FBSD_SYSCALL_REGISTER_FOUR_ARGS
 #endif
 
+/* r285819 eliminated b_saveaddr from struct buf */
+#if __FreeBSD_version >= 1100078
+#define FBSD_STRUCT_BUF_NO_SAVEADDR
+#endif
+
+/* r292373 changed the KPI for VOP_GETPAGES */
+#if __FreeBSD_version >= 1100092
+#define FBSD_VOP_GETPAGES_BUSIED
+#endif
+
 #else /* !defined(UKERNEL) */
 
 /* This section for user space compiles only */