static vop_mknod_t afs_vop_mknod;
static vop_open_t afs_vop_open;
static vop_pathconf_t afs_vop_pathconf;
-static vop_poll_t afs_vop_poll;
static vop_print_t afs_vop_print;
static vop_putpages_t afs_vop_putpages;
static vop_read_t afs_vop_read;
.vop_mknod = afs_vop_mknod,
.vop_open = afs_vop_open,
.vop_pathconf = afs_vop_pathconf,
- .vop_poll = afs_vop_poll,
.vop_print = afs_vop_print,
.vop_putpages = afs_vop_putpages,
.vop_read = afs_vop_read,
int afs_vop_putpages(struct vop_putpages_args *);
int afs_vop_ioctl(struct vop_ioctl_args *);
static int afs_vop_pathconf(struct vop_pathconf_args *);
-int afs_vop_poll(struct vop_poll_args *);
int afs_vop_fsync(struct vop_fsync_args *);
int afs_vop_remove(struct vop_remove_args *);
int afs_vop_link(struct vop_link_args *);
{&vop_mknod_desc, (vop_t *) afs_vop_mknod}, /* mknod */
{&vop_open_desc, (vop_t *) afs_vop_open}, /* open */
{&vop_pathconf_desc, (vop_t *) afs_vop_pathconf}, /* pathconf */
- {&vop_poll_desc, (vop_t *) afs_vop_poll}, /* select */
+ {&vop_poll_desc, (vop_t *) vop_nopoll}, /* select */
{&vop_print_desc, (vop_t *) afs_vop_print}, /* print */
{&vop_read_desc, (vop_t *) afs_vop_read}, /* read */
{&vop_readdir_desc, (vop_t *) afs_vop_readdir}, /* readdir */
* 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;
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) {
/* 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;
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;
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);
}
#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
}
}
-/* ARGSUSED */
-int
-afs_vop_poll(ap)
- struct vop_poll_args /* {
- * struct vnode *a_vp;
- * int a_events;
- * struct ucred *a_cred;
- * struct thread *td;
- * } */ *ap;
-{
- /*
- * We should really check to see if I/O is possible.
- */
- return (1);
-}
-
int
afs_vop_fsync(ap)
struct vop_fsync_args /* {
* int a_flags;
* } */ *ap;
{
- int error;
+ int error, a_op;
struct ucred cr = *osi_curcred();
+ a_op = ap->a_op;
+ if (a_op == F_UNLCK) {
+ /*
+ * When a_fl->type is F_UNLCK, FreeBSD passes in an a_op of F_UNLCK.
+ * This is (confusingly) different than how you actually release a lock
+ * with fcntl(), which is done with an a_op of F_SETLK and an l_type of
+ * F_UNLCK. Pretend we were given an a_op of F_SETLK in this case,
+ * since this is what afs_lockctl expects.
+ */
+ a_op = F_SETLK;
+ }
+
AFS_GLOCK();
error =
afs_lockctl(VTOAFS(ap->a_vp),
ap->a_fl,
- ap->a_op, &cr,
+ a_op, &cr,
(int)(intptr_t)ap->a_id); /* XXX: no longer unique! */
AFS_GUNLOCK();
return error;