From dd80f081663c50f93618da7a309b390f2fbdbc59 Mon Sep 17 00:00:00 2001 From: Tim Creech Date: Sun, 5 Mar 2017 18:13:45 -0500 Subject: [PATCH] FBSD: build fix for FreeBSD 11 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 Tested-by: BuildBot --- src/afs/FBSD/osi_vnodeops.c | 69 ++++++++++++++++++++++--------- src/afs/VNOPS/afs_vnop_strategy.c | 6 +-- src/config/param.generic_fbsd.h | 10 +++++ 3 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/afs/FBSD/osi_vnodeops.c b/src/afs/FBSD/osi_vnodeops.c index b2f595634..df97f349d 100644 --- a/src/afs/FBSD/osi_vnodeops.c +++ b/src/afs/FBSD/osi_vnodeops.c @@ -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 diff --git a/src/afs/VNOPS/afs_vnop_strategy.c b/src/afs/VNOPS/afs_vnop_strategy.c index 6e2970c01..97b699310 100644 --- a/src/afs/VNOPS/afs_vnop_strategy.c +++ b/src/afs/VNOPS/afs_vnop_strategy.c @@ -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; diff --git a/src/config/param.generic_fbsd.h b/src/config/param.generic_fbsd.h index 9977eeeea..bc193bf66 100644 --- a/src/config/param.generic_fbsd.h +++ b/src/config/param.generic_fbsd.h @@ -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 */ -- 2.39.5