*
* @(#)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 $
*/
/*
* 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,
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;
};
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;
}
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);
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;
* 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) {
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);
*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);
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) {
}
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
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;
if (doit) {
nfsm_getfh(fhp, fhsize, 1);
if (NFS_CMPFH(dnp, fhp, fhsize)) {
- VREF(vp);
+ vref(vp);
newvp = vp;
np = dnp;
} else {
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);
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);
*/
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));
}
/*
*/
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));
}
/*
(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));
}
/*
*/
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));
}
/*
*/
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));
}
/*
(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));
}