: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