Since the VFS_LOCK_GIANT() code in the experimental NFS
server is broken and the major file systems are now all mpsafe, modify the server so that it will only export mpsafe file systems. This was discussed on freebsd-fs@ and removes a fair bit of crufty code. MFC after: 12 days
This commit is contained in:
parent
e9dc47ee81
commit
8974bc2f3a
@ -570,8 +570,6 @@ int nfsvno_pathconf(vnode_t, int, register_t *, struct ucred *,
|
|||||||
NFSPROC_T *);
|
NFSPROC_T *);
|
||||||
vnode_t nfsvno_getvp(fhandle_t *);
|
vnode_t nfsvno_getvp(fhandle_t *);
|
||||||
int nfsvno_advlock(vnode_t, int, u_int64_t, u_int64_t, NFSPROC_T *);
|
int nfsvno_advlock(vnode_t, int, u_int64_t, u_int64_t, NFSPROC_T *);
|
||||||
void nfsvno_unlockvfs(mount_t);
|
|
||||||
int nfsvno_lockvfs(mount_t);
|
|
||||||
int nfsrv_v4rootexport(void *, struct ucred *, NFSPROC_T *);
|
int nfsrv_v4rootexport(void *, struct ucred *, NFSPROC_T *);
|
||||||
int nfsvno_testexp(struct nfsrv_descript *, struct nfsexstuff *);
|
int nfsvno_testexp(struct nfsrv_descript *, struct nfsexstuff *);
|
||||||
uint32_t nfsrv_hashfh(fhandle_t *);
|
uint32_t nfsrv_hashfh(fhandle_t *);
|
||||||
|
@ -52,7 +52,6 @@
|
|||||||
* needs to be returned by nfsd_fhtovp().
|
* needs to be returned by nfsd_fhtovp().
|
||||||
*/
|
*/
|
||||||
struct nfsexstuff {
|
struct nfsexstuff {
|
||||||
int nes_vfslocked; /* required for all ports */
|
|
||||||
int nes_exflag; /* export flags */
|
int nes_exflag; /* export flags */
|
||||||
int nes_numsecflavor; /* # of security flavors */
|
int nes_numsecflavor; /* # of security flavors */
|
||||||
int nes_secflavors[MAXSECFLAVORS]; /* and the flavors */
|
int nes_secflavors[MAXSECFLAVORS]; /* and the flavors */
|
||||||
|
@ -332,18 +332,7 @@ nfsvno_namei(struct nfsrv_descript *nd, struct nameidata *ndp,
|
|||||||
* In either case ni_startdir will be dereferenced and NULLed
|
* In either case ni_startdir will be dereferenced and NULLed
|
||||||
* out.
|
* out.
|
||||||
*/
|
*/
|
||||||
if (exp->nes_vfslocked)
|
|
||||||
ndp->ni_cnd.cn_flags |= GIANTHELD;
|
|
||||||
error = lookup(ndp);
|
error = lookup(ndp);
|
||||||
/*
|
|
||||||
* The Giant lock should only change when
|
|
||||||
* crossing mount points.
|
|
||||||
*/
|
|
||||||
if (crossmnt) {
|
|
||||||
exp->nes_vfslocked =
|
|
||||||
(ndp->ni_cnd.cn_flags & GIANTHELD) != 0;
|
|
||||||
ndp->ni_cnd.cn_flags &= ~GIANTHELD;
|
|
||||||
}
|
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2471,7 +2460,10 @@ nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct sockaddr *nam,
|
|||||||
|
|
||||||
*credp = NULL;
|
*credp = NULL;
|
||||||
exp->nes_numsecflavor = 0;
|
exp->nes_numsecflavor = 0;
|
||||||
error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
|
if (VFS_NEEDSGIANT(mp))
|
||||||
|
error = ESTALE;
|
||||||
|
else
|
||||||
|
error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
/* Make sure the server replies ESTALE to the client. */
|
/* Make sure the server replies ESTALE to the client. */
|
||||||
error = ESTALE;
|
error = ESTALE;
|
||||||
@ -2521,19 +2513,8 @@ nfsvno_pathconf(struct vnode *vp, int flag, register_t *retf,
|
|||||||
* - get vp and export rights by calling nfsvno_fhtovp()
|
* - get vp and export rights by calling nfsvno_fhtovp()
|
||||||
* - if cred->cr_uid == 0 or MNT_EXPORTANON set it to credanon
|
* - if cred->cr_uid == 0 or MNT_EXPORTANON set it to credanon
|
||||||
* for AUTH_SYS
|
* for AUTH_SYS
|
||||||
* Also handle getting the Giant lock for the file system,
|
* - if mpp != NULL, return the mount point so that it can
|
||||||
* as required:
|
* be used for vn_finished_write() by the caller
|
||||||
* - if same mount point as *mpp
|
|
||||||
* do nothing
|
|
||||||
* else if *mpp == NULL
|
|
||||||
* if already locked
|
|
||||||
* leave it locked
|
|
||||||
* else
|
|
||||||
* call VFS_LOCK_GIANT()
|
|
||||||
* else
|
|
||||||
* if already locked
|
|
||||||
* unlock Giant
|
|
||||||
* call VFS_LOCK_GIANT()
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
|
nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
|
||||||
@ -2549,27 +2530,14 @@ nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
|
|||||||
* Check for the special case of the nfsv4root_fh.
|
* Check for the special case of the nfsv4root_fh.
|
||||||
*/
|
*/
|
||||||
mp = vfs_busyfs(&fhp->fh_fsid);
|
mp = vfs_busyfs(&fhp->fh_fsid);
|
||||||
|
if (mpp != NULL)
|
||||||
|
*mpp = mp;
|
||||||
if (mp == NULL) {
|
if (mp == NULL) {
|
||||||
*vpp = NULL;
|
*vpp = NULL;
|
||||||
nd->nd_repstat = ESTALE;
|
nd->nd_repstat = ESTALE;
|
||||||
if (*mpp && exp->nes_vfslocked)
|
|
||||||
VFS_UNLOCK_GIANT(*mpp);
|
|
||||||
*mpp = NULL;
|
|
||||||
exp->nes_vfslocked = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Now, handle Giant for the file system.
|
|
||||||
*/
|
|
||||||
if (*mpp != NULL && *mpp != mp && exp->nes_vfslocked) {
|
|
||||||
VFS_UNLOCK_GIANT(*mpp);
|
|
||||||
exp->nes_vfslocked = 0;
|
|
||||||
}
|
|
||||||
if (!exp->nes_vfslocked && *mpp != mp)
|
|
||||||
exp->nes_vfslocked = VFS_LOCK_GIANT(mp);
|
|
||||||
|
|
||||||
*mpp = mp;
|
|
||||||
if (startwrite)
|
if (startwrite)
|
||||||
vn_start_write(NULL, mpp, V_WAIT);
|
vn_start_write(NULL, mpp, V_WAIT);
|
||||||
|
|
||||||
@ -2633,12 +2601,9 @@ nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
|
|||||||
if (nd->nd_repstat) {
|
if (nd->nd_repstat) {
|
||||||
if (startwrite)
|
if (startwrite)
|
||||||
vn_finished_write(mp);
|
vn_finished_write(mp);
|
||||||
if (exp->nes_vfslocked) {
|
|
||||||
VFS_UNLOCK_GIANT(mp);
|
|
||||||
exp->nes_vfslocked = 0;
|
|
||||||
}
|
|
||||||
*vpp = NULL;
|
*vpp = NULL;
|
||||||
*mpp = NULL;
|
if (mpp != NULL)
|
||||||
|
*mpp = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2839,29 +2804,6 @@ nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first,
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Unlock an underlying local file system.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
nfsvno_unlockvfs(struct mount *mp)
|
|
||||||
{
|
|
||||||
|
|
||||||
VFS_UNLOCK_GIANT(mp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Lock an underlying file system, as required, and return
|
|
||||||
* whether or not it is locked.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
nfsvno_lockvfs(struct mount *mp)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = VFS_LOCK_GIANT(mp);
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the nfsv4 root exports.
|
* Check the nfsv4 root exports.
|
||||||
*/
|
*/
|
||||||
|
@ -1351,7 +1351,6 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
|
|||||||
struct nfsvattr fdirfor, fdiraft, tdirfor, tdiraft;
|
struct nfsvattr fdirfor, fdiraft, tdirfor, tdiraft;
|
||||||
struct nfsexstuff tnes;
|
struct nfsexstuff tnes;
|
||||||
struct nfsrvfh tfh;
|
struct nfsrvfh tfh;
|
||||||
mount_t mp = NULL;
|
|
||||||
char *bufp, *tbufp = NULL;
|
char *bufp, *tbufp = NULL;
|
||||||
u_long *hashp;
|
u_long *hashp;
|
||||||
|
|
||||||
@ -1387,9 +1386,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
nd->nd_cred->cr_uid = nd->nd_saveduid;
|
nd->nd_cred->cr_uid = nd->nd_saveduid;
|
||||||
/* Won't lock vfs if already locked, mp == NULL */
|
nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, 0, p);
|
||||||
tnes.nes_vfslocked = exp->nes_vfslocked;
|
|
||||||
nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, &mp, 0, p);
|
|
||||||
if (tdp) {
|
if (tdp) {
|
||||||
tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
|
tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
|
||||||
p, 1);
|
p, 1);
|
||||||
@ -1401,12 +1398,8 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
|
|||||||
if (!nd->nd_repstat) {
|
if (!nd->nd_repstat) {
|
||||||
error = nfsrv_parsename(nd, tbufp, hashp, &tond.ni_pathlen);
|
error = nfsrv_parsename(nd, tbufp, hashp, &tond.ni_pathlen);
|
||||||
if (error) {
|
if (error) {
|
||||||
if (tdp) {
|
if (tdp)
|
||||||
if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
|
|
||||||
!(nd->nd_flag & ND_NFSV4))
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
vrele(tdp);
|
vrele(tdp);
|
||||||
}
|
|
||||||
vput(dp);
|
vput(dp);
|
||||||
nfsvno_relpathbuf(&fromnd);
|
nfsvno_relpathbuf(&fromnd);
|
||||||
nfsvno_relpathbuf(&tond);
|
nfsvno_relpathbuf(&tond);
|
||||||
@ -1420,12 +1413,8 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
|
|||||||
nfsrv_wcc(nd, tdirfor_ret, &tdirfor, tdiraft_ret,
|
nfsrv_wcc(nd, tdirfor_ret, &tdirfor, tdiraft_ret,
|
||||||
&tdiraft);
|
&tdiraft);
|
||||||
}
|
}
|
||||||
if (tdp) {
|
if (tdp)
|
||||||
if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
|
|
||||||
!(nd->nd_flag & ND_NFSV4))
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
vrele(tdp);
|
vrele(tdp);
|
||||||
}
|
|
||||||
vput(dp);
|
vput(dp);
|
||||||
nfsvno_relpathbuf(&fromnd);
|
nfsvno_relpathbuf(&fromnd);
|
||||||
nfsvno_relpathbuf(&tond);
|
nfsvno_relpathbuf(&tond);
|
||||||
@ -1445,12 +1434,8 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
|
|||||||
}
|
}
|
||||||
if (fdirp)
|
if (fdirp)
|
||||||
vrele(fdirp);
|
vrele(fdirp);
|
||||||
if (tdp) {
|
if (tdp)
|
||||||
if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
|
|
||||||
!(nd->nd_flag & ND_NFSV4))
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
vrele(tdp);
|
vrele(tdp);
|
||||||
}
|
|
||||||
nfsvno_relpathbuf(&tond);
|
nfsvno_relpathbuf(&tond);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -1465,9 +1450,6 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
|
|||||||
if (tdirp)
|
if (tdirp)
|
||||||
tdiraft_ret = nfsvno_getattr(tdirp, &tdiraft, nd->nd_cred, p,
|
tdiraft_ret = nfsvno_getattr(tdirp, &tdiraft, nd->nd_cred, p,
|
||||||
0);
|
0);
|
||||||
if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
|
|
||||||
!(nd->nd_flag & ND_NFSV4))
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
if (fdirp)
|
if (fdirp)
|
||||||
vrele(fdirp);
|
vrele(fdirp);
|
||||||
if (tdirp)
|
if (tdirp)
|
||||||
@ -1505,7 +1487,6 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
|
|||||||
struct nfsvattr dirfor, diraft, at;
|
struct nfsvattr dirfor, diraft, at;
|
||||||
struct nfsexstuff tnes;
|
struct nfsexstuff tnes;
|
||||||
struct nfsrvfh dfh;
|
struct nfsrvfh dfh;
|
||||||
mount_t mp = NULL;
|
|
||||||
char *bufp;
|
char *bufp;
|
||||||
u_long *hashp;
|
u_long *hashp;
|
||||||
|
|
||||||
@ -1541,9 +1522,7 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
|
|||||||
/* tovp is always NULL unless NFSv4 */
|
/* tovp is always NULL unless NFSv4 */
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
/* Won't lock vfs if already locked, mp == NULL */
|
nfsd_fhtovp(nd, &dfh, LK_EXCLUSIVE, &dp, &tnes, NULL, 0,
|
||||||
tnes.nes_vfslocked = exp->nes_vfslocked;
|
|
||||||
nfsd_fhtovp(nd, &dfh, LK_EXCLUSIVE, &dp, &tnes, &mp, 0,
|
|
||||||
p);
|
p);
|
||||||
if (dp)
|
if (dp)
|
||||||
NFSVOPUNLOCK(dp, 0, p);
|
NFSVOPUNLOCK(dp, 0, p);
|
||||||
@ -1556,12 +1535,8 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
|
|||||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
|
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
|
||||||
if (error) {
|
if (error) {
|
||||||
vrele(vp);
|
vrele(vp);
|
||||||
if (dp) {
|
if (dp)
|
||||||
if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
|
|
||||||
!(nd->nd_flag & ND_NFSV4))
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
vrele(dp);
|
vrele(dp);
|
||||||
}
|
|
||||||
nfsvno_relpathbuf(&named);
|
nfsvno_relpathbuf(&named);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@ -1591,9 +1566,6 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
|
|||||||
diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p, 0);
|
diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p, 0);
|
||||||
vrele(dirp);
|
vrele(dirp);
|
||||||
}
|
}
|
||||||
if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
|
|
||||||
!(nd->nd_flag & ND_NFSV4))
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
vrele(vp);
|
vrele(vp);
|
||||||
if (nd->nd_flag & ND_NFSV3) {
|
if (nd->nd_flag & ND_NFSV3) {
|
||||||
nfsrv_postopattr(nd, getret, &at);
|
nfsrv_postopattr(nd, getret, &at);
|
||||||
@ -3101,7 +3073,6 @@ nfsrvd_secinfo(struct nfsrv_descript *nd, int isdgram,
|
|||||||
vnode_t dirp = NULL, vp;
|
vnode_t dirp = NULL, vp;
|
||||||
struct nfsrvfh fh;
|
struct nfsrvfh fh;
|
||||||
struct nfsexstuff retnes;
|
struct nfsexstuff retnes;
|
||||||
mount_t mp;
|
|
||||||
u_int32_t *sizp;
|
u_int32_t *sizp;
|
||||||
int error, savflag, i;
|
int error, savflag, i;
|
||||||
char *bufp;
|
char *bufp;
|
||||||
@ -3134,12 +3105,10 @@ nfsrvd_secinfo(struct nfsrv_descript *nd, int isdgram,
|
|||||||
fh.nfsrvfh_len = NFSX_MYFH;
|
fh.nfsrvfh_len = NFSX_MYFH;
|
||||||
vp = named.ni_vp;
|
vp = named.ni_vp;
|
||||||
nd->nd_repstat = nfsvno_getfh(vp, (fhandle_t *)fh.nfsrvfh_data, p);
|
nd->nd_repstat = nfsvno_getfh(vp, (fhandle_t *)fh.nfsrvfh_data, p);
|
||||||
mp = vnode_mount(vp); /* so it won't try to re-lock filesys */
|
|
||||||
retnes.nes_vfslocked = exp->nes_vfslocked;
|
|
||||||
vput(vp);
|
vput(vp);
|
||||||
savflag = nd->nd_flag;
|
savflag = nd->nd_flag;
|
||||||
if (!nd->nd_repstat) {
|
if (!nd->nd_repstat) {
|
||||||
nfsd_fhtovp(nd, &fh, LK_SHARED, &vp, &retnes, &mp, 0, p);
|
nfsd_fhtovp(nd, &fh, LK_SHARED, &vp, &retnes, NULL, 0, p);
|
||||||
if (vp)
|
if (vp)
|
||||||
vput(vp);
|
vput(vp);
|
||||||
}
|
}
|
||||||
|
@ -386,7 +386,6 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
|
|||||||
lktype = LK_SHARED;
|
lktype = LK_SHARED;
|
||||||
else
|
else
|
||||||
lktype = LK_EXCLUSIVE;
|
lktype = LK_EXCLUSIVE;
|
||||||
nes.nes_vfslocked = 0;
|
|
||||||
if (nd->nd_flag & ND_PUBLOOKUP)
|
if (nd->nd_flag & ND_PUBLOOKUP)
|
||||||
nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes,
|
nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes,
|
||||||
&mp, nfs_writerpc[nd->nd_procnum], p);
|
&mp, nfs_writerpc[nd->nd_procnum], p);
|
||||||
@ -415,12 +414,8 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
|
|||||||
if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
|
if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
|
||||||
*nd->nd_errp = nfsd_errmap(nd);
|
*nd->nd_errp = nfsd_errmap(nd);
|
||||||
NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
|
NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
|
||||||
if (mp != NULL) {
|
if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
|
||||||
if (nfs_writerpc[nd->nd_procnum])
|
vn_finished_write(mp);
|
||||||
NFS_ENDWRITE(mp);
|
|
||||||
if (nes.nes_vfslocked)
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,12 +440,8 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
|
|||||||
error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
|
error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
|
||||||
vp, p, &nes);
|
vp, p, &nes);
|
||||||
}
|
}
|
||||||
if (mp) {
|
if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
|
||||||
if (nfs_writerpc[nd->nd_procnum])
|
vn_finished_write(mp);
|
||||||
NFS_ENDWRITE(mp);
|
|
||||||
if (nes.nes_vfslocked)
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
}
|
|
||||||
NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
|
NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -498,9 +489,10 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
|
|||||||
u_char tag[NFSV4_SMALLSTR + 1], *tagstr;
|
u_char tag[NFSV4_SMALLSTR + 1], *tagstr;
|
||||||
vnode_t vp, nvp, savevp;
|
vnode_t vp, nvp, savevp;
|
||||||
struct nfsrvfh fh;
|
struct nfsrvfh fh;
|
||||||
mount_t mp, savemp, temp_mp = NULL;
|
mount_t new_mp, temp_mp = NULL;
|
||||||
struct ucred *credanon;
|
struct ucred *credanon;
|
||||||
struct nfsexstuff nes, vpnes, savevpnes;
|
struct nfsexstuff nes, vpnes, savevpnes;
|
||||||
|
fsid_t cur_fsid, save_fsid;
|
||||||
static u_int64_t compref = 0;
|
static u_int64_t compref = 0;
|
||||||
|
|
||||||
NFSVNO_EXINIT(&vpnes);
|
NFSVNO_EXINIT(&vpnes);
|
||||||
@ -597,8 +589,8 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
savevp = vp = NULL;
|
savevp = vp = NULL;
|
||||||
savevpnes.nes_vfslocked = vpnes.nes_vfslocked = 0;
|
save_fsid.val[0] = save_fsid.val[1] = 0;
|
||||||
savemp = mp = NULL;
|
cur_fsid.val[0] = cur_fsid.val[1] = 0;
|
||||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||||
taglen = fxdr_unsigned(int, *tl);
|
taglen = fxdr_unsigned(int, *tl);
|
||||||
if (taglen < 0) {
|
if (taglen < 0) {
|
||||||
@ -704,46 +696,44 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
|
|||||||
error = nfsrv_mtofh(nd, &fh);
|
error = nfsrv_mtofh(nd, &fh);
|
||||||
if (error)
|
if (error)
|
||||||
goto nfsmout;
|
goto nfsmout;
|
||||||
if (!nd->nd_repstat) {
|
if (!nd->nd_repstat)
|
||||||
nes.nes_vfslocked = vpnes.nes_vfslocked;
|
nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes,
|
||||||
nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes, &mp,
|
NULL, 0, p);
|
||||||
0, p);
|
|
||||||
}
|
|
||||||
/* For now, allow this for non-export FHs */
|
/* For now, allow this for non-export FHs */
|
||||||
if (!nd->nd_repstat) {
|
if (!nd->nd_repstat) {
|
||||||
if (vp)
|
if (vp)
|
||||||
vrele(vp);
|
vrele(vp);
|
||||||
vp = nvp;
|
vp = nvp;
|
||||||
NFSVOPUNLOCK(vp, 0, p);
|
cur_fsid = vp->v_mount->mnt_stat.f_fsid;
|
||||||
|
VOP_UNLOCK(vp, 0);
|
||||||
vpnes = nes;
|
vpnes = nes;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NFSV4OP_PUTPUBFH:
|
case NFSV4OP_PUTPUBFH:
|
||||||
if (nfs_pubfhset) {
|
if (nfs_pubfhset)
|
||||||
nes.nes_vfslocked = vpnes.nes_vfslocked;
|
|
||||||
nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp,
|
nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp,
|
||||||
&nes, &mp, 0, p);
|
&nes, NULL, 0, p);
|
||||||
} else {
|
else
|
||||||
nd->nd_repstat = NFSERR_NOFILEHANDLE;
|
nd->nd_repstat = NFSERR_NOFILEHANDLE;
|
||||||
}
|
|
||||||
if (!nd->nd_repstat) {
|
if (!nd->nd_repstat) {
|
||||||
if (vp)
|
if (vp)
|
||||||
vrele(vp);
|
vrele(vp);
|
||||||
vp = nvp;
|
vp = nvp;
|
||||||
NFSVOPUNLOCK(vp, 0, p);
|
cur_fsid = vp->v_mount->mnt_stat.f_fsid;
|
||||||
|
VOP_UNLOCK(vp, 0);
|
||||||
vpnes = nes;
|
vpnes = nes;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NFSV4OP_PUTROOTFH:
|
case NFSV4OP_PUTROOTFH:
|
||||||
if (nfs_rootfhset) {
|
if (nfs_rootfhset) {
|
||||||
nes.nes_vfslocked = vpnes.nes_vfslocked;
|
|
||||||
nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
|
nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
|
||||||
&nes, &mp, 0, p);
|
&nes, NULL, 0, p);
|
||||||
if (!nd->nd_repstat) {
|
if (!nd->nd_repstat) {
|
||||||
if (vp)
|
if (vp)
|
||||||
vrele(vp);
|
vrele(vp);
|
||||||
vp = nvp;
|
vp = nvp;
|
||||||
NFSVOPUNLOCK(vp, 0, p);
|
cur_fsid = vp->v_mount->mnt_stat.f_fsid;
|
||||||
|
VOP_UNLOCK(vp, 0);
|
||||||
vpnes = nes;
|
vpnes = nes;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@ -759,7 +749,7 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
|
|||||||
VREF(vp);
|
VREF(vp);
|
||||||
savevp = vp;
|
savevp = vp;
|
||||||
savevpnes = vpnes;
|
savevpnes = vpnes;
|
||||||
savemp = mp;
|
save_fsid = cur_fsid;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nd->nd_repstat = NFSERR_NOFILEHANDLE;
|
nd->nd_repstat = NFSERR_NOFILEHANDLE;
|
||||||
@ -771,23 +761,10 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
|
|||||||
/* If vp == savevp, a no-op */
|
/* If vp == savevp, a no-op */
|
||||||
if (vp != savevp) {
|
if (vp != savevp) {
|
||||||
VREF(savevp);
|
VREF(savevp);
|
||||||
if (mp == NULL || savemp == NULL)
|
|
||||||
panic("nfscmpmp");
|
|
||||||
if (!savevpnes.nes_vfslocked &&
|
|
||||||
vpnes.nes_vfslocked) {
|
|
||||||
if (mp == savemp)
|
|
||||||
panic("nfscmp2");
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
} else if (savevpnes.nes_vfslocked &&
|
|
||||||
!vpnes.nes_vfslocked) {
|
|
||||||
if (mp == savemp)
|
|
||||||
panic("nfscmp3");
|
|
||||||
savevpnes.nes_vfslocked = nfsvno_lockvfs(savemp);
|
|
||||||
}
|
|
||||||
vrele(vp);
|
vrele(vp);
|
||||||
vp = savevp;
|
vp = savevp;
|
||||||
vpnes = savevpnes;
|
vpnes = savevpnes;
|
||||||
mp = savemp;
|
cur_fsid = save_fsid;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nd->nd_repstat = NFSERR_RESTOREFH;
|
nd->nd_repstat = NFSERR_RESTOREFH;
|
||||||
@ -841,11 +818,14 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
|
|||||||
error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
|
error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
|
||||||
&nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes);
|
&nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes);
|
||||||
if (!error && !nd->nd_repstat) {
|
if (!error && !nd->nd_repstat) {
|
||||||
if (vfs_statfs(mp)->f_fsid.val[0] !=
|
if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) {
|
||||||
vfs_statfs(vnode_mount(nvp))->f_fsid.val[0] ||
|
new_mp = nvp->v_mount;
|
||||||
vfs_statfs(mp)->f_fsid.val[1] !=
|
if (cur_fsid.val[0] !=
|
||||||
vfs_statfs(vnode_mount(nvp))->f_fsid.val[1]) {
|
new_mp->mnt_stat.f_fsid.val[0] ||
|
||||||
nd->nd_repstat = nfsvno_checkexp(vnode_mount(nvp),
|
cur_fsid.val[1] !=
|
||||||
|
new_mp->mnt_stat.f_fsid.val[1]) {
|
||||||
|
/* crossed a server mount point */
|
||||||
|
nd->nd_repstat = nfsvno_checkexp(new_mp,
|
||||||
nd->nd_nam, &nes, &credanon);
|
nd->nd_nam, &nes, &credanon);
|
||||||
if (!nd->nd_repstat)
|
if (!nd->nd_repstat)
|
||||||
nd->nd_repstat = nfsd_excred(nd,
|
nd->nd_repstat = nfsd_excred(nd,
|
||||||
@ -853,17 +833,13 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
|
|||||||
if (credanon != NULL)
|
if (credanon != NULL)
|
||||||
crfree(credanon);
|
crfree(credanon);
|
||||||
if (!nd->nd_repstat) {
|
if (!nd->nd_repstat) {
|
||||||
if (vpnes.nes_vfslocked)
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
mp = vnode_mount(nvp);
|
|
||||||
vpnes = nes;
|
vpnes = nes;
|
||||||
vpnes.nes_vfslocked =
|
cur_fsid = new_mp->mnt_stat.f_fsid;
|
||||||
nfsvno_lockvfs(mp);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/* Lookup ops return a locked vnode */
|
||||||
|
VOP_UNLOCK(nvp, 0);
|
||||||
}
|
}
|
||||||
if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP)
|
|
||||||
/* Lookup ops return a locked vnode */
|
|
||||||
VOP_UNLOCK(nvp, 0);
|
|
||||||
if (!nd->nd_repstat) {
|
if (!nd->nd_repstat) {
|
||||||
vrele(vp);
|
vrele(vp);
|
||||||
vp = nvp;
|
vp = nvp;
|
||||||
@ -876,7 +852,8 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
|
|||||||
if (vp == NULL || savevp == NULL) {
|
if (vp == NULL || savevp == NULL) {
|
||||||
nd->nd_repstat = NFSERR_NOFILEHANDLE;
|
nd->nd_repstat = NFSERR_NOFILEHANDLE;
|
||||||
break;
|
break;
|
||||||
} else if (mp != savemp) {
|
} else if (cur_fsid.val[0] != save_fsid.val[0] ||
|
||||||
|
cur_fsid.val[1] != save_fsid.val[1]) {
|
||||||
nd->nd_repstat = NFSERR_XDEV;
|
nd->nd_repstat = NFSERR_XDEV;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -960,8 +937,6 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
|
|||||||
} else {
|
} else {
|
||||||
*retopsp = txdr_unsigned(retops);
|
*retopsp = txdr_unsigned(retops);
|
||||||
}
|
}
|
||||||
if (mp && vpnes.nes_vfslocked)
|
|
||||||
nfsvno_unlockvfs(mp);
|
|
||||||
if (vp)
|
if (vp)
|
||||||
vrele(vp);
|
vrele(vp);
|
||||||
if (savevp)
|
if (savevp)
|
||||||
|
Loading…
Reference in New Issue
Block a user