FreeBSD/sys/fs/nfsserver/nfs_nfsdport.c
/*
 * Do the vnode op stuff for Open. Similar to nfsvno_createsub(), but
 * must handle nfsrv_opencheck() calls after any other access checks.
 */
Do the vnode op stuff for Open. Similar to nfsvno_createsub(), but
must handle nfsrv_opencheck() calls after any other access checks.
Do the vnode op stuff for Open . Similar to nfsvno_createsub () but must handle nfsrv_opencheck () calls after any other access checks .
void
nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
    nfsquad_t clientid, nfsv4stateid_t *stateidp, struct nfsstate *stp,
    int *exclusive_flagp, struct nfsvattr *nvap, int32_t *cverf, int create,
    NFSACL_T *aclp, nfsattrbit_t *attrbitp, struct ucred *cred, struct thread *p,
    struct nfsexstuff *exp, struct vnode **vpp)
{
	struct vnode *vp = NULL;
	u_quad_t tempsize;
	struct nfsexstuff nes;
	if (ndp->ni_vp == NULL)
		nd->nd_repstat = nfsrv_opencheck(clientid,
		    stateidp, stp, NULL, nd, p, nd->nd_repstat);
	if (!nd->nd_repstat) {
		if (ndp->ni_vp == NULL) {
			vrele(ndp->ni_startdir);
			nd->nd_repstat = VOP_CREATE(ndp->ni_dvp,
			    &ndp->ni_vp, &ndp->ni_cnd, &nvap->na_vattr);
			vput(ndp->ni_dvp);
			nfsvno_relpathbuf(ndp);
			if (!nd->nd_repstat) {
				if (*exclusive_flagp) {
					*exclusive_flagp = 0;
					NFSVNO_ATTRINIT(nvap);
					nvap->na_atime.tv_sec = cverf[0];
					nvap->na_atime.tv_nsec = cverf[1];
					nd->nd_repstat = VOP_SETATTR(ndp->ni_vp,
					    &nvap->na_vattr, cred);
					if (nd->nd_repstat != 0) {
						vput(ndp->ni_vp);
						ndp->ni_vp = NULL;
						nd->nd_repstat = NFSERR_NOTSUPP;
					}
				} else {
					nfsrv_fixattr(nd, ndp->ni_vp, nvap,
					    aclp, p, attrbitp, exp);
				}
			}
			vp = ndp->ni_vp;
		} else {
			if (ndp->ni_startdir)
				vrele(ndp->ni_startdir);
			nfsvno_relpathbuf(ndp);
			vp = ndp->ni_vp;
			if (create == NFSV4OPEN_CREATE) {
				if (ndp->ni_dvp == vp)
					vrele(ndp->ni_dvp);
				else
					vput(ndp->ni_dvp);
			}
			if (NFSVNO_ISSETSIZE(nvap) && vp->v_type == VREG) {
				if (ndp->ni_cnd.cn_flags & RDONLY)
					NFSVNO_SETEXRDONLY(&nes);
				else
					NFSVNO_EXINIT(&nes);
				nd->nd_repstat = nfsvno_accchk(vp, 
				    VWRITE, cred, &nes, p,
				    NFSACCCHK_NOOVERRIDE,
				    NFSACCCHK_VPISLOCKED, NULL);
				nd->nd_repstat = nfsrv_opencheck(clientid,
				    stateidp, stp, vp, nd, p, nd->nd_repstat);
				if (!nd->nd_repstat) {
					tempsize = nvap->na_size;
					NFSVNO_ATTRINIT(nvap);
					nvap->na_size = tempsize;
					nd->nd_repstat = VOP_SETATTR(vp,
					    &nvap->na_vattr, cred);
				}
			} else if (vp->v_type == VREG) {
				nd->nd_repstat = nfsrv_opencheck(clientid,
				    stateidp, stp, vp, nd, p, nd->nd_repstat);
			}
		}
	} else {
		if (ndp->ni_cnd.cn_flags & HASBUF)
			nfsvno_relpathbuf(ndp);
		if (ndp->ni_startdir && create == NFSV4OPEN_CREATE) {
			vrele(ndp->ni_startdir);
			if (ndp->ni_dvp == ndp->ni_vp)
				vrele(ndp->ni_dvp);
			else
				vput(ndp->ni_dvp);
			if (ndp->ni_vp)
				vput(ndp->ni_vp);
		}
	}
	*vpp = vp;
	NFSEXITCODE2(0, nd);
}
void nfsvno_open ( struct nfsrv_descript * nd , struct nameidata * ndp , nfsquad_t clientid , nfsv4stateid_t * stateidp , struct nfsstate * stp , int * exclusive_flagp , struct nfsvattr * nvap , int32_t * cverf , int create , NFSACL_T * aclp , nfsattrbit_t * attrbitp , struct ucred * cred , struct thread * p , struct nfsexstuff * exp , struct vnode * * vpp ) { struct vnode * vp = NULL ; u_quad_t tempsize ; struct nfsexstuff nes ; if ( ndp -> ni_vp == NULL ) nd -> nd_repstat = nfsrv_opencheck ( clientid , stateidp , stp , NULL , nd , p , nd -> nd_repstat ) ; if ( ! nd -> nd_repstat ) { if ( ndp -> ni_vp == NULL ) { vrele ( ndp -> ni_startdir ) ; nd -> nd_repstat = VOP_CREATE ( ndp -> ni_dvp , & ndp -> ni_vp , & ndp -> ni_cnd , & nvap -> na_vattr ) ; vput ( ndp -> ni_dvp ) ; nfsvno_relpathbuf ( ndp ) ; if ( ! nd -> nd_repstat ) { if ( * exclusive_flagp ) { * exclusive_flagp = 0 ; NFSVNO_ATTRINIT ( nvap ) ; nvap -> na_atime . tv_sec = cverf [ 0 ] ; nvap -> na_atime . tv_nsec = cverf [ 1 ] ; nd -> nd_repstat = VOP_SETATTR ( ndp -> ni_vp , & nvap -> na_vattr , cred ) ; if ( nd -> nd_repstat != 0 ) { vput ( ndp -> ni_vp ) ; ndp -> ni_vp = NULL ; nd -> nd_repstat = NFSERR_NOTSUPP ; } } else { nfsrv_fixattr ( nd , ndp -> ni_vp , nvap , aclp , p , attrbitp , exp ) ; } } vp = ndp -> ni_vp ; } else { if ( ndp -> ni_startdir ) vrele ( ndp -> ni_startdir ) ; nfsvno_relpathbuf ( ndp ) ; vp = ndp -> ni_vp ; if ( create == NFSV4OPEN_CREATE ) { if ( ndp -> ni_dvp == vp ) vrele ( ndp -> ni_dvp ) ; else vput ( ndp -> ni_dvp ) ; } if ( NFSVNO_ISSETSIZE ( nvap ) && vp -> v_type == VREG ) { if ( ndp -> ni_cnd . cn_flags & RDONLY ) NFSVNO_SETEXRDONLY ( & nes ) ; else NFSVNO_EXINIT ( & nes ) ; nd -> nd_repstat = nfsvno_accchk ( vp , VWRITE , cred , & nes , p , NFSACCCHK_NOOVERRIDE , NFSACCCHK_VPISLOCKED , NULL ) ; nd -> nd_repstat = nfsrv_opencheck ( clientid , stateidp , stp , vp , nd , p , nd -> nd_repstat ) ; if ( ! nd -> nd_repstat ) { tempsize = nvap -> na_size ; NFSVNO_ATTRINIT ( nvap ) ; nvap -> na_size = tempsize ; nd -> nd_repstat = VOP_SETATTR ( vp , & nvap -> na_vattr , cred ) ; } } else if ( vp -> v_type == VREG ) { nd -> nd_repstat = nfsrv_opencheck ( clientid , stateidp , stp , vp , nd , p , nd -> nd_repstat ) ; } } } else { if ( ndp -> ni_cnd . cn_flags & HASBUF ) nfsvno_relpathbuf ( ndp ) ; if ( ndp -> ni_startdir && create == NFSV4OPEN_CREATE ) { vrele ( ndp -> ni_startdir ) ; if ( ndp -> ni_dvp == ndp -> ni_vp ) vrele ( ndp -> ni_dvp ) ; else vput ( ndp -> ni_dvp ) ; if ( ndp -> ni_vp ) vput ( ndp -> ni_vp ) ; } } * vpp = vp ; NFSEXITCODE2 ( 0 , nd ) ; }
Do the vnode op stuff for Open.
Do the vnode op stuff for Open .