Subject: kern/10377: dounmount() leaks vnodes
To: None <gnats-bugs@gnats.netbsd.org>
From: IWAMOTO Toshihiro <iwamoto@sat.t.u-tokyo.ac.jp>
List: netbsd-bugs
Date: 06/16/2000 04:05:19
>Number: 10377
>Category: kern
>Synopsis: dounmount() leaks vnodes
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Jun 16 04:06:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: IWAMOTO Toshihiro
>Release: yesterday's -current
>Organization:
>Environment:
System: NetBSD kiku.my.domain 1.4ZD NetBSD 1.4ZD (KIKU) #35: Fri Jun 16 19:22:06 JST 2000 toshii@kiku.my.domain:/usr/src/syssrc/sys/arch/i386/compile/KIKU i386
>Description:
vfs_allocate_syncvnode() calls getnewvnode(), which removes
one element from the vnode free list.
But, dounmount() doesn't put the allocated vnode onto the free list.
>How-To-Repeat:
Configure a system with amd(8) and wait about a week,
or more quickly:
# i=0; while [ $i -lt 1000 ]; do mount /dev/vnd0a /mnt; umount /mnt; i=$(($i+1)); done
# pstat -T
>Fix:
The following patch prevents vnode leaks, while I don't feel this
patch is quite correct.
Index: vfs_syscalls.c
===================================================================
RCS file: /export/kiku/NetBSD/NetBSD-CVS/syssrc/sys/kern/vfs_syscalls.c,v
retrieving revision 1.156
diff -u -r1.156 vfs_syscalls.c
--- vfs_syscalls.c 2000/04/17 14:31:22 1.156
+++ vfs_syscalls.c 2000/06/16 10:21:45
@@ -329,7 +329,8 @@
error = vfs_allocate_syncvnode(mp);
} else {
if (mp->mnt_syncer != NULL) {
- vgone(mp->mnt_syncer);
+ mp->mnt_syncer->v_writecount--;
+ vrele(mp->mnt_syncer);
mp->mnt_syncer = NULL;
}
}
@@ -498,7 +499,8 @@
mp->mnt_flag &= ~MNT_ASYNC;
cache_purgevfs(mp); /* remove cache entries for this file sys */
if (mp->mnt_syncer != NULL) {
- vgone(mp->mnt_syncer);
+ mp->mnt_syncer->v_writecount--;
+ vrele(mp->mnt_syncer);
mp->mnt_syncer = NULL;
}
if (((mp->mnt_flag & MNT_RDONLY) ||
>Release-Note:
>Audit-Trail:
>Unformatted: