:Crap, I just sent out an incomplete message. Let me pick up from where
:I left off. Here's a diff that shows the changes I made to nfs_vfsops.c:
:
:*** nfs_vnops.c.orig   Thu Jul 29 22:46:28 1999
:--- nfs_vnops.c        Thu Jul 29 22:36:39 1999
:***************
:*** 2342,2348 ****
:                                   IFTODT(VTTOIF(np->n_vattr.va_type));
:                               ndp->ni_vp = newvp;
:                               cnp->cn_hash = 0;
:!                              for (cp = cnp->cn_nameptr, i = 1; i <= len;
:                                   i++, cp++)
:                                   cnp->cn_hash += (unsigned char)*cp * i;
:                               cache_enter(ndp->ni_dvp, ndp->ni_vp, cnp);
:--- 2342,2351 ----
:                                   IFTODT(VTTOIF(np->n_vattr.va_type));
:                               ndp->ni_vp = newvp;
:                               cnp->cn_hash = 0;
:!                              /*for (cp = cnp->cn_nameptr, i = 1; i <= len;*/
:!                              if (len != cnp->cn_namelen)
:!                                      printf("bogus: %d %d\n", len, cnp->cn_namelen);
:!                              for (cp = cnp->cn_nameptr, i = 1; i <= cnp->cn_namelen;
:                                   i++, cp++)
:                                   cnp->cn_hash += (unsigned char)*cp * i;
:                               cache_enter(ndp->ni_dvp, ndp->ni_vp, cnp);
:
:Basically, at some point, the code tries to calculate a new hash value
:(what for I don't know) of a name that was read from the directory
:listing. However it uses "len" as the length of the name, which for
:some reason I can't understand turns out not matching the cn_namelen
:value in cnp. The "bogus" printf shows about a half dozen occasions
:where len and cn_namelen don't agree. Sometimes "len" is larger
:than "cnp->cn_namelen," sometimes it's smaller. By using cn_namelen
:instead of len, everything seems to work correctly. It looks like
:this loop makes more than one pass over directory entries, so it could
:be that len is sometimes stale. If you can make sense of why this
:happens, I would appreciate it: I don't like to commit changes when
:I don't fully understand what's going on.

    Look up a bit in the code.  If bigenough is not true, cnp does not 
    get initialized.  This could lead to the bogus length -- or rather,
    it would be the cnp that is bogus, not the 'len'.

    The question is how to fix it.  I think we can safely avoid doing the
    cache_enter so try changing the 'if (doit)' to 'if (doit && bigenough)'.
    I've included the patch below.

    I am not 100% sure about this.

:>     Presumably this will not fix the SGI client.  I've no idea what the
:>     problem there is.  There may be a bug in the SGI client or there may
:>     be a bug in the client & server implementation of the protocol in FreeBSD.
:
:Er, I think you misunderstood: there's nothing wrong with the SGI in
:this case. I mentioned it because I was using it as a _server_ when
:testing the client side readdirplus support: the behavior with the
:...
:was just a consequence of the filesystems being laid out differently.
:The patched FreeBSD client works fine now with the SGI server.
:
:-Bill

   Ah, ok.  I mistook the SGI for being a client.

                                        -Matt
                                        Matthew Dillon 
                                        <[EMAIL PROTECTED]>

Index: nfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs/nfs_vnops.c,v
retrieving revision 1.135
diff -u -r1.135 nfs_vnops.c
--- nfs_vnops.c 1999/07/01 13:32:54     1.135
+++ nfs_vnops.c 1999/07/30 03:28:36
@@ -2343,7 +2343,7 @@
                                        newvp = NFSTOV(np);
                                }
                            }
-                           if (doit) {
+                           if (doit && bigenough) {
                                dpossav2 = dpos;
                                dpos = dpossav1;
                                mdsav2 = md;
@@ -2367,7 +2367,10 @@
                            nfsm_adv(nfsm_rndup(i));
                        }
                        if (newvp != NULLVP) {
-                           vrele(newvp);
+                           if (newvp == vp)
+                               vrele(newvp);
+                           else
+                               vput(newvp);
                            newvp = NULLVP;
                        }
                        nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to