NFS deadlock (unkillable nfsd and no mounts work)
Kostik Belousov
kostikbel at gmail.com
Fri Nov 5 21:28:02 UTC 2010
On Fri, Nov 05, 2010 at 10:27:09AM -0700, Josh Carroll wrote:
> >> I'm having a problem with nfsd hanging and not serving mount points,
> >> during which time it can not not be killed. This problem started
> >> happening sometime after November 2nd, since kernel from 11/2 sources
> >> does not exhibit this problem.
> >
> > Please try the attached patch, rick
>
> Thanks! I had to manually patch for some reason, but I can confirmed
> that nfsd is now well-behaved with your patch applied. I tested a
> couple of different mounts and played two separate files on the
> Popcorn Hour (one lower bitrate, the other higher bitrate) and both
> played without a hiccup. While those were playing I also was able to
> automount my home directory on the macbook and move around my home
> directory.
>
> So it looks like this patch did the trick. Thanks Rick, really
> appreciate the fast response. Is there a reason why this doesn't seem
> to be getting reported a lot? What is particular in my setup that
> broke it?
>
> > ps: Starting about Monday I won't be able to do commits for about 3 weeks
> > so, if this patch works, could someone else please commit it, thanks,
> > rick
> >
>
> If someone can commit this, I'd really appreciate it. I will report
> back if I notice any problems, but I imagine this would probably get
> fixed in HEAD first, then MFC'd anyway, right? Unless this is already
> fixed in HEAD.
>
> Anyway, thanks again Rick! I appreciate it.
>
> Regards,
> Josh
> As far as I can tell, there have been no adverse effects or
> regressions with the kernel built with this patch (I had t
I agree that the fix a right fix for real issue. It should only
affect the filesystems that do support VFS_VGET(). In other words,
it is relevant for e.g. UFS exports, but not for ZFS, that is the
Andrey case.
The change is committed as r214851 with shortest MFC timeout possible.
There is further issue with use of VOP_ISLOCKED(). Andrey, can you
try this untested change in your settings ?
Thanks and sorry.
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
index 2b9131f..668b02c 100644
--- a/sys/nfsserver/nfs_serv.c
+++ b/sys/nfsserver/nfs_serv.c
@@ -3037,6 +3037,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
struct vattr va, at, *vap = &va;
struct nfs_fattr *fp;
int len, nlen, rem, xfer, tsiz, i, error = 0, error1, getret = 1;
+ int vp_locked;
int siz, cnt, fullsiz, eofflag, rdonly, dirlen, ncookies;
u_quad_t off, toff, verf;
u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
@@ -3067,10 +3068,12 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
fullsiz = siz;
error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
nam, &rdonly, TRUE);
+ vp_locked = 1;
if (!error && vp->v_type != VDIR) {
error = ENOTDIR;
vput(vp);
vp = NULL;
+ vp_locked = 0;
}
if (error) {
nfsm_reply(NFSX_UNSIGNED);
@@ -3090,6 +3093,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
error = nfsrv_access(vp, VEXEC, cred, rdonly, 0);
if (error) {
vput(vp);
+ vp_locked = 0;
vp = NULL;
nfsm_reply(NFSX_V3POSTOPATTR);
nfsm_srvpostop_attr(getret, &at);
@@ -3097,6 +3101,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
goto nfsmout;
}
VOP_UNLOCK(vp, 0);
+ vp_locked = 0;
rbuf = malloc(siz, M_TEMP, M_WAITOK);
again:
iv.iov_base = rbuf;
@@ -3110,6 +3115,7 @@ again:
io.uio_td = NULL;
eofflag = 0;
vn_lock(vp, LK_SHARED | LK_RETRY);
+ vp_locked = 1;
if (cookies) {
free((caddr_t)cookies, M_TEMP);
cookies = NULL;
@@ -3118,6 +3124,7 @@ again:
off = (u_quad_t)io.uio_offset;
getret = VOP_GETATTR(vp, &at, cred);
VOP_UNLOCK(vp, 0);
+ vp_locked = 0;
if (!cookies && !error)
error = NFSERR_PERM;
if (!error)
@@ -3238,8 +3245,10 @@ again:
} else {
cn.cn_flags &= ~ISDOTDOT;
}
- if (!VOP_ISLOCKED(vp))
+ if (!vp_locked) {
vn_lock(vp, LK_SHARED | LK_RETRY);
+ vp_locked = 1;
+ }
if ((vp->v_vflag & VV_ROOT) != 0 &&
(cn.cn_flags & ISDOTDOT) != 0) {
vref(vp);
@@ -3342,7 +3351,7 @@ invalid:
cookiep++;
ncookies--;
}
- if (!usevget && VOP_ISLOCKED(vp))
+ if (!usevget && vp_locked)
vput(vp);
else
vrele(vp);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-stable/attachments/20101105/df96da13/attachment.pgp
More information about the freebsd-stable
mailing list