patches for easier mirroring, to eliminate a special copy, to make www.freebsd.org/security a full copy of security.freebsd.org and be eventually be the same. For now files are just sitting there. The symlinks are missing. Discussed on: www (repository location) Discussed with: simon (so)
421 lines
9.4 KiB
Diff
421 lines
9.4 KiB
Diff
Index: sys/nfsserver/nfs_serv.c
|
|
===================================================================
|
|
RCS file: /home/ncvs/src/sys/nfsserver/nfs_serv.c,v
|
|
retrieving revision 1.156
|
|
diff -u -r1.156 nfs_serv.c
|
|
--- sys/nfsserver/nfs_serv.c 17 Apr 2005 16:25:36 -0000 1.156
|
|
+++ sys/nfsserver/nfs_serv.c 13 Feb 2007 20:43:09 -0000
|
|
@@ -569,6 +569,10 @@
|
|
|
|
error = lookup(&ind);
|
|
ind.ni_dvp = NULL;
|
|
+ if (ind.ni_cnd.cn_flags & GIANTHELD) {
|
|
+ mtx_unlock(&Giant);
|
|
+ ind.ni_cnd.cn_flags &= ~GIANTHELD;
|
|
+ }
|
|
|
|
if (error == 0) {
|
|
/*
|
|
@@ -599,15 +603,9 @@
|
|
}
|
|
}
|
|
|
|
- if (dirp) {
|
|
- vrele(dirp);
|
|
- dirp = NULL;
|
|
- }
|
|
-
|
|
/*
|
|
* Resources at this point:
|
|
* ndp->ni_vp may not be NULL
|
|
- *
|
|
*/
|
|
|
|
if (error) {
|
|
@@ -621,15 +619,6 @@
|
|
}
|
|
|
|
/*
|
|
- * Clear out some resources prior to potentially blocking. This
|
|
- * is not as critical as ni_dvp resources in other routines, but
|
|
- * it helps.
|
|
- */
|
|
- vrele(ndp->ni_startdir);
|
|
- ndp->ni_startdir = NULL;
|
|
- NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
-
|
|
- /*
|
|
* Get underlying attribute, then release remaining resources ( for
|
|
* the same potential blocking reason ) and reply.
|
|
*/
|
|
@@ -641,8 +630,12 @@
|
|
error = VOP_GETATTR(vp, vap, cred, td);
|
|
|
|
vput(vp);
|
|
- mtx_unlock(&Giant); /* VFS */
|
|
+ vrele(ndp->ni_startdir);
|
|
+ vrele(dirp);
|
|
ndp->ni_vp = NULL;
|
|
+ ndp->ni_startdir = NULL;
|
|
+ dirp = NULL;
|
|
+ mtx_unlock(&Giant); /* VFS */
|
|
NFSD_LOCK();
|
|
nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3));
|
|
if (error) {
|
|
@@ -662,17 +655,19 @@
|
|
|
|
nfsmout:
|
|
NFSD_LOCK_ASSERT();
|
|
- NFSD_UNLOCK();
|
|
- mtx_lock(&Giant); /* VFS */
|
|
- if (dirp)
|
|
- vrele(dirp);
|
|
+ if (ndp->ni_vp || dirp || ndp->ni_startdir) {
|
|
+ NFSD_UNLOCK();
|
|
+ mtx_lock(&Giant); /* VFS */
|
|
+ if (ndp->ni_vp)
|
|
+ vput(ndp->ni_vp);
|
|
+ if (dirp)
|
|
+ vrele(dirp);
|
|
+ if (ndp->ni_startdir)
|
|
+ vrele(ndp->ni_startdir);
|
|
+ mtx_unlock(&Giant); /* VFS */
|
|
+ NFSD_LOCK();
|
|
+ }
|
|
NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
- if (ndp->ni_startdir)
|
|
- vrele(ndp->ni_startdir);
|
|
- if (ndp->ni_vp)
|
|
- vput(ndp->ni_vp);
|
|
- mtx_unlock(&Giant); /* VFS */
|
|
- NFSD_LOCK();
|
|
return (error);
|
|
}
|
|
|
|
@@ -1924,6 +1919,10 @@
|
|
|
|
error = lookup(&nd);
|
|
nd.ni_dvp = NULL;
|
|
+ if (nd.ni_cnd.cn_flags & GIANTHELD) {
|
|
+ mtx_unlock(&Giant);
|
|
+ nd.ni_cnd.cn_flags &= ~GIANTHELD;
|
|
+ }
|
|
if (error)
|
|
goto ereply;
|
|
|
|
@@ -2004,13 +2003,6 @@
|
|
NFSD_LOCK_ASSERT();
|
|
NFSD_UNLOCK();
|
|
mtx_lock(&Giant); /* VFS */
|
|
- if (nd.ni_startdir) {
|
|
- vrele(nd.ni_startdir);
|
|
- nd.ni_startdir = NULL;
|
|
- }
|
|
- if (dirp)
|
|
- vrele(dirp);
|
|
- NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
if (nd.ni_dvp) {
|
|
if (nd.ni_dvp == nd.ni_vp)
|
|
vrele(nd.ni_dvp);
|
|
@@ -2019,6 +2011,13 @@
|
|
}
|
|
if (nd.ni_vp)
|
|
vput(nd.ni_vp);
|
|
+ if (nd.ni_startdir) {
|
|
+ vrele(nd.ni_startdir);
|
|
+ nd.ni_startdir = NULL;
|
|
+ }
|
|
+ if (dirp)
|
|
+ vrele(dirp);
|
|
+ NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
vn_finished_write(mp);
|
|
mtx_unlock(&Giant); /* VFS */
|
|
NFSD_LOCK();
|
|
@@ -2092,6 +2091,8 @@
|
|
tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
|
|
vtyp = nfsv3tov_type(*tl);
|
|
if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) {
|
|
+ NFSD_UNLOCK();
|
|
+ mtx_lock(&Giant); /* VFS */
|
|
error = NFSERR_BADTYPE;
|
|
goto out;
|
|
}
|
|
@@ -2108,6 +2109,8 @@
|
|
* Iff doesn't exist, create it.
|
|
*/
|
|
if (nd.ni_vp) {
|
|
+ NFSD_UNLOCK();
|
|
+ mtx_lock(&Giant); /* VFS */
|
|
error = EEXIST;
|
|
goto out;
|
|
}
|
|
@@ -2146,6 +2149,10 @@
|
|
|
|
error = lookup(&nd);
|
|
nd.ni_dvp = NULL;
|
|
+ if (nd.ni_cnd.cn_flags & GIANTHELD) {
|
|
+ mtx_unlock(&Giant);
|
|
+ nd.ni_cnd.cn_flags &= ~GIANTHELD;
|
|
+ }
|
|
|
|
if (error)
|
|
goto out;
|
|
@@ -2158,18 +2165,6 @@
|
|
*/
|
|
out:
|
|
NFSD_UNLOCK_ASSERT();
|
|
- if (nd.ni_startdir) {
|
|
- vrele(nd.ni_startdir);
|
|
- nd.ni_startdir = NULL;
|
|
- }
|
|
- NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
- if (nd.ni_dvp) {
|
|
- if (nd.ni_dvp == nd.ni_vp)
|
|
- vrele(nd.ni_dvp);
|
|
- else
|
|
- vput(nd.ni_dvp);
|
|
- nd.ni_dvp = NULL;
|
|
- }
|
|
vp = nd.ni_vp;
|
|
if (!error) {
|
|
bzero((caddr_t)fhp, sizeof(nfh));
|
|
@@ -2178,11 +2173,23 @@
|
|
if (!error)
|
|
error = VOP_GETATTR(vp, vap, cred, td);
|
|
}
|
|
+ if (nd.ni_dvp) {
|
|
+ if (nd.ni_dvp == nd.ni_vp)
|
|
+ vrele(nd.ni_dvp);
|
|
+ else
|
|
+ vput(nd.ni_dvp);
|
|
+ nd.ni_dvp = NULL;
|
|
+ }
|
|
if (vp) {
|
|
vput(vp);
|
|
vp = NULL;
|
|
nd.ni_vp = NULL;
|
|
}
|
|
+ if (nd.ni_startdir) {
|
|
+ vrele(nd.ni_startdir);
|
|
+ nd.ni_startdir = NULL;
|
|
+ }
|
|
+ NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
if (dirp) {
|
|
vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY, td);
|
|
diraft_ret = VOP_GETATTR(dirp, &diraft, cred, td);
|
|
@@ -2210,11 +2217,6 @@
|
|
NFSD_LOCK_ASSERT();
|
|
NFSD_UNLOCK();
|
|
mtx_lock(&Giant); /* VFS */
|
|
- if (dirp)
|
|
- vrele(dirp);
|
|
- if (nd.ni_startdir)
|
|
- vrele(nd.ni_startdir);
|
|
- NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
if (nd.ni_dvp) {
|
|
if (nd.ni_dvp == nd.ni_vp)
|
|
vrele(nd.ni_dvp);
|
|
@@ -2223,6 +2225,11 @@
|
|
}
|
|
if (nd.ni_vp)
|
|
vput(nd.ni_vp);
|
|
+ if (dirp)
|
|
+ vrele(dirp);
|
|
+ if (nd.ni_startdir)
|
|
+ vrele(nd.ni_startdir);
|
|
+ NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
vn_finished_write(mp);
|
|
mtx_unlock(&Giant); /* VFS */
|
|
NFSD_LOCK();
|
|
@@ -2519,8 +2526,8 @@
|
|
tond.ni_dvp = NULL;
|
|
tond.ni_vp = NULL;
|
|
if (error) {
|
|
- fromnd.ni_cnd.cn_flags &= ~HASBUF;
|
|
- tond.ni_cnd.cn_flags &= ~HASBUF;
|
|
+ NDFREE(&fromnd, NDF_ONLY_PNBUF);
|
|
+ NDFREE(&tond, NDF_ONLY_PNBUF);
|
|
}
|
|
} else {
|
|
if (error == -1)
|
|
@@ -2573,11 +2580,6 @@
|
|
NFSD_LOCK_ASSERT();
|
|
NFSD_UNLOCK();
|
|
mtx_lock(&Giant); /* VFS */
|
|
- if (tdirp)
|
|
- vrele(tdirp);
|
|
- if (tond.ni_startdir)
|
|
- vrele(tond.ni_startdir);
|
|
- NDFREE(&tond, NDF_ONLY_PNBUF);
|
|
if (tond.ni_dvp) {
|
|
if (tond.ni_dvp == tond.ni_vp)
|
|
vrele(tond.ni_dvp);
|
|
@@ -2586,7 +2588,11 @@
|
|
}
|
|
if (tond.ni_vp)
|
|
vput(tond.ni_vp);
|
|
-
|
|
+ if (tdirp)
|
|
+ vrele(tdirp);
|
|
+ if (tond.ni_startdir)
|
|
+ vrele(tond.ni_startdir);
|
|
+ NDFREE(&tond, NDF_ONLY_PNBUF);
|
|
/*
|
|
* Clear out fromnd related fields
|
|
*/
|
|
@@ -2747,8 +2753,6 @@
|
|
NFSD_UNLOCK();
|
|
mtx_lock(&Giant); /* VFS */
|
|
NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
- if (dirp)
|
|
- vrele(dirp);
|
|
if (vp)
|
|
vput(vp);
|
|
if (nd.ni_dvp) {
|
|
@@ -2757,6 +2761,8 @@
|
|
else
|
|
vput(nd.ni_dvp);
|
|
}
|
|
+ if (dirp)
|
|
+ vrele(dirp);
|
|
if (nd.ni_vp)
|
|
vrele(nd.ni_vp);
|
|
vn_finished_write(mp);
|
|
@@ -2815,6 +2821,12 @@
|
|
nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART;
|
|
error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
|
|
&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
|
|
+ if (error == 0) {
|
|
+ VATTR_NULL(vap);
|
|
+ if (v3)
|
|
+ nfsm_srvsattr(vap);
|
|
+ nfsm_srvpathsiz(len2);
|
|
+ }
|
|
NFSD_UNLOCK();
|
|
mtx_lock(&Giant); /* VFS */
|
|
if (dirp && !v3) {
|
|
@@ -2824,10 +2836,6 @@
|
|
if (error)
|
|
goto out;
|
|
|
|
- VATTR_NULL(vap);
|
|
- if (v3)
|
|
- nfsm_srvsattr(vap);
|
|
- nfsm_srvpathsiz(len2);
|
|
MALLOC(pathcp, caddr_t, len2 + 1, M_TEMP, M_WAITOK);
|
|
iv.iov_base = pathcp;
|
|
iv.iov_len = len2;
|
|
@@ -2884,6 +2892,10 @@
|
|
|
|
error = lookup(&nd);
|
|
nd.ni_dvp = NULL;
|
|
+ if (nd.ni_cnd.cn_flags & GIANTHELD) {
|
|
+ mtx_unlock(&Giant);
|
|
+ nd.ni_cnd.cn_flags &= ~GIANTHELD;
|
|
+ }
|
|
|
|
if (error == 0) {
|
|
bzero((caddr_t)fhp, sizeof(nfh));
|
|
@@ -3113,8 +3125,6 @@
|
|
NFSD_LOCK_ASSERT();
|
|
NFSD_UNLOCK();
|
|
mtx_lock(&Giant); /* VFS */
|
|
- if (dirp)
|
|
- vrele(dirp);
|
|
if (nd.ni_dvp) {
|
|
NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
if (nd.ni_dvp == nd.ni_vp && vpexcl)
|
|
@@ -3128,6 +3138,8 @@
|
|
else
|
|
vrele(nd.ni_vp);
|
|
}
|
|
+ if (dirp)
|
|
+ vrele(dirp);
|
|
vn_finished_write(mp);
|
|
mtx_unlock(&Giant); /* VFS */
|
|
NFSD_LOCK();
|
|
@@ -3255,8 +3267,6 @@
|
|
NFSD_UNLOCK();
|
|
mtx_lock(&Giant); /* VFS */
|
|
NDFREE(&nd, NDF_ONLY_PNBUF);
|
|
- if (dirp)
|
|
- vrele(dirp);
|
|
if (nd.ni_dvp) {
|
|
if (nd.ni_dvp == nd.ni_vp)
|
|
vrele(nd.ni_dvp);
|
|
@@ -3265,6 +3275,8 @@
|
|
}
|
|
if (nd.ni_vp)
|
|
vput(nd.ni_vp);
|
|
+ if (dirp)
|
|
+ vrele(dirp);
|
|
|
|
vn_finished_write(mp);
|
|
mtx_unlock(&Giant); /* VFS */
|
|
Index: sys/nfsserver/nfs_srvsubs.c
|
|
===================================================================
|
|
RCS file: /home/ncvs/src/sys/nfsserver/nfs_srvsubs.c,v
|
|
retrieving revision 1.136
|
|
diff -u -r1.136 nfs_srvsubs.c
|
|
--- sys/nfsserver/nfs_srvsubs.c 28 Mar 2005 18:51:58 -0000 1.136
|
|
+++ sys/nfsserver/nfs_srvsubs.c 13 Feb 2007 20:43:09 -0000
|
|
@@ -875,6 +875,10 @@
|
|
}
|
|
if (!lockleaf)
|
|
cnp->cn_flags &= ~LOCKLEAF;
|
|
+ if (cnp->cn_flags & GIANTHELD) {
|
|
+ mtx_unlock(&Giant);
|
|
+ cnp->cn_flags &= ~GIANTHELD;
|
|
+ }
|
|
|
|
/*
|
|
* nfs_namei() guarentees that fields will not contain garbage
|
|
@@ -1331,6 +1335,24 @@
|
|
return 0;
|
|
}
|
|
|
|
+int
|
|
+nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
|
|
+{
|
|
+ u_int32_t *tl;
|
|
+
|
|
+ NFSD_LOCK_DONTCARE();
|
|
+
|
|
+ tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
|
|
+ if (tl == NULL)
|
|
+ return EBADRPC;
|
|
+ *s = fxdr_unsigned(int32_t, *tl);
|
|
+ if (*s > m)
|
|
+ return NFSERR_NAMETOL;
|
|
+ if (*s < 0)
|
|
+ return EBADRPC;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
void
|
|
nfsm_clget_xx(u_int32_t **tl, struct mbuf *mb, struct mbuf **mp,
|
|
char **bp, char **be, caddr_t bpos, int droplock)
|
|
Index: sys/nfsserver/nfsm_subs.h
|
|
===================================================================
|
|
RCS file: /home/ncvs/src/sys/nfsserver/nfsm_subs.h,v
|
|
retrieving revision 1.37
|
|
diff -u -r1.37 nfsm_subs.h
|
|
--- sys/nfsserver/nfsm_subs.h 7 Jan 2005 01:45:51 -0000 1.37
|
|
+++ sys/nfsserver/nfsm_subs.h 13 Feb 2007 20:43:09 -0000
|
|
@@ -74,6 +74,7 @@
|
|
|
|
int nfsm_srvstrsiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
|
|
int nfsm_srvnamesiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
|
|
+int nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
|
|
int nfsm_srvmtofh_xx(fhandle_t *f, struct nfsrv_descript *nfsd,
|
|
struct mbuf **md, caddr_t *dpos);
|
|
int nfsm_srvsattr_xx(struct vattr *a, struct mbuf **md, caddr_t *dpos);
|
|
@@ -101,7 +102,7 @@
|
|
#define nfsm_srvpathsiz(s) \
|
|
do { \
|
|
int t1; \
|
|
- t1 = nfsm_srvnamesiz_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
|
|
+ t1 = nfsm_srvnamesiz0_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
|
|
if (t1) { \
|
|
error = t1; \
|
|
nfsm_reply(0); \
|