diff options
author | dillon <dillon@FreeBSD.org> | 1999-10-30 00:51:14 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 1999-10-30 00:51:14 +0000 |
commit | 6554c27772118d5fb8324d1fa7ebc217d5e7c986 (patch) | |
tree | b607cb35136418636a1bd7b58a874bb9740f45d7 /sys/ufs | |
parent | 4e01e860c92cedcd8838ee525ab49fe99411affb (diff) | |
download | FreeBSD-src-6554c27772118d5fb8324d1fa7ebc217d5e7c986.zip FreeBSD-src-6554c27772118d5fb8324d1fa7ebc217d5e7c986.tar.gz |
Add sysctl debug.dircheck to allow directory sanity checking to be turned
on with a sysctl.
Fix two bugs in ufs_lookup that can cause deadlocks due to out-of-order
locking. This fix was tested for a few days prior to commit.
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ufs/ufs_lookup.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 020750d..77c0151a 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -48,6 +48,7 @@ #include <sys/stat.h> #include <sys/mount.h> #include <sys/vnode.h> +#include <sys/sysctl.h> #include <vm/vm.h> #include <vm/vm_extern.h> @@ -64,6 +65,8 @@ int dirchk = 1; int dirchk = 0; #endif +SYSCTL_INT(_debug, OID_AUTO, dircheck, CTLFLAG_RW, &dirchk, 0, ""); + /* true if old FS format...*/ #define OFSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0) @@ -452,7 +455,11 @@ found: *vpp = vdp; return (0); } + if (flags & ISDOTDOT) + VOP_UNLOCK(vdp, 0, p); /* race to get the inode */ error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp); + if (flags & ISDOTDOT) + vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p); if (error) return (error); /* @@ -489,7 +496,11 @@ found: */ if (dp->i_number == dp->i_ino) return (EISDIR); + if (flags & ISDOTDOT) + VOP_UNLOCK(vdp, 0, p); /* race to get the inode */ error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp); + if (flags & ISDOTDOT) + vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p); if (error) return (error); *vpp = tdp; |