Changeset View
Standalone View
sys/fs/nfsserver/nfs_nfsdserv.c
Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
* function in nfsd_port.c | * function in nfsd_port.c | ||||
* 3 - build the rpc reply in an mbuf list | * 3 - build the rpc reply in an mbuf list | ||||
* For nfsv4, these functions are called for each Op within the Compound RPC. | * For nfsv4, these functions are called for each Op within the Compound RPC. | ||||
*/ | */ | ||||
#include <fs/nfs/nfsport.h> | #include <fs/nfs/nfsport.h> | ||||
#include <sys/extattr.h> | #include <sys/extattr.h> | ||||
#include <sys/filio.h> | #include <sys/filio.h> | ||||
#include <security/audit/audit.h> | |||||
/* Global vars */ | /* Global vars */ | ||||
extern u_int32_t newnfs_false, newnfs_true; | extern u_int32_t newnfs_false, newnfs_true; | ||||
extern enum vtype nv34tov_type[8]; | extern enum vtype nv34tov_type[8]; | ||||
extern struct timeval nfsboottime; | extern struct timeval nfsboottime; | ||||
extern int nfs_rootfhset; | extern int nfs_rootfhset; | ||||
extern int nfsrv_enable_crossmntpt; | extern int nfsrv_enable_crossmntpt; | ||||
extern int nfsrv_statehashsize; | extern int nfsrv_statehashsize; | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | nfsrvd_access(struct nfsrv_descript *nd, __unused int isdgram, | ||||
u_int32_t testmode, nfsmode, supported = 0; | u_int32_t testmode, nfsmode, supported = 0; | ||||
accmode_t deletebit; | accmode_t deletebit; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
nfsrv_postopattr(nd, 1, &nva); | nfsrv_postopattr(nd, 1, &nva); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); | NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); | ||||
nfsmode = fxdr_unsigned(u_int32_t, *tl); | nfsmode = fxdr_unsigned(u_int32_t, *tl); | ||||
AUDIT_NFSARG_MODE(nd, nfsmode); | |||||
if ((nd->nd_flag & ND_NFSV4) && | if ((nd->nd_flag & ND_NFSV4) && | ||||
(nfsmode & ~(NFSACCESS_READ | NFSACCESS_LOOKUP | | (nfsmode & ~(NFSACCESS_READ | NFSACCESS_LOOKUP | | ||||
NFSACCESS_MODIFY | NFSACCESS_EXTEND | NFSACCESS_DELETE | | NFSACCESS_MODIFY | NFSACCESS_EXTEND | NFSACCESS_DELETE | | ||||
NFSACCESS_EXECUTE | NFSACCESS_XAREAD | NFSACCESS_XAWRITE | | NFSACCESS_EXECUTE | NFSACCESS_XAREAD | NFSACCESS_XAWRITE | | ||||
NFSACCESS_XALIST))) { | NFSACCESS_XALIST))) { | ||||
nd->nd_repstat = NFSERR_INVAL; | nd->nd_repstat = NFSERR_INVAL; | ||||
vput(vp); | vput(vp); | ||||
goto out; | goto out; | ||||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram, | ||||
struct vnode *tvp = NULL; | struct vnode *tvp = NULL; | ||||
struct vattr va; | struct vattr va; | ||||
uint64_t mounted_on_fileno = 0; | uint64_t mounted_on_fileno = 0; | ||||
accmode_t accmode; | accmode_t accmode; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
if (nd->nd_repstat) | if (nd->nd_repstat) | ||||
goto out; | goto out; | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
if (nd->nd_flag & ND_NFSV4) { | if (nd->nd_flag & ND_NFSV4) { | ||||
error = nfsrv_getattrbits(nd, &attrbits, NULL, NULL); | error = nfsrv_getattrbits(nd, &attrbits, NULL, NULL); | ||||
if (error) { | if (error) { | ||||
vput(vp); | vput(vp); | ||||
rmacklem: Yes. All of these functions check for the ESTALE error case at
the beginning of them (line#247… | |||||
goto out; | goto out; | ||||
} | } | ||||
/* | /* | ||||
* Check for a referral. | * Check for a referral. | ||||
*/ | */ | ||||
refp = nfsv4root_getreferral(vp, NULL, 0); | refp = nfsv4root_getreferral(vp, NULL, 0); | ||||
if (refp != NULL) { | if (refp != NULL) { | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram, | ||||
nfsv4stateid_t stateid; | nfsv4stateid_t stateid; | ||||
NFSACL_T *aclp = NULL; | NFSACL_T *aclp = NULL; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
nfsrv_wcc(nd, preat_ret, &nva2, postat_ret, &nva); | nfsrv_wcc(nd, preat_ret, &nva2, postat_ret, &nva); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
#ifdef NFS4_ACL_EXTATTR_NAME | #ifdef NFS4_ACL_EXTATTR_NAME | ||||
aclp = acl_alloc(M_WAITOK); | aclp = acl_alloc(M_WAITOK); | ||||
aclp->acl_cnt = 0; | aclp->acl_cnt = 0; | ||||
#endif | #endif | ||||
gotproxystateid = 0; | gotproxystateid = 0; | ||||
NFSVNO_ATTRINIT(&nva); | NFSVNO_ATTRINIT(&nva); | ||||
if (nd->nd_flag & ND_NFSV4) { | if (nd->nd_flag & ND_NFSV4) { | ||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID); | NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID); | ||||
▲ Show 20 Lines • Show All 216 Lines • ▼ Show 20 Lines | NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, LOOKUP, | ||||
LOCKLEAF | SAVESTART); | LOCKLEAF | SAVESTART); | ||||
nfsvno_setpathbuf(&named, &bufp, &hashp); | nfsvno_setpathbuf(&named, &bufp, &hashp); | ||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | ||||
if (error) { | if (error) { | ||||
vrele(dp); | vrele(dp); | ||||
nfsvno_relpathbuf(&named); | nfsvno_relpathbuf(&named); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_UPATH1_VP(nd, p, named.ni_rootdir, dp, | |||||
named.ni_cnd.cn_pnbuf); | |||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
nd->nd_repstat = nfsvno_namei(nd, &named, dp, 0, exp, p, &dirp); | nd->nd_repstat = nfsvno_namei(nd, &named, dp, 0, exp, p, &dirp); | ||||
} else { | } else { | ||||
vrele(dp); | vrele(dp); | ||||
nfsvno_relpathbuf(&named); | nfsvno_relpathbuf(&named); | ||||
} | } | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
if (dirp) { | if (dirp) { | ||||
if (nd->nd_flag & ND_NFSV3) | if (nd->nd_flag & ND_NFSV3) | ||||
dattr_ret = nfsvno_getattr(dirp, &dattr, nd, p, | dattr_ret = nfsvno_getattr(dirp, &dattr, nd, p, | ||||
0, NULL); | 0, NULL); | ||||
vrele(dirp); | vrele(dirp); | ||||
} | } | ||||
if (nd->nd_flag & ND_NFSV3) | if (nd->nd_flag & ND_NFSV3) | ||||
nfsrv_postopattr(nd, dattr_ret, &dattr); | nfsrv_postopattr(nd, dattr_ret, &dattr); | ||||
goto out; | goto out; | ||||
} | } | ||||
if (named.ni_startdir) | if (named.ni_startdir) | ||||
vrele(named.ni_startdir); | vrele(named.ni_startdir); | ||||
nfsvno_relpathbuf(&named); | nfsvno_relpathbuf(&named); | ||||
vp = named.ni_vp; | vp = named.ni_vp; | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
if ((nd->nd_flag & ND_NFSV4) != 0 && !NFSVNO_EXPORTED(exp) && | if ((nd->nd_flag & ND_NFSV4) != 0 && !NFSVNO_EXPORTED(exp) && | ||||
vp->v_type != VDIR && vp->v_type != VLNK) | vp->v_type != VDIR && vp->v_type != VLNK) | ||||
/* | /* | ||||
* Only allow lookup of VDIR and VLNK for traversal of | * Only allow lookup of VDIR and VLNK for traversal of | ||||
* non-exported volumes during NFSv4 mounting. | * non-exported volumes during NFSv4 mounting. | ||||
*/ | */ | ||||
nd->nd_repstat = ENOENT; | nd->nd_repstat = ENOENT; | ||||
if (nd->nd_repstat == 0) | if (nd->nd_repstat == 0) | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | nfsrvd_readlink(struct nfsrv_descript *nd, __unused int isdgram, | ||||
int getret = 1, len; | int getret = 1, len; | ||||
struct nfsvattr nva; | struct nfsvattr nva; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
nfsrv_postopattr(nd, getret, &nva); | nfsrv_postopattr(nd, getret, &nva); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
if (vnode_vtype(vp) != VLNK) { | if (vnode_vtype(vp) != VLNK) { | ||||
if (nd->nd_flag & ND_NFSV2) | if (nd->nd_flag & ND_NFSV2) | ||||
nd->nd_repstat = ENXIO; | nd->nd_repstat = ENXIO; | ||||
else | else | ||||
nd->nd_repstat = EINVAL; | nd->nd_repstat = EINVAL; | ||||
} | } | ||||
if (!nd->nd_repstat) | if (!nd->nd_repstat) | ||||
nd->nd_repstat = nfsvno_readlink(vp, nd->nd_cred, p, | nd->nd_repstat = nfsvno_readlink(vp, nd->nd_cred, p, | ||||
Show All 35 Lines | nfsrvd_read(struct nfsrv_descript *nd, __unused int isdgram, | ||||
nfsv4stateid_t stateid; | nfsv4stateid_t stateid; | ||||
nfsquad_t clientid; | nfsquad_t clientid; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
nfsrv_postopattr(nd, getret, &nva); | nfsrv_postopattr(nd, getret, &nva); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
if (nd->nd_flag & ND_NFSV2) { | if (nd->nd_flag & ND_NFSV2) { | ||||
NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); | NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); | ||||
off = (off_t)fxdr_unsigned(u_int32_t, *tl++); | off = (off_t)fxdr_unsigned(u_int32_t, *tl++); | ||||
reqlen = fxdr_unsigned(int, *tl); | reqlen = fxdr_unsigned(int, *tl); | ||||
} else if (nd->nd_flag & ND_NFSV3) { | } else if (nd->nd_flag & ND_NFSV3) { | ||||
NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED); | NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED); | ||||
off = fxdr_hyper(tl); | off = fxdr_hyper(tl); | ||||
tl += 2; | tl += 2; | ||||
▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | nfsrvd_write(struct nfsrv_descript *nd, __unused int isdgram, | ||||
nfsquad_t clientid; | nfsquad_t clientid; | ||||
nfsattrbit_t attrbits; | nfsattrbit_t attrbits; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
nfsrv_wcc(nd, forat_ret, &forat, aftat_ret, &nva); | nfsrv_wcc(nd, forat_ret, &forat, aftat_ret, &nva); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
gotproxystateid = 0; | gotproxystateid = 0; | ||||
if (nd->nd_flag & ND_NFSV2) { | if (nd->nd_flag & ND_NFSV2) { | ||||
NFSM_DISSECT(tl, u_int32_t *, 4 * NFSX_UNSIGNED); | NFSM_DISSECT(tl, u_int32_t *, 4 * NFSX_UNSIGNED); | ||||
off = (off_t)fxdr_unsigned(u_int32_t, *++tl); | off = (off_t)fxdr_unsigned(u_int32_t, *++tl); | ||||
tl += 2; | tl += 2; | ||||
retlen = len = fxdr_unsigned(int32_t, *tl); | retlen = len = fxdr_unsigned(int32_t, *tl); | ||||
} else if (nd->nd_flag & ND_NFSV3) { | } else if (nd->nd_flag & ND_NFSV3) { | ||||
NFSM_DISSECT(tl, u_int32_t *, 5 * NFSX_UNSIGNED); | NFSM_DISSECT(tl, u_int32_t *, 5 * NFSX_UNSIGNED); | ||||
▲ Show 20 Lines • Show All 175 Lines • ▼ Show 20 Lines | if (nd->nd_repstat) { | ||||
goto out; | goto out; | ||||
} | } | ||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, | NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, | ||||
LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE); | LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE); | ||||
nfsvno_setpathbuf(&named, &bufp, &hashp); | nfsvno_setpathbuf(&named, &bufp, &hashp); | ||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | ||||
if (error) | if (error) | ||||
goto nfsmout; | goto nfsmout; | ||||
AUDIT_NFSARG_UPATH1_VP(nd, p, named.ni_rootdir, dp, | |||||
named.ni_cnd.cn_pnbuf); | |||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
NFSVNO_ATTRINIT(&nva); | NFSVNO_ATTRINIT(&nva); | ||||
if (nd->nd_flag & ND_NFSV2) { | if (nd->nd_flag & ND_NFSV2) { | ||||
NFSM_DISSECT(sp, struct nfsv2_sattr *, NFSX_V2SATTR); | NFSM_DISSECT(sp, struct nfsv2_sattr *, NFSX_V2SATTR); | ||||
vtyp = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode)); | vtyp = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode)); | ||||
if (vtyp == VNON) | if (vtyp == VNON) | ||||
vtyp = VREG; | vtyp = VREG; | ||||
Done Inline ActionsAs noted in a separate discussion, unlocking and relocking of a directory For example, at this time, the path has already been put through a "lookup" However, unlocking/relocking allows another thread to create an object of In general, I am opposed to unlocking/relocking vnodes in the code, rmacklem: As noted in a separate discussion, unlocking and relocking of a directory
vnode needs to be… | |||||
Done Inline ActionsThere is a problem with calling AUDIT_NFSARG_UPATH1_VP at the beginning (as you suggested to do it in nfsd_fhtovp in the mail) of the RPC operation: I don't have the pathname and rootdir info at that point, since the RPC extracts those data in nfsrvd_*. shivank: There is a problem with calling AUDIT_NFSARG_UPATH1_VP at the beginning (as you suggested to do… | |||||
NFSVNO_SETATTRVAL(&nva, type, vtyp); | NFSVNO_SETATTRVAL(&nva, type, vtyp); | ||||
NFSVNO_SETATTRVAL(&nva, mode, | NFSVNO_SETATTRVAL(&nva, mode, | ||||
nfstov_mode(sp->sa_mode)); | nfstov_mode(sp->sa_mode)); | ||||
AUDIT_NFSARG_MODE(nd, nva.na_mode); | |||||
switch (nva.na_type) { | switch (nva.na_type) { | ||||
case VREG: | case VREG: | ||||
tsize = fxdr_unsigned(int32_t, sp->sa_size); | tsize = fxdr_unsigned(int32_t, sp->sa_size); | ||||
if (tsize != -1) | if (tsize != -1) | ||||
NFSVNO_SETATTRVAL(&nva, size, | NFSVNO_SETATTRVAL(&nva, size, | ||||
(u_quad_t)tsize); | (u_quad_t)tsize); | ||||
break; | break; | ||||
case VCHR: | case VCHR: | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram, | ||||
* Iff doesn't exist, create it | * Iff doesn't exist, create it | ||||
* otherwise just truncate to 0 length | * otherwise just truncate to 0 length | ||||
* should I set the mode too ? | * should I set the mode too ? | ||||
*/ | */ | ||||
nd->nd_repstat = nfsvno_createsub(nd, &named, &vp, &nva, | nd->nd_repstat = nfsvno_createsub(nd, &named, &vp, &nva, | ||||
&exclusive_flag, cverf, rdev, exp); | &exclusive_flag, cverf, rdev, exp); | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
AUDIT_NFSARG_VNODE1(nd, named.ni_vp); | |||||
nd->nd_repstat = nfsvno_getfh(vp, &fh, p); | nd->nd_repstat = nfsvno_getfh(vp, &fh, p); | ||||
if (!nd->nd_repstat) | if (!nd->nd_repstat) | ||||
nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, | nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, | ||||
NULL); | NULL); | ||||
vput(vp); | vput(vp); | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
tverf[0] = nva.na_atime.tv_sec; | tverf[0] = nva.na_atime.tv_sec; | ||||
tverf[1] = nva.na_atime.tv_nsec; | tverf[1] = nva.na_atime.tv_nsec; | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | #ifdef NFS4_ACL_EXTATTR_NAME | ||||
acl_free(aclp); | acl_free(aclp); | ||||
#endif | #endif | ||||
goto out; | goto out; | ||||
} | } | ||||
} | } | ||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, cnflags | NOCACHE); | NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, cnflags | NOCACHE); | ||||
nfsvno_setpathbuf(&named, &bufp, &hashp); | nfsvno_setpathbuf(&named, &bufp, &hashp); | ||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | ||||
AUDIT_NFSARG_UPATH1_VP(nd, p, named.ni_rootdir, dp, | |||||
named.ni_cnd.cn_pnbuf); | |||||
if (error) | if (error) | ||||
goto nfsmout; | goto nfsmout; | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
if (nd->nd_flag & ND_NFSV3) { | if (nd->nd_flag & ND_NFSV3) { | ||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); | NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); | ||||
vtyp = nfsv34tov_type(*tl); | vtyp = nfsv34tov_type(*tl); | ||||
} | } | ||||
error = nfsrv_sattr(nd, NULL, &nva, &attrbits, aclp, p); | error = nfsrv_sattr(nd, NULL, &nva, &attrbits, aclp, p); | ||||
if (error) | if (error) | ||||
goto nfsmout; | goto nfsmout; | ||||
nva.na_type = vtyp; | nva.na_type = vtyp; | ||||
if (!nd->nd_repstat && (nd->nd_flag & ND_NFSV3) && | if (!nd->nd_repstat && (nd->nd_flag & ND_NFSV3) && | ||||
(vtyp == VCHR || vtyp == VBLK)) { | (vtyp == VCHR || vtyp == VBLK)) { | ||||
NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); | NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); | ||||
major = fxdr_unsigned(u_int32_t, *tl++); | major = fxdr_unsigned(u_int32_t, *tl++); | ||||
minor = fxdr_unsigned(u_int32_t, *tl); | minor = fxdr_unsigned(u_int32_t, *tl); | ||||
nva.na_rdev = NFSMAKEDEV(major, minor); | nva.na_rdev = NFSMAKEDEV(major, minor); | ||||
AUDIT_NFSARG_DEV(nd, nva.na_rdev); | |||||
} | } | ||||
} | } | ||||
dirfor_ret = nfsvno_getattr(dp, &dirfor, nd, p, 0, NULL); | dirfor_ret = nfsvno_getattr(dp, &dirfor, nd, p, 0, NULL); | ||||
if (!nd->nd_repstat && (nd->nd_flag & ND_NFSV4)) { | if (!nd->nd_repstat && (nd->nd_flag & ND_NFSV4)) { | ||||
if (!dirfor_ret && NFSVNO_ISSETGID(&nva) && | if (!dirfor_ret && NFSVNO_ISSETGID(&nva) && | ||||
dirfor.na_gid == nva.na_gid) | dirfor.na_gid == nva.na_gid) | ||||
NFSVNO_UNSET(&nva, gid); | NFSVNO_UNSET(&nva, gid); | ||||
Show All 18 Lines | #endif | ||||
* in va_mode, so we'll have to set a default here. | * in va_mode, so we'll have to set a default here. | ||||
*/ | */ | ||||
if (NFSVNO_NOTSETMODE(&nva)) { | if (NFSVNO_NOTSETMODE(&nva)) { | ||||
if (vtyp == VLNK) | if (vtyp == VLNK) | ||||
nva.na_mode = 0755; | nva.na_mode = 0755; | ||||
else | else | ||||
nva.na_mode = 0400; | nva.na_mode = 0400; | ||||
} | } | ||||
AUDIT_NFSARG_MODE(nd, nva.na_mode); | |||||
if (vtyp == VDIR) | if (vtyp == VDIR) | ||||
named.ni_cnd.cn_flags |= WILLBEDIR; | named.ni_cnd.cn_flags |= WILLBEDIR; | ||||
nd->nd_repstat = nfsvno_namei(nd, &named, dp, 0, exp, p, &dirp); | nd->nd_repstat = nfsvno_namei(nd, &named, dp, 0, exp, p, &dirp); | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
if (dirp) { | if (dirp) { | ||||
if (nd->nd_flag & ND_NFSV3) | if (nd->nd_flag & ND_NFSV3) | ||||
dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, | dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, | ||||
Show All 30 Lines | #endif | ||||
free(pathcp, M_TEMP); | free(pathcp, M_TEMP); | ||||
goto out; | goto out; | ||||
} | } | ||||
} | } | ||||
nd->nd_repstat = nfsvno_mknod(&named, &nva, nd->nd_cred, p); | nd->nd_repstat = nfsvno_mknod(&named, &nva, nd->nd_cred, p); | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
vp = named.ni_vp; | vp = named.ni_vp; | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
nfsrv_fixattr(nd, vp, &nva, aclp, p, &attrbits, exp); | nfsrv_fixattr(nd, vp, &nva, aclp, p, &attrbits, exp); | ||||
nd->nd_repstat = nfsvno_getfh(vp, fhp, p); | nd->nd_repstat = nfsvno_getfh(vp, fhp, p); | ||||
if ((nd->nd_flag & ND_NFSV3) && !nd->nd_repstat) | if ((nd->nd_flag & ND_NFSV3) && !nd->nd_repstat) | ||||
nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, | nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, | ||||
NULL); | NULL); | ||||
if (vpp != NULL && nd->nd_repstat == 0) { | if (vpp != NULL && nd->nd_repstat == 0) { | ||||
NFSVOPUNLOCK(vp); | NFSVOPUNLOCK(vp); | ||||
*vpp = vp; | *vpp = vp; | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, DELETE, | ||||
LOCKPARENT | LOCKLEAF); | LOCKPARENT | LOCKLEAF); | ||||
nfsvno_setpathbuf(&named, &bufp, &hashp); | nfsvno_setpathbuf(&named, &bufp, &hashp); | ||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | ||||
if (error) { | if (error) { | ||||
vput(dp); | vput(dp); | ||||
nfsvno_relpathbuf(&named); | nfsvno_relpathbuf(&named); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_UPATH1_VP(nd, p, named.ni_rootdir, dp, | |||||
named.ni_cnd.cn_pnbuf); | |||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
nd->nd_repstat = nfsvno_namei(nd, &named, dp, 1, exp, p, &dirp); | nd->nd_repstat = nfsvno_namei(nd, &named, dp, 1, exp, p, &dirp); | ||||
} else { | } else { | ||||
vput(dp); | vput(dp); | ||||
nfsvno_relpathbuf(&named); | nfsvno_relpathbuf(&named); | ||||
} | } | ||||
if (dirp) { | if (dirp) { | ||||
if (!(nd->nd_flag & ND_NFSV2)) { | if (!(nd->nd_flag & ND_NFSV2)) { | ||||
dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, | dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, | ||||
NULL); | NULL); | ||||
Done Inline ActionsSame as above w.r.t. unlocking/relocking a directory vnode. rmacklem: Same as above w.r.t. unlocking/relocking a directory vnode.
| |||||
} else { | } else { | ||||
vrele(dirp); | vrele(dirp); | ||||
dirp = NULL; | dirp = NULL; | ||||
} | } | ||||
} | } | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
AUDIT_NFSARG_VNODE1(nd, named.ni_vp); | |||||
if (nd->nd_flag & ND_NFSV4) { | if (nd->nd_flag & ND_NFSV4) { | ||||
if (vnode_vtype(named.ni_vp) == VDIR) | if (vnode_vtype(named.ni_vp) == VDIR) | ||||
nd->nd_repstat = nfsvno_rmdirsub(&named, 1, | nd->nd_repstat = nfsvno_rmdirsub(&named, 1, | ||||
nd->nd_cred, p, exp); | nd->nd_cred, p, exp); | ||||
else | else | ||||
nd->nd_repstat = nfsvno_removesub(&named, 1, | nd->nd_repstat = nfsvno_removesub(&named, 1, | ||||
nd->nd_cred, p, exp); | nd->nd_cred, p, exp); | ||||
} else if (nd->nd_procnum == NFSPROC_RMDIR) { | } else if (nd->nd_procnum == NFSPROC_RMDIR) { | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | nfsrvd_rename(struct nfsrv_descript *nd, int isdgram, | ||||
error = nfsrv_parsename(nd, bufp, hashp, &fromnd.ni_pathlen); | error = nfsrv_parsename(nd, bufp, hashp, &fromnd.ni_pathlen); | ||||
if (error) { | if (error) { | ||||
vput(dp); | vput(dp); | ||||
if (todp) | if (todp) | ||||
vrele(todp); | vrele(todp); | ||||
nfsvno_relpathbuf(&fromnd); | nfsvno_relpathbuf(&fromnd); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_UPATH1_VP(nd, p, fromnd.ni_rootdir, dp, | |||||
fromnd.ni_cnd.cn_pnbuf); | |||||
/* | /* | ||||
* Unlock dp in this code section, so it is unlocked before | * Unlock dp in this code section, so it is unlocked before | ||||
* tdp gets locked. This avoids a potential LOR if tdp is the | * tdp gets locked. This avoids a potential LOR if tdp is the | ||||
* parent directory of dp. | * parent directory of dp. | ||||
*/ | */ | ||||
if (nd->nd_flag & ND_NFSV4) { | if (nd->nd_flag & ND_NFSV4) { | ||||
tdp = todp; | tdp = todp; | ||||
tnes = *toexp; | tnes = *toexp; | ||||
if (dp != tdp) { | if (dp != tdp) { | ||||
NFSVOPUNLOCK(dp); | NFSVOPUNLOCK(dp); | ||||
Done Inline ActionsSame as above... rmacklem: Same as above... | |||||
/* Might lock tdp. */ | /* Might lock tdp. */ | ||||
tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd, p, 0, | tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd, p, 0, | ||||
NULL); | NULL); | ||||
} else { | } else { | ||||
tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd, p, 1, | tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd, p, 1, | ||||
NULL); | NULL); | ||||
NFSVOPUNLOCK(dp); | NFSVOPUNLOCK(dp); | ||||
} | } | ||||
Show All 38 Lines | if (error) { | ||||
if (tdp) | if (tdp) | ||||
vrele(tdp); | vrele(tdp); | ||||
vrele(dp); | vrele(dp); | ||||
nfsvno_relpathbuf(&fromnd); | nfsvno_relpathbuf(&fromnd); | ||||
nfsvno_relpathbuf(&tond); | nfsvno_relpathbuf(&tond); | ||||
goto out; | goto out; | ||||
} | } | ||||
} | } | ||||
AUDIT_NFSARG_UPATH2_VP(nd, p, tond.ni_rootdir, tdp, | |||||
tond.ni_cnd.cn_pnbuf); | |||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
if (nd->nd_flag & ND_NFSV3) { | if (nd->nd_flag & ND_NFSV3) { | ||||
nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret, | nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret, | ||||
&fdiraft); | &fdiraft); | ||||
nfsrv_wcc(nd, tdirfor_ret, &tdirfor, tdiraft_ret, | nfsrv_wcc(nd, tdirfor_ret, &tdirfor, tdiraft_ret, | ||||
&tdiraft); | &tdiraft); | ||||
} | } | ||||
if (tdp) | if (tdp) | ||||
Show All 17 Lines | if (nd->nd_repstat) { | ||||
} | } | ||||
if (fdirp) | if (fdirp) | ||||
vrele(fdirp); | vrele(fdirp); | ||||
if (tdp) | if (tdp) | ||||
vrele(tdp); | vrele(tdp); | ||||
nfsvno_relpathbuf(&tond); | nfsvno_relpathbuf(&tond); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, fromnd.ni_vp); | |||||
if (vnode_vtype(fromnd.ni_vp) == VDIR) | if (vnode_vtype(fromnd.ni_vp) == VDIR) | ||||
tond.ni_cnd.cn_flags |= WILLBEDIR; | tond.ni_cnd.cn_flags |= WILLBEDIR; | ||||
nd->nd_repstat = nfsvno_namei(nd, &tond, tdp, 0, &tnes, p, &tdirp); | nd->nd_repstat = nfsvno_namei(nd, &tond, tdp, 0, &tnes, p, &tdirp); | ||||
nd->nd_repstat = nfsvno_rename(&fromnd, &tond, nd->nd_repstat, | nd->nd_repstat = nfsvno_rename(&fromnd, &tond, nd->nd_repstat, | ||||
nd->nd_flag, nd->nd_cred, p); | nd->nd_flag, nd->nd_cred, p); | ||||
if (fdirp) | if (fdirp) | ||||
fdiraft_ret = nfsvno_getattr(fdirp, &fdiraft, nd, p, 0, NULL); | fdiraft_ret = nfsvno_getattr(fdirp, &fdiraft, nd, p, 0, NULL); | ||||
if (tdirp) | if (tdirp) | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | nfsrvd_link(struct nfsrv_descript *nd, int isdgram, | ||||
u_long *hashp; | u_long *hashp; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
nfsrv_postopattr(nd, getret, &at); | nfsrv_postopattr(nd, getret, &at); | ||||
nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft); | nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
NFSVOPUNLOCK(vp); | NFSVOPUNLOCK(vp); | ||||
if (vnode_vtype(vp) == VDIR) { | if (vnode_vtype(vp) == VDIR) { | ||||
if (nd->nd_flag & ND_NFSV4) | if (nd->nd_flag & ND_NFSV4) | ||||
nd->nd_repstat = NFSERR_ISDIR; | nd->nd_repstat = NFSERR_ISDIR; | ||||
else | else | ||||
nd->nd_repstat = NFSERR_INVAL; | nd->nd_repstat = NFSERR_INVAL; | ||||
if (tovp) | if (tovp) | ||||
vrele(tovp); | vrele(tovp); | ||||
Show All 14 Lines | if (nd->nd_flag & ND_NFSV4) { | ||||
NFSVOPUNLOCK(dp); | NFSVOPUNLOCK(dp); | ||||
} | } | ||||
} | } | ||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, | NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, | ||||
LOCKPARENT | SAVENAME | NOCACHE); | LOCKPARENT | SAVENAME | NOCACHE); | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
nfsvno_setpathbuf(&named, &bufp, &hashp); | nfsvno_setpathbuf(&named, &bufp, &hashp); | ||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | ||||
AUDIT_NFSARG_UPATH1_VP(nd, p, named.ni_rootdir, dp, | |||||
named.ni_cnd.cn_pnbuf); | |||||
if (error) { | if (error) { | ||||
vrele(vp); | vrele(vp); | ||||
if (dp) | if (dp) | ||||
vrele(dp); | vrele(dp); | ||||
nfsvno_relpathbuf(&named); | nfsvno_relpathbuf(&named); | ||||
goto out; | goto out; | ||||
} | } | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | nfsrvd_symlink(struct nfsrv_descript *nd, __unused int isdgram, | ||||
} | } | ||||
if (vpp) | if (vpp) | ||||
*vpp = NULL; | *vpp = NULL; | ||||
NFSVNO_ATTRINIT(&nva); | NFSVNO_ATTRINIT(&nva); | ||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, | NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, | ||||
LOCKPARENT | SAVESTART | NOCACHE); | LOCKPARENT | SAVESTART | NOCACHE); | ||||
nfsvno_setpathbuf(&named, &bufp, &hashp); | nfsvno_setpathbuf(&named, &bufp, &hashp); | ||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | ||||
if (!error && !nd->nd_repstat) | if (!error && !nd->nd_repstat) { | ||||
AUDIT_NFSARG_UPATH1_VP(nd, p, named.ni_rootdir, dp, | |||||
named.ni_cnd.cn_pnbuf); | |||||
error = nfsvno_getsymlink(nd, &nva, p, &pathcp, &pathlen); | error = nfsvno_getsymlink(nd, &nva, p, &pathcp, &pathlen); | ||||
} | |||||
if (error) { | if (error) { | ||||
vrele(dp); | vrele(dp); | ||||
nfsvno_relpathbuf(&named); | nfsvno_relpathbuf(&named); | ||||
goto out; | goto out; | ||||
} | } | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
nd->nd_repstat = nfsvno_namei(nd, &named, dp, 0, exp, p, &dirp); | nd->nd_repstat = nfsvno_namei(nd, &named, dp, 0, exp, p, &dirp); | ||||
} else { | } else { | ||||
Show All 11 Lines | nfsrvd_symlink(struct nfsrv_descript *nd, __unused int isdgram, | ||||
*/ | */ | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
if (dirp != NULL) | if (dirp != NULL) | ||||
dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, | dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, | ||||
NULL); | NULL); | ||||
nfsrvd_symlinksub(nd, &named, &nva, fhp, vpp, dirp, | nfsrvd_symlinksub(nd, &named, &nva, fhp, vpp, dirp, | ||||
&dirfor, &diraft, &diraft_ret, NULL, NULL, p, exp, | &dirfor, &diraft, &diraft_ret, NULL, NULL, p, exp, | ||||
pathcp, pathlen); | pathcp, pathlen); | ||||
AUDIT_NFSARG_VNODE1(nd, named.ni_vp); | |||||
} else if (dirp != NULL) { | } else if (dirp != NULL) { | ||||
dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, NULL); | dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, NULL); | ||||
vrele(dirp); | vrele(dirp); | ||||
} | } | ||||
if (pathcp) | if (pathcp) | ||||
free(pathcp, M_TEMP); | free(pathcp, M_TEMP); | ||||
if (nd->nd_flag & ND_NFSV3) { | if (nd->nd_flag & ND_NFSV3) { | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | if (nd->nd_repstat) { | ||||
goto out; | goto out; | ||||
} | } | ||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, | NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, | ||||
LOCKPARENT | SAVENAME | NOCACHE); | LOCKPARENT | SAVENAME | NOCACHE); | ||||
nfsvno_setpathbuf(&named, &bufp, &hashp); | nfsvno_setpathbuf(&named, &bufp, &hashp); | ||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen); | ||||
if (error) | if (error) | ||||
goto nfsmout; | goto nfsmout; | ||||
AUDIT_NFSARG_UPATH1_VP(nd, p, named.ni_rootdir, dp, | |||||
named.ni_cnd.cn_pnbuf); | |||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
NFSVNO_ATTRINIT(&nva); | NFSVNO_ATTRINIT(&nva); | ||||
if (nd->nd_flag & ND_NFSV3) { | if (nd->nd_flag & ND_NFSV3) { | ||||
error = nfsrv_sattr(nd, NULL, &nva, NULL, NULL, p); | error = nfsrv_sattr(nd, NULL, &nva, NULL, NULL, p); | ||||
if (error) | if (error) | ||||
goto nfsmout; | goto nfsmout; | ||||
} else { | } else { | ||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); | NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); | ||||
nva.na_mode = nfstov_mode(*tl++); | nva.na_mode = nfstov_mode(*tl++); | ||||
} | } | ||||
} | } | ||||
AUDIT_NFSARG_MODE(nd, nva.na_mode); | |||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
nd->nd_repstat = nfsvno_namei(nd, &named, dp, 0, exp, p, &dirp); | nd->nd_repstat = nfsvno_namei(nd, &named, dp, 0, exp, p, &dirp); | ||||
} else { | } else { | ||||
vrele(dp); | vrele(dp); | ||||
nfsvno_relpathbuf(&named); | nfsvno_relpathbuf(&named); | ||||
} | } | ||||
if (dirp != NULL && !(nd->nd_flag & ND_NFSV3)) { | if (dirp != NULL && !(nd->nd_flag & ND_NFSV3)) { | ||||
vrele(dirp); | vrele(dirp); | ||||
Show All 14 Lines | if (dirp != NULL) | ||||
dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, NULL); | dirfor_ret = nfsvno_getattr(dirp, &dirfor, nd, p, 0, NULL); | ||||
/* | /* | ||||
* Call nfsrvd_mkdirsub() for the code common to V4 as well. | * Call nfsrvd_mkdirsub() for the code common to V4 as well. | ||||
*/ | */ | ||||
nfsrvd_mkdirsub(nd, &named, &nva, fhp, vpp, dirp, &dirfor, &diraft, | nfsrvd_mkdirsub(nd, &named, &nva, fhp, vpp, dirp, &dirfor, &diraft, | ||||
&diraft_ret, NULL, NULL, p, exp); | &diraft_ret, NULL, NULL, p, exp); | ||||
AUDIT_NFSARG_VNODE1(nd, named.ni_vp); | |||||
if (nd->nd_flag & ND_NFSV3) { | if (nd->nd_flag & ND_NFSV3) { | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
(void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 1); | (void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 1); | ||||
nfsrv_postopattr(nd, 0, &nva); | nfsrv_postopattr(nd, 0, &nva); | ||||
} | } | ||||
nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft); | nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft); | ||||
} else if (!nd->nd_repstat) { | } else if (!nd->nd_repstat) { | ||||
(void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 0); | (void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 0); | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | nfsrvd_commit(struct nfsrv_descript *nd, __unused int isdgram, | ||||
vnode_t vp, __unused struct nfsexstuff *exp) | vnode_t vp, __unused struct nfsexstuff *exp) | ||||
{ | { | ||||
struct nfsvattr bfor, aft; | struct nfsvattr bfor, aft; | ||||
u_int32_t *tl; | u_int32_t *tl; | ||||
int error = 0, for_ret = 1, aft_ret = 1, cnt; | int error = 0, for_ret = 1, aft_ret = 1, cnt; | ||||
u_int64_t off; | u_int64_t off; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
nfsrv_wcc(nd, for_ret, &bfor, aft_ret, &aft); | nfsrv_wcc(nd, for_ret, &bfor, aft_ret, &aft); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
/* Return NFSERR_ISDIR in NFSv4 when commit on a directory. */ | /* Return NFSERR_ISDIR in NFSv4 when commit on a directory. */ | ||||
if (vp->v_type != VREG) { | if (vp->v_type != VREG) { | ||||
if (nd->nd_flag & ND_NFSV3) | if (nd->nd_flag & ND_NFSV3) | ||||
error = NFSERR_NOTSUPP; | error = NFSERR_NOTSUPP; | ||||
else | else | ||||
error = (vp->v_type == VDIR) ? NFSERR_ISDIR : NFSERR_INVAL; | error = (vp->v_type == VDIR) ? NFSERR_ISDIR : NFSERR_INVAL; | ||||
goto nfsmout; | goto nfsmout; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | nfsrvd_statfs(struct nfsrv_descript *nd, __unused int isdgram, | ||||
u_quad_t tval; | u_quad_t tval; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
sf = NULL; | sf = NULL; | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
nfsrv_postopattr(nd, getret, &at); | nfsrv_postopattr(nd, getret, &at); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
sf = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); | sf = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK); | ||||
nd->nd_repstat = nfsvno_statfs(vp, sf); | nd->nd_repstat = nfsvno_statfs(vp, sf); | ||||
getret = nfsvno_getattr(vp, &at, nd, p, 1, NULL); | getret = nfsvno_getattr(vp, &at, nd, p, 1, NULL); | ||||
vput(vp); | vput(vp); | ||||
if (nd->nd_flag & ND_NFSV3) | if (nd->nd_flag & ND_NFSV3) | ||||
nfsrv_postopattr(nd, getret, &at); | nfsrv_postopattr(nd, getret, &at); | ||||
if (nd->nd_repstat) | if (nd->nd_repstat) | ||||
goto out; | goto out; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | nfsrvd_fsinfo(struct nfsrv_descript *nd, int isdgram, | ||||
int getret = 1; | int getret = 1; | ||||
struct nfsvattr at; | struct nfsvattr at; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
nfsrv_postopattr(nd, getret, &at); | nfsrv_postopattr(nd, getret, &at); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
getret = nfsvno_getattr(vp, &at, nd, p, 1, NULL); | getret = nfsvno_getattr(vp, &at, nd, p, 1, NULL); | ||||
nfsvno_getfs(&fs, isdgram); | nfsvno_getfs(&fs, isdgram); | ||||
vput(vp); | vput(vp); | ||||
nfsrv_postopattr(nd, getret, &at); | nfsrv_postopattr(nd, getret, &at); | ||||
NFSM_BUILD(tl, u_int32_t *, NFSX_V3FSINFO); | NFSM_BUILD(tl, u_int32_t *, NFSX_V3FSINFO); | ||||
*tl++ = txdr_unsigned(fs.fs_rtmax); | *tl++ = txdr_unsigned(fs.fs_rtmax); | ||||
*tl++ = txdr_unsigned(fs.fs_rtpref); | *tl++ = txdr_unsigned(fs.fs_rtpref); | ||||
*tl++ = txdr_unsigned(fs.fs_rtmult); | *tl++ = txdr_unsigned(fs.fs_rtmult); | ||||
Show All 24 Lines | nfsrvd_pathconf(struct nfsrv_descript *nd, __unused int isdgram, | ||||
long linkmax, namemax, chownres, notrunc; | long linkmax, namemax, chownres, notrunc; | ||||
struct nfsvattr at; | struct nfsvattr at; | ||||
struct thread *p = curthread; | struct thread *p = curthread; | ||||
if (nd->nd_repstat) { | if (nd->nd_repstat) { | ||||
nfsrv_postopattr(nd, getret, &at); | nfsrv_postopattr(nd, getret, &at); | ||||
goto out; | goto out; | ||||
} | } | ||||
AUDIT_NFSARG_VNODE1(nd, vp); | |||||
nd->nd_repstat = nfsvno_pathconf(vp, _PC_LINK_MAX, &linkmax, | nd->nd_repstat = nfsvno_pathconf(vp, _PC_LINK_MAX, &linkmax, | ||||
nd->nd_cred, p); | nd->nd_cred, p); | ||||
if (!nd->nd_repstat) | if (!nd->nd_repstat) | ||||
nd->nd_repstat = nfsvno_pathconf(vp, _PC_NAME_MAX, &namemax, | nd->nd_repstat = nfsvno_pathconf(vp, _PC_NAME_MAX, &namemax, | ||||
nd->nd_cred, p); | nd->nd_cred, p); | ||||
if (!nd->nd_repstat) | if (!nd->nd_repstat) | ||||
nd->nd_repstat=nfsvno_pathconf(vp, _PC_CHOWN_RESTRICTED, | nd->nd_repstat = nfsvno_pathconf(vp, _PC_CHOWN_RESTRICTED, | ||||
&chownres, nd->nd_cred, p); | &chownres, nd->nd_cred, p); | ||||
if (!nd->nd_repstat) | if (!nd->nd_repstat) | ||||
nd->nd_repstat = nfsvno_pathconf(vp, _PC_NO_TRUNC, ¬runc, | nd->nd_repstat = nfsvno_pathconf(vp, _PC_NO_TRUNC, ¬runc, | ||||
nd->nd_cred, p); | nd->nd_cred, p); | ||||
getret = nfsvno_getattr(vp, &at, nd, p, 1, NULL); | getret = nfsvno_getattr(vp, &at, nd, p, 1, NULL); | ||||
vput(vp); | vput(vp); | ||||
nfsrv_postopattr(nd, getret, &at); | nfsrv_postopattr(nd, getret, &at); | ||||
if (!nd->nd_repstat) { | if (!nd->nd_repstat) { | ||||
▲ Show 20 Lines • Show All 3,612 Lines • Show Last 20 Lines |
Yes. All of these functions check for the ESTALE error case at
the beginning of them (line#247 below for example).
It might be better to put this call after the error check.
(after line#248 below, for example)