When perfoming a mknod operation over NFS it can happen that another
client creates a file with the same name between the namei() and
VOP_MKNOD() calls in domknod(). This leads to an error path in
nfsrv_mknod() being triggered. In that error path there is a
vput(nd.ni_np) missing, resulting in the vnode getting stuck with a
stale reference and lock, while it shouldn't have either.
Ok?
natano
Index: nfs/nfs_serv.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_serv.c,v
retrieving revision 1.108
diff -u -p -r1.108 nfs_serv.c
--- nfs/nfs_serv.c 29 Apr 2016 14:40:36 -0000 1.108
+++ nfs/nfs_serv.c 3 Jul 2016 18:00:54 -0000
@@ -1163,7 +1163,12 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
error = NFSERR_BADTYPE;
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
- vput(nd.ni_dvp);
+ if (nd.ni_dvp == nd.ni_vp)
+ vrele(nd.ni_dvp);
+ else
+ vput(nd.ni_dvp);
+ if (nd.ni_vp)
+ vput(nd.ni_vp);
goto out;
}
VATTR_NULL(&va);
@@ -1185,7 +1190,11 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
error = EEXIST;
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
- vput(nd.ni_dvp);
+ if (nd.ni_dvp == nd.ni_vp)
+ vrele(nd.ni_dvp);
+ else
+ vput(nd.ni_dvp);
+ vput(nd.ni_vp);
goto out;
}
va.va_type = vtyp;