Subject: kern/3215: NFS getdirentries(2) result is truncated (with fix)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <soda@sra.co.jp>
List: netbsd-bugs
Date: 02/13/1997 00:31:48
>Number: 3215
>Category: kern
>Synopsis: NFS getdirentries(2) result is truncated
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Feb 12 07:50:00 1997
>Last-Modified:
>Originator: Hiroshi Tezuka <tezuka@trc.rwcp.or.jp>
>Organization:
Real World Computing Partnership.
>Release: 1.2 and 1.2C (-current Feb 10, 1997)
>Environment:
System: NetBSD mpspc5.trc.rwcp.or.jp 1.2C NetBSD 1.2C (MPSPC) #1: Tue Feb 11 20:51:40 JST 1997 soda@mpspc7.trc.rwcp.or.jp:/amd/u56/mnt5/mpsoft/work/soda.i386/src.netpower/netbsd-19970210/sys/arch/i386/compile/MPSPC i386
>Description:
Sometimes, getdirentries(2) returns incorrect result
(not all entries are returned), when the directory is big
and NFS mounted.
For example,
normal case:
% /bin/ls -af /home/ | wc
857 857 6562
illegal case:
% /bin/ls -af /home/ | wc
294 294 2211
normal case:
% cd /home/tezuka
% /bin/pwd
/amd/sh1/afs/rwcp.or.jp/home/tezuka
illegal case:
% /bin/pwd
pwd: No such file or directory
Note, the directory "/home" is not modified during operation.
>How-To-Repeat:
Assume "/home" is big and NFS mounted.
% /bin/ls -af /home/ | wc
857 857 6562
--- reading big directory
% cd /home/arita
--- change directory to first entry of /home
% cat /bin/* /usr/bin/* > /dev/null
--- clear buffer cache
% pwd
/amd/sh1/afs/rwcp.or.jp/home/arita
--- read to first entry on the /home direcotry
% /bin/ls -af /home/ | wc
294 294 2211
--- TRUNCATED !!!
% cat /bin/* /usr/bin/* > /dev/null
--- clear buffer cache
% /bin/ls -af /home/ | wc
857 857 6562
--- recovered
>Fix:
Investigating the reason and making fix are done by
Mr. Hiroshi Tezuka <tezuka@trc.rwcp.or.jp>.
Reason:
- `n_sillyrename' member and `n_cookie' member in struct nfsnode
share same memory. (because they are in same union `n_un3').
- nfs_inactive() in nfs_node.c makes `n_sillyrename' NULL,
even if the vnode is directory, so that `n_cookie' is broken
by accident.
Fix:
DO NOT break `n_cookie' member, if the vnode is directory.
------------------------------------------------------------------------
Index: nfs_node.c
===================================================================
RCS file: /usr/trc/project/mpsoft/cvs/netbsd/sys/nfs/nfs_node.c,v
retrieving revision 1.1
diff -c -r1.1 nfs_node.c
*** nfs_node.c 1996/08/20 07:46:16 1.1
--- nfs_node.c 1997/02/12 14:47:06
***************
*** 173,183 ****
np = VTONFS(ap->a_vp);
if (prtactive && ap->a_vp->v_usecount != 0)
vprint("nfs_inactive: pushing active", ap->a_vp);
! if (ap->a_vp->v_type != VDIR)
sp = np->n_sillyrename;
! else
sp = (struct sillyrename *)0;
- np->n_sillyrename = (struct sillyrename *)0;
if (sp) {
/*
* Remove the silly file that was rename'd earlier
--- 173,183 ----
np = VTONFS(ap->a_vp);
if (prtactive && ap->a_vp->v_usecount != 0)
vprint("nfs_inactive: pushing active", ap->a_vp);
! if (ap->a_vp->v_type != VDIR) {
sp = np->n_sillyrename;
! np->n_sillyrename = (struct sillyrename *)0;
! } else
sp = (struct sillyrename *)0;
if (sp) {
/*
* Remove the silly file that was rename'd earlier
------------------------------------------------------------------------
--
soda@sra.co.jp Software Research Associates, Inc., Japan
(Noriyuki Soda) software tools and technology group
>Audit-Trail:
>Unformatted: