summaryrefslogtreecommitdiffstats
path: root/sys/nfsserver
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1995-05-29 04:01:09 +0000
committerdg <dg@FreeBSD.org>1995-05-29 04:01:09 +0000
commitda17d8251a2dd8bcaa843590de03bf685b4553ff (patch)
tree13faff4fe324ccd67ebb85c65757b262476506f2 /sys/nfsserver
parent48a749d725591845bf064778b92e5694409c5e64 (diff)
downloadFreeBSD-src-da17d8251a2dd8bcaa843590de03bf685b4553ff.zip
FreeBSD-src-da17d8251a2dd8bcaa843590de03bf685b4553ff.tar.gz
Fixed some serious bugs that resulted in object reference counts not being
handled correctly. This would manifest itself as "object deallocated too many times" panics and perhaps other strange inconsistencies on NFS servers. Reviewed by: me, of course Submitted by: John Dyson
Diffstat (limited to 'sys/nfsserver')
-rw-r--r--sys/nfsserver/nfs_serv.c34
-rw-r--r--sys/nfsserver/nfs_srvsubs.c6
2 files changed, 36 insertions, 4 deletions
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
index f3eba1c..bd8f0c3 100644
--- a/sys/nfsserver/nfs_serv.c
+++ b/sys/nfsserver/nfs_serv.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_serv.c 8.3 (Berkeley) 1/12/94
- * $Id: nfs_serv.c,v 1.11 1995/03/17 07:45:19 davidg Exp $
+ * $Id: nfs_serv.c,v 1.12 1995/03/19 12:04:11 davidg Exp $
*/
/*
@@ -748,6 +748,7 @@ nfsrv_create(nfsd, mrep, md, dpos, cred, nam, mrq)
error=VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
if (error)
nfsm_reply(0);
+ nfsrv_vmio(nd.ni_vp);
FREE(nd.ni_cnd.cn_pnbuf, M_NAMEI);
} else if (vap->va_type == VCHR || vap->va_type == VBLK ||
vap->va_type == VFIFO) {
@@ -778,6 +779,7 @@ nfsrv_create(nfsd, mrep, md, dpos, cred, nam, mrq)
free(nd.ni_cnd.cn_pnbuf, M_NAMEI);
nfsm_reply(0);
}
+ nfsrv_vmio(nd.ni_vp);
FREE(nd.ni_cnd.cn_pnbuf, M_NAMEI);
if (nd.ni_cnd.cn_flags & ISSYMLINK) {
nfsrv_vrele(nd.ni_dvp);
@@ -905,9 +907,15 @@ nfsrv_remove(nfsd, mrep, md, dpos, cred, nam, mrq)
(void) vnode_pager_uncache(vp);
out:
if (!error) {
+ int deallocobj = 0;
nqsrv_getl(nd.ni_dvp, NQL_WRITE);
nqsrv_getl(vp, NQL_WRITE);
+
+ if ((vp->v_flag & VVMIO) && vp->v_vmdata)
+ deallocobj = 1;
error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
+ if (error == 0 && deallocobj)
+ vm_object_deallocate((vm_object_t) vp->v_vmdata);
} else {
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
if (nd.ni_dvp == vp)
@@ -1014,12 +1022,23 @@ nfsrv_rename(nfsd, mrep, md, dpos, cred, nam, mrq)
error = -1;
out:
if (!error) {
+ int deallocobjfrom = 0, deallocobjto = 0;
nqsrv_getl(fromnd.ni_dvp, NQL_WRITE);
nqsrv_getl(tdvp, NQL_WRITE);
- if (tvp)
+ if (tvp) {
nqsrv_getl(tvp, NQL_WRITE);
+ if ((tvp->v_flag & VVMIO) && tvp->v_vmdata)
+ deallocobjto = 1;
+ }
+ if ((fvp->v_flag & VVMIO) && fvp->v_vmdata)
+ deallocobjfrom = 1;
error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
+ if (deallocobjfrom)
+ vm_object_deallocate((vm_object_t) fvp->v_vmdata);
+ if (deallocobjto)
+ vm_object_deallocate((vm_object_t) tvp->v_vmdata);
+
} else {
VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd);
if (tdvp == tvp)
@@ -1105,9 +1124,14 @@ nfsrv_link(nfsd, mrep, md, dpos, cred, nam, mrq)
error = EXDEV;
out:
if (!error) {
+ int deallocobj = 0;
nqsrv_getl(vp, NQL_WRITE);
nqsrv_getl(xp, NQL_WRITE);
+ if ((vp->v_flag & VVMIO) && vp->v_vmdata)
+ deallocobj = 1;
error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
+ if (error == 0 && deallocobj)
+ vm_object_deallocate((vm_object_t) vp->v_vmdata);
} else {
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
if (nd.ni_dvp == nd.ni_vp)
@@ -1134,6 +1158,7 @@ nfsrv_symlink(nfsd, mrep, md, dpos, cred, nam, mrq)
struct ucred *cred;
struct mbuf *nam, **mrq;
{
+ struct vnode *ovp;
struct vattr va;
struct nameidata nd;
register struct vattr *vap = &va;
@@ -1149,6 +1174,7 @@ nfsrv_symlink(nfsd, mrep, md, dpos, cred, nam, mrq)
nfsv2fh_t nfh;
fhandle_t *fhp;
u_quad_t frev;
+ int deallocobj = 0;
pathcp = (char *)0;
fhp = &nfh.fh_generic;
@@ -1188,7 +1214,11 @@ nfsrv_symlink(nfsd, mrep, md, dpos, cred, nam, mrq)
VATTR_NULL(vap);
vap->va_mode = fxdr_unsigned(u_short, sp->sa_mode);
nqsrv_getl(nd.ni_dvp, NQL_WRITE);
+ if ((ovp = nd.ni_vp) && (ovp->v_flag & VVMIO) && ovp->v_vmdata)
+ deallocobj = 1;
error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap, pathcp);
+ if (error == 0 && deallocobj)
+ vm_object_deallocate( (vm_object_t) ovp->v_vmdata);
out:
if (pathcp)
FREE(pathcp, M_TEMP);
diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
index 1497a82..3ccc10a 100644
--- a/sys/nfsserver/nfs_srvsubs.c
+++ b/sys/nfsserver/nfs_srvsubs.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_subs.c,v 1.12 1995/03/16 18:15:39 bde Exp $
+ * $Id: nfs_subs.c,v 1.13 1995/04/21 02:58:49 dyson Exp $
*/
/*
@@ -990,12 +990,14 @@ nfs_namei(ndp, fhp, len, slp, nam, mdp, dposp, p)
error = EINVAL;
goto out;
}
+
+ nfsrv_vmio(ndp->ni_vp);
+
/*
* Check for saved name request
*/
if (cnp->cn_flags & (SAVENAME | SAVESTART)) {
cnp->cn_flags |= HASBUF;
- nfsrv_vmio( ndp->ni_vp);
return (0);
}
out:
OpenPOWER on IntegriCloud