X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/17ff8c4b215552a4880d5fa0d66f3a0fa22d71e9..14c92d030823830875c4491975fa0439e6503872:/sys/vfs/nfs/nfs_vnops.c diff --git a/sys/vfs/nfs/nfs_vnops.c b/sys/vfs/nfs/nfs_vnops.c index 71ed66ac99..28ac6a1010 100644 --- a/sys/vfs/nfs/nfs_vnops.c +++ b/sys/vfs/nfs/nfs_vnops.c @@ -35,7 +35,7 @@ * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.21 2004/04/19 16:33:49 cpressey Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.30 2004/09/26 01:24:56 dillon Exp $ */ @@ -138,95 +138,83 @@ static int nfs_bwrite (struct vop_bwrite_args *); /* * Global vfs data structures for nfs */ -vop_t **nfsv2_vnodeop_p; -static struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = { - { &vop_default_desc, (vop_t *) vop_defaultop }, - { &vop_access_desc, (vop_t *) nfs_access }, - { &vop_advlock_desc, (vop_t *) nfs_advlock }, - { &vop_bmap_desc, (vop_t *) nfs_bmap }, - { &vop_bwrite_desc, (vop_t *) nfs_bwrite }, - { &vop_close_desc, (vop_t *) nfs_close }, - { &vop_create_desc, (vop_t *) nfs_create }, - { &vop_fsync_desc, (vop_t *) nfs_fsync }, - { &vop_getattr_desc, (vop_t *) nfs_getattr }, - { &vop_getpages_desc, (vop_t *) nfs_getpages }, - { &vop_putpages_desc, (vop_t *) nfs_putpages }, - { &vop_inactive_desc, (vop_t *) nfs_inactive }, - { &vop_islocked_desc, (vop_t *) vop_stdislocked }, - { &vop_lease_desc, (vop_t *) vop_null }, - { &vop_link_desc, (vop_t *) nfs_link }, - { &vop_lock_desc, (vop_t *) vop_sharedlock }, - { &vop_lookup_desc, (vop_t *) nfs_lookup }, - { &vop_mkdir_desc, (vop_t *) nfs_mkdir }, - { &vop_mknod_desc, (vop_t *) nfs_mknod }, - { &vop_mmap_desc, (vop_t *) nfs_mmap }, - { &vop_open_desc, (vop_t *) nfs_open }, - { &vop_poll_desc, (vop_t *) nfs_poll }, - { &vop_print_desc, (vop_t *) nfs_print }, - { &vop_read_desc, (vop_t *) nfs_read }, - { &vop_readdir_desc, (vop_t *) nfs_readdir }, - { &vop_readlink_desc, (vop_t *) nfs_readlink }, - { &vop_reclaim_desc, (vop_t *) nfs_reclaim }, - { &vop_remove_desc, (vop_t *) nfs_remove }, - { &vop_rename_desc, (vop_t *) nfs_rename }, - { &vop_rmdir_desc, (vop_t *) nfs_rmdir }, - { &vop_setattr_desc, (vop_t *) nfs_setattr }, - { &vop_strategy_desc, (vop_t *) nfs_strategy }, - { &vop_symlink_desc, (vop_t *) nfs_symlink }, - { &vop_unlock_desc, (vop_t *) vop_stdunlock }, - { &vop_write_desc, (vop_t *) nfs_write }, +struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = { + { &vop_default_desc, vop_defaultop }, + { &vop_access_desc, (void *) nfs_access }, + { &vop_advlock_desc, (void *) nfs_advlock }, + { &vop_bmap_desc, (void *) nfs_bmap }, + { &vop_bwrite_desc, (void *) nfs_bwrite }, + { &vop_close_desc, (void *) nfs_close }, + { &vop_create_desc, (void *) nfs_create }, + { &vop_fsync_desc, (void *) nfs_fsync }, + { &vop_getattr_desc, (void *) nfs_getattr }, + { &vop_getpages_desc, (void *) nfs_getpages }, + { &vop_putpages_desc, (void *) nfs_putpages }, + { &vop_inactive_desc, (void *) nfs_inactive }, + { &vop_islocked_desc, (void *) vop_stdislocked }, + { &vop_lease_desc, vop_null }, + { &vop_link_desc, (void *) nfs_link }, + { &vop_lock_desc, (void *) vop_stdlock }, + { &vop_lookup_desc, (void *) nfs_lookup }, + { &vop_mkdir_desc, (void *) nfs_mkdir }, + { &vop_mknod_desc, (void *) nfs_mknod }, + { &vop_mmap_desc, (void *) nfs_mmap }, + { &vop_open_desc, (void *) nfs_open }, + { &vop_poll_desc, (void *) nfs_poll }, + { &vop_print_desc, (void *) nfs_print }, + { &vop_read_desc, (void *) nfs_read }, + { &vop_readdir_desc, (void *) nfs_readdir }, + { &vop_readlink_desc, (void *) nfs_readlink }, + { &vop_reclaim_desc, (void *) nfs_reclaim }, + { &vop_remove_desc, (void *) nfs_remove }, + { &vop_rename_desc, (void *) nfs_rename }, + { &vop_rmdir_desc, (void *) nfs_rmdir }, + { &vop_setattr_desc, (void *) nfs_setattr }, + { &vop_strategy_desc, (void *) nfs_strategy }, + { &vop_symlink_desc, (void *) nfs_symlink }, + { &vop_unlock_desc, (void *) vop_stdunlock }, + { &vop_write_desc, (void *) nfs_write }, { NULL, NULL } }; -static struct vnodeopv_desc nfsv2_vnodeop_opv_desc = - { &nfsv2_vnodeop_p, nfsv2_vnodeop_entries }; -VNODEOP_SET(nfsv2_vnodeop_opv_desc); /* * Special device vnode ops */ -vop_t **spec_nfsv2nodeop_p; -static struct vnodeopv_entry_desc nfsv2_specop_entries[] = { - { &vop_default_desc, (vop_t *) spec_vnoperate }, - { &vop_access_desc, (vop_t *) nfsspec_access }, - { &vop_close_desc, (vop_t *) nfsspec_close }, - { &vop_fsync_desc, (vop_t *) nfs_fsync }, - { &vop_getattr_desc, (vop_t *) nfs_getattr }, - { &vop_inactive_desc, (vop_t *) nfs_inactive }, - { &vop_islocked_desc, (vop_t *) vop_stdislocked }, - { &vop_lock_desc, (vop_t *) vop_sharedlock }, - { &vop_print_desc, (vop_t *) nfs_print }, - { &vop_read_desc, (vop_t *) nfsspec_read }, - { &vop_reclaim_desc, (vop_t *) nfs_reclaim }, - { &vop_setattr_desc, (vop_t *) nfs_setattr }, - { &vop_unlock_desc, (vop_t *) vop_stdunlock }, - { &vop_write_desc, (vop_t *) nfsspec_write }, +struct vnodeopv_entry_desc nfsv2_specop_entries[] = { + { &vop_default_desc, (void *) spec_vnoperate }, + { &vop_access_desc, (void *) nfsspec_access }, + { &vop_close_desc, (void *) nfsspec_close }, + { &vop_fsync_desc, (void *) nfs_fsync }, + { &vop_getattr_desc, (void *) nfs_getattr }, + { &vop_inactive_desc, (void *) nfs_inactive }, + { &vop_islocked_desc, (void *) vop_stdislocked }, + { &vop_lock_desc, (void *) vop_stdlock }, + { &vop_print_desc, (void *) nfs_print }, + { &vop_read_desc, (void *) nfsspec_read }, + { &vop_reclaim_desc, (void *) nfs_reclaim }, + { &vop_setattr_desc, (void *) nfs_setattr }, + { &vop_unlock_desc, (void *) vop_stdunlock }, + { &vop_write_desc, (void *) nfsspec_write }, { NULL, NULL } }; -static struct vnodeopv_desc spec_nfsv2nodeop_opv_desc = - { &spec_nfsv2nodeop_p, nfsv2_specop_entries }; -VNODEOP_SET(spec_nfsv2nodeop_opv_desc); - -vop_t **fifo_nfsv2nodeop_p; -static struct vnodeopv_entry_desc nfsv2_fifoop_entries[] = { - { &vop_default_desc, (vop_t *) fifo_vnoperate }, - { &vop_access_desc, (vop_t *) nfsspec_access }, - { &vop_close_desc, (vop_t *) nfsfifo_close }, - { &vop_fsync_desc, (vop_t *) nfs_fsync }, - { &vop_getattr_desc, (vop_t *) nfs_getattr }, - { &vop_inactive_desc, (vop_t *) nfs_inactive }, - { &vop_islocked_desc, (vop_t *) vop_stdislocked }, - { &vop_lock_desc, (vop_t *) vop_sharedlock }, - { &vop_print_desc, (vop_t *) nfs_print }, - { &vop_read_desc, (vop_t *) nfsfifo_read }, - { &vop_reclaim_desc, (vop_t *) nfs_reclaim }, - { &vop_setattr_desc, (vop_t *) nfs_setattr }, - { &vop_unlock_desc, (vop_t *) vop_stdunlock }, - { &vop_write_desc, (vop_t *) nfsfifo_write }, + +struct vnodeopv_entry_desc nfsv2_fifoop_entries[] = { + { &vop_default_desc, (void *) fifo_vnoperate }, + { &vop_access_desc, (void *) nfsspec_access }, + { &vop_close_desc, (void *) nfsfifo_close }, + { &vop_fsync_desc, (void *) nfs_fsync }, + { &vop_getattr_desc, (void *) nfs_getattr }, + { &vop_inactive_desc, (void *) nfs_inactive }, + { &vop_islocked_desc, (void *) vop_stdislocked }, + { &vop_lock_desc, (void *) vop_stdlock }, + { &vop_print_desc, (void *) nfs_print }, + { &vop_read_desc, (void *) nfsfifo_read }, + { &vop_reclaim_desc, (void *) nfs_reclaim }, + { &vop_setattr_desc, (void *) nfs_setattr }, + { &vop_unlock_desc, (void *) vop_stdunlock }, + { &vop_write_desc, (void *) nfsfifo_write }, { NULL, NULL } }; -static struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc = - { &fifo_nfsv2nodeop_p, nfsv2_fifoop_entries }; -VNODEOP_SET(fifo_nfsv2nodeop_opv_desc); static int nfs_mknodrpc (struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, @@ -744,10 +732,14 @@ nfs_setattr(struct vop_setattr_args *ap) return (error); } } - /* np->n_size has already been set to vap->va_size + /* + * np->n_size has already been set to vap->va_size * in nfs_meta_setsize(). We must set it again since * nfs_loadattrcache() could be called through * nfs_meta_setsize() and could modify np->n_size. + * + * (note that nfs_loadattrcache() will have called + * vnode_pager_setsize() for us in that case). */ np->n_vattr.va_size = np->n_size = vap->va_size; }; @@ -772,6 +764,7 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred, struct thread *td) { struct nfsv2_sattr *sp; + struct nfsnode *np = VTONFS(vp); caddr_t cp; int32_t t1, t2; caddr_t bpos, dpos, cp2; @@ -807,6 +800,7 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, } nfsm_request(vp, NFSPROC_SETATTR, td, cred); if (v3) { + np->n_modestamp = 0; nfsm_wcc_data(vp, wccflag); } else nfsm_loadattr(vp, (struct vattr *)0); @@ -863,7 +857,7 @@ nfs_lookup(struct vop_lookup_args *ap) wantparent = flags & (CNP_LOCKPARENT|CNP_WANTPARENT); nmp = VFSTONFS(dvp->v_mount); np = VTONFS(dvp); - error = cache_lookup(dvp, NCPNULL, vpp, NCPPNULL, cnp); + error = cache_lookup(dvp, vpp, cnp); if (error != 0) { struct vattr vattr; int vpid; @@ -884,17 +878,23 @@ nfs_lookup(struct vop_lookup_args *ap) * for an explanation of the locking protocol */ if (dvp == newvp) { - VREF(newvp); + vref(newvp); error = 0; } else if (flags & CNP_ISDOTDOT) { VOP_UNLOCK(dvp, NULL, 0, td); + cnp->cn_flags |= CNP_PDIRUNLOCK; error = vget(newvp, NULL, LK_EXCLUSIVE, td); - if (!error && lockparent && (flags & CNP_ISLASTCN)) + if (!error && lockparent && (flags & CNP_ISLASTCN)) { error = vn_lock(dvp, NULL, LK_EXCLUSIVE, td); + if (error == 0) + cnp->cn_flags &= ~CNP_PDIRUNLOCK; + } } else { error = vget(newvp, NULL, LK_EXCLUSIVE, td); - if (!lockparent || error || !(flags & CNP_ISLASTCN)) + if (!lockparent || error || !(flags & CNP_ISLASTCN)) { VOP_UNLOCK(dvp, NULL, 0, td); + cnp->cn_flags |= CNP_PDIRUNLOCK; + } } if (!error) { if (vpid == newvp->v_id) { @@ -909,10 +909,14 @@ nfs_lookup(struct vop_lookup_args *ap) cache_purge(newvp); } vput(newvp); - if (lockparent && dvp != newvp && (flags & CNP_ISLASTCN)) + if (lockparent && dvp != newvp && (flags & CNP_ISLASTCN)) { VOP_UNLOCK(dvp, NULL, 0, td); + cnp->cn_flags |= CNP_PDIRUNLOCK; + } } error = vn_lock(dvp, NULL, LK_EXCLUSIVE, td); + if (error == 0) + cnp->cn_flags &= ~CNP_PDIRUNLOCK; *vpp = NULLVP; if (error) return (error); @@ -978,26 +982,33 @@ nfs_lookup(struct vop_lookup_args *ap) *vpp = newvp; m_freem(mrep); cnp->cn_flags |= CNP_SAVENAME; - if (!lockparent) + if (!lockparent) { VOP_UNLOCK(dvp, NULL, 0, td); + cnp->cn_flags |= CNP_PDIRUNLOCK; + } return (0); } if (flags & CNP_ISDOTDOT) { VOP_UNLOCK(dvp, NULL, 0, td); + cnp->cn_flags |= CNP_PDIRUNLOCK; error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); if (error) { vn_lock(dvp, NULL, LK_EXCLUSIVE | LK_RETRY, td); - return (error); + cnp->cn_flags &= ~CNP_PDIRUNLOCK; + return (error); /* NOTE: return error from nget */ } newvp = NFSTOV(np); - if (lockparent && (flags & CNP_ISLASTCN) && - (error = vn_lock(dvp, NULL, LK_EXCLUSIVE, td))) { - vput(newvp); - return (error); + if (lockparent && (flags & CNP_ISLASTCN)) { + error = vn_lock(dvp, NULL, LK_EXCLUSIVE, td); + if (error) { + vput(newvp); + return (error); + } + cnp->cn_flags |= CNP_PDIRUNLOCK; } } else if (NFS_CMPFH(np, fhp, fhsize)) { - VREF(dvp); + vref(dvp); newvp = dvp; } else { error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); @@ -1005,8 +1016,10 @@ nfs_lookup(struct vop_lookup_args *ap) m_freem(mrep); return (error); } - if (!lockparent || !(flags & CNP_ISLASTCN)) + if (!lockparent || !(flags & CNP_ISLASTCN)) { VOP_UNLOCK(dvp, NULL, 0, td); + cnp->cn_flags |= CNP_PDIRUNLOCK; + } newvp = NFSTOV(np); } if (v3) { @@ -1031,8 +1044,10 @@ nfsmout: } if ((cnp->cn_nameiop == NAMEI_CREATE || cnp->cn_nameiop == NAMEI_RENAME) && (flags & CNP_ISLASTCN) && error == ENOENT) { - if (!lockparent) + if (!lockparent) { VOP_UNLOCK(dvp, NULL, 0, td); + cnp->cn_flags |= CNP_PDIRUNLOCK; + } if (dvp->v_mount->mnt_flag & MNT_RDONLY) error = EROFS; else @@ -1441,7 +1456,7 @@ again: nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF); #ifdef INET if (!TAILQ_EMPTY(&in_ifaddrhead)) - *tl++ = IA_SIN(in_ifaddrhead.tqh_first)->sin_addr.s_addr; + *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr.s_addr; else #endif *tl++ = create_verf; @@ -2411,7 +2426,7 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) if (doit) { nfsm_getfh(fhp, fhsize, 1); if (NFS_CMPFH(dnp, fhp, fhsize)) { - VREF(vp); + vref(vp); newvp = vp; np = dnp; } else { @@ -2522,7 +2537,7 @@ nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) M_NFSREQ, M_WAITOK); sp->s_cred = crdup(cnp->cn_cred); sp->s_dvp = dvp; - VREF(dvp); + vref(dvp); /* Fudge together a funny name */ sp->s_namlen = sprintf(sp->s_name, ".nfsA%08x4.4", (int)cnp->cn_td); @@ -2592,7 +2607,7 @@ nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred, np->n_fhsize = fhlen; newvp = NFSTOV(np); } else if (NFS_CMPFH(dnp, nfhp, fhlen)) { - VREF(dvp); + vref(dvp); newvp = dvp; } else { error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np); @@ -3194,7 +3209,7 @@ nfsspec_read(struct vop_read_args *ap) */ np->n_flag |= NACC; getnanotime(&np->n_atim); - return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap)); + return (VOCALL(spec_vnode_vops, &ap->a_head)); } /* @@ -3213,7 +3228,7 @@ nfsspec_write(struct vop_write_args *ap) */ np->n_flag |= NUPD; getnanotime(&np->n_mtim); - return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap)); + return (VOCALL(spec_vnode_vops, &ap->a_head)); } /* @@ -3243,7 +3258,7 @@ nfsspec_close(struct vop_close_args *ap) (void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE), ap->a_td); } } - return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap)); + return (VOCALL(spec_vnode_vops, &ap->a_head)); } /* @@ -3262,7 +3277,7 @@ nfsfifo_read(struct vop_read_args *ap) */ np->n_flag |= NACC; getnanotime(&np->n_atim); - return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap)); + return (VOCALL(fifo_vnode_vops, &ap->a_head)); } /* @@ -3281,7 +3296,7 @@ nfsfifo_write(struct vop_write_args *ap) */ np->n_flag |= NUPD; getnanotime(&np->n_mtim); - return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap)); + return (VOCALL(fifo_vnode_vops, &ap->a_head)); } /* @@ -3316,6 +3331,6 @@ nfsfifo_close(struct vop_close_args *ap) (void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE), ap->a_td); } } - return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap)); + return (VOCALL(fifo_vnode_vops, &ap->a_head)); }