diff options
author | iedowse <iedowse@FreeBSD.org> | 2001-08-26 20:47:19 +0000 |
---|---|---|
committer | iedowse <iedowse@FreeBSD.org> | 2001-08-26 20:47:19 +0000 |
commit | bff1ce4c20830226c53b34bfe46cd59cb4b269f6 (patch) | |
tree | d3dd877f730ba39c56a402a7e8d8916b8dca0a39 /sys/ufs | |
parent | a88b1ce13d5bea3b1414e2739b83df71478e6bda (diff) | |
download | FreeBSD-src-bff1ce4c20830226c53b34bfe46cd59cb4b269f6.zip FreeBSD-src-bff1ce4c20830226c53b34bfe46cd59cb4b269f6.tar.gz |
Stop using dirhash when a directory is removed, and ensure that we
never attempt to hash directories once they are deleted. This fixes
a problem where operations on a deleted directory could trigger
dirhash sanity panics.
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ufs/ufs_dirhash.c | 4 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 8 |
2 files changed, 12 insertions, 0 deletions
diff --git a/sys/ufs/ufs/ufs_dirhash.c b/sys/ufs/ufs/ufs_dirhash.c index e9441cb..2a69f6b 100644 --- a/sys/ufs/ufs/ufs_dirhash.c +++ b/sys/ufs/ufs/ufs_dirhash.c @@ -135,6 +135,10 @@ ufsdirhash_build(struct inode *ip) ufsdirhash_free(ip); } + /* Don't hash removed directories. */ + if (ip->i_effnlink == 0) + return (-1); + vp = ip->i_vnode; /* Allocate 50% more entries than this dir size could ever need. */ KASSERT(ip->i_size >= DIRBLKSIZ, ("ufsdirhash_build size")); diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index a095798..c0826cf 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -77,6 +77,9 @@ #include <ufs/ufs/dir.h> #include <ufs/ufs/ufsmount.h> #include <ufs/ufs/ufs_extern.h> +#ifdef UFS_DIRHASH +#include <ufs/ufs/dirhash.h> +#endif static int ufs_access __P((struct vop_access_args *)); static int ufs_advlock __P((struct vop_advlock_args *)); @@ -1691,6 +1694,11 @@ ufs_rmdir(ap) cnp->cn_proc); } cache_purge(vp); +#ifdef UFS_DIRHASH + /* Kill any active hash; i_effnlink == 0, so it will not come back. */ + if (ip->i_dirhash != NULL) + ufsdirhash_free(ip); +#endif out: VN_KNOTE(vp, NOTE_DELETE); return (error); |