summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2009-02-05 08:46:18 +0000
committertrasz <trasz@FreeBSD.org>2009-02-05 08:46:18 +0000
commita4e8c3ba997f73078710bd9a44277288dca15874 (patch)
treead7dbff1afb2c539ce3ab2fe6f719b0af6bcc18a /sys/kern
parentd0a09ee159f618321ade9364ccf8b823779b0ffe (diff)
downloadFreeBSD-src-a4e8c3ba997f73078710bd9a44277288dca15874.zip
FreeBSD-src-a4e8c3ba997f73078710bd9a44277288dca15874.tar.gz
In some situations, mnt_lockref could go negative due to vfs_unbusy() being
called without calling vfs_busy() first. This made umount(8) hang waiting for mnt_lockref to become zero, which would never happen. Reviewed by: kib Approved by: rwatson (mentor) Reported by: pho Found with: stress2 Sponsored by: FreeBSD Foundation
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_syscalls.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index a910bf3..be3dc76 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -395,14 +395,16 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
vfs_ref(mp);
VOP_UNLOCK(vp, 0);
fdrop(fp, td);
- if (vp->v_iflag & VI_DOOMED) {
+ if (mp == NULL) {
error = EBADF;
goto out;
}
error = vfs_busy(mp, 0);
vfs_rel(mp);
- if (error)
- goto out;
+ if (error) {
+ VFS_UNLOCK_GIANT(vfslocked);
+ return (error);
+ }
#ifdef MAC
error = mac_mount_check_stat(td->td_ucred, mp);
if (error)
OpenPOWER on IntegriCloud