summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ufs
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>1999-10-30 00:51:14 +0000
committerdillon <dillon@FreeBSD.org>1999-10-30 00:51:14 +0000
commit6554c27772118d5fb8324d1fa7ebc217d5e7c986 (patch)
treeb607cb35136418636a1bd7b58a874bb9740f45d7 /sys/ufs/ufs
parent4e01e860c92cedcd8838ee525ab49fe99411affb (diff)
downloadFreeBSD-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/ufs')
-rw-r--r--sys/ufs/ufs/ufs_lookup.c11
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;
OpenPOWER on IntegriCloud