Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Feb 2002 16:45:35 -0800
From:      Scott Renfro <scott@renfro.org>
To:        freebsd-hackers@freebsd.org
Subject:   panic: nfs: bioread, not dir
Message-ID:  <20020216164535.A64097@bonsai.home.renfro.org>

next in thread | raw e-mail | index | archive | help
I've hit the "nfs: bioread, not dir" panic at nfs_bio.c:389 on several
occasions, but have a good crash dump from a recent -stable (cvsup'd
yesterday) this time.  No recent changes introduced this problem since
I've been getting it periodically for quite some time and the relevant
code hasn't changed in years.

This typically occurs when saving changes to an existing file on a nfsv2
mount where the server is Matt Blaze's cfs backed to the local
filesystem.

Here's a snippet of the call stack (I can send the full gdb output if
its helpful):

#3  0xc01c7345 in nfs_bioread (vp=0xcdb7fc80, uio=0xcdc72f14, ioflag=0,
    cred=0xc137b280) at /usr/src/sys/nfs/nfs_bio.c:389
#4  0xc01eef47 in nfs_readlink (ap=0xcdc72ebc) at
    /usr/src/sys/nfs/nfs_vnops.c:1037
#5  0xc0180cfb in readlink (p=0xcdc6ee00, uap=0xcdc72f80) at
    vnode_if.h:794

During the emacs save operation, we get a readlink(2) operation where
vnode->v_type == VLNK and the nfsnode->n_flag NMODIFIED bit is set.

The combination violates the test in nfs_bioread() at nfs_bio.c:385,
which flushes buffers before the read if they're dirty to try and
maintain cache consistency.  Here's that code starting at nfs_bio.c:385:

 385:   if ((nmp->nm_flag & NFSMNT_NQNFS) == 0) {
             if (np->n_flag & NMODIFIED) {
                 if (vp->v_type != VREG) {
                     if (vp->v_type != VDIR)
 389:                    panic("nfs: bioread, not dir");
                     nfs_invaldir(vp);
                     error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
                     if (error)
                         return (error);
                 } 
                np->n_attrstamp = 0;
                 error = VOP_GETATTR(vp, &vattr, cred, p);
                 if (error)
                     return (error);
                 np->n_mtime = vattr.va_mtime.tv_sec;
 400:        } else {

There used to be a test for vp->v_type != VLNK on line 385.  This was
removed [2] as part of fixing support for amd direct maps with rev 1.17,
commited 8/24/95.  NetBSD's corresponding fix [3] didn't include removal
of the check; instead they made a change to not cache symlinks later in
nfs_bioread().  There's a few messages in the archives, but nothing that
includes rationale [1].

Is the VLNK with NMODIFIED bit a valid condition, or does it imply a bug
elsewhere?

Should we have made the fix that NetBSD made rather than removing the
check?

thanks,
--Scott

[1] The urls are long, but search groups.google.com for amd direct vlnk

[2] http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/nfs/Attic/nfs_bio.c.diff?r1=1.16&r2=1.17

===================================================================
RCS file: /c/ncvs/src/sys/nfs/Attic/nfs_bio.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -p -r1.16 -r1.17
--- src/sys/nfs/Attic/nfs_bio.c 1995/07/07 11:01:30     1.16
+++ src/sys/nfs/Attic/nfs_bio.c 1995/08/24 10:17:32     1.17
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *     @(#)nfs_bio.c   8.5 (Berkeley) 1/4/94
- * $Id: nfs_bio.c,v 1.15 1995/06/27 11:06:34 dfr Exp $
+ * $Id: nfs_bio.c,v 1.16 1995/07/07 11:01:30 dfr Exp $
  */
 
 #include <sys/param.h>
@@ -125,7 +125,7 @@ nfs_bioread(vp, uio, ioflag, cred)
         * attributes this could be forced by setting n_attrstamp to 0
         before
         * the VOP_GETATTR() call.
         */
-       if ((nmp->nm_flag & NFSMNT_NQNFS) == 0 && vp->v_type != VLNK) {
+       if ((nmp->nm_flag & NFSMNT_NQNFS) == 0) {
                if (np->n_flag & NMODIFIED) {
                        if (vp->v_type != VREG) {
                                if (vp->v_type != VDIR)


[3] http://cvsweb.no.netbsd.org/bsdweb.cgi/syssrc/sys/nfs/nfs_bio.c.diff?r1=1.25&r2=1.26

===================================================================
RCS file: /var/jailhouse/cvsjail/cvsroot/syssrc/sys/nfs/nfs_bio.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- syssrc/sys/nfs/nfs_bio.c    1996/02/29 20:26:16     1.25
+++ syssrc/sys/nfs/nfs_bio.c    1996/05/23 22:47:27     1.26
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfs_bio.c,v 1.24 1996/02/18 11:53:39 fvdl Exp $
*/
+/*     $NetBSD: nfs_bio.c,v 1.25 1996/02/29 20:26:16 fvdl Exp $
*/

 /*
  * Copyright (c) 1989, 1993
@@ -173,7 +173,11 @@
                        return (error);
                }
            }
-           if (np->n_flag & NQNFSNONCACHE) {
+           /*
+            * Don't cache symlinks.
+            */
+           if (np->n_flag & NQNFSNONCACHE
+               || ((vp->v_flag & VROOT) && vp->v_type == VLNK)) {
                switch (vp->v_type) {
                case VREG:
                        return (nfs_readrpc(vp, uio, cred));

-- 
Scott Renfro <scott@renfro.org>

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020216164535.A64097>