diff options
-rw-r--r-- | sys/ufs/ufs/dirhash.h | 2 | ||||
-rw-r--r-- | sys/ufs/ufs/quota.h | 1 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_dirhash.c | 11 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_extern.h | 2 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_ihash.c | 11 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_quota.c | 15 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vfsops.c | 30 |
7 files changed, 65 insertions, 7 deletions
diff --git a/sys/ufs/ufs/dirhash.h b/sys/ufs/ufs/dirhash.h index 4aea6c1..1acb4ef 100644 --- a/sys/ufs/ufs/dirhash.h +++ b/sys/ufs/ufs/dirhash.h @@ -108,6 +108,8 @@ struct dirhash { /* * Dirhash functions. */ +void ufsdirhash_init(void); +void ufsdirhash_uninit(void); int ufsdirhash_build(struct inode *); doff_t ufsdirhash_findfree(struct inode *, int, int *); doff_t ufsdirhash_enduseful(struct inode *); diff --git a/sys/ufs/ufs/quota.h b/sys/ufs/ufs/quota.h index 15f512c..df5d1f37 100644 --- a/sys/ufs/ufs/quota.h +++ b/sys/ufs/ufs/quota.h @@ -182,6 +182,7 @@ int chkdq(struct inode *, int64_t, struct ucred *, int); int chkiq(struct inode *, ino_t, struct ucred *, int); void dqinit(void); void dqrele(struct vnode *, struct dquot *); +void dquninit(void); int getinoquota(struct inode *); int getquota(struct mount *, u_long, int, caddr_t); int qsync(struct mount *mp); diff --git a/sys/ufs/ufs/ufs_dirhash.c b/sys/ufs/ufs/ufs_dirhash.c index a5600da..4473791 100644 --- a/sys/ufs/ufs/ufs_dirhash.c +++ b/sys/ufs/ufs/ufs_dirhash.c @@ -85,7 +85,6 @@ static void ufsdirhash_delslot(struct dirhash *dh, int slot); static int ufsdirhash_findslot(struct dirhash *dh, char *name, int namelen, doff_t offset); static doff_t ufsdirhash_getprev(struct direct *dp, doff_t offset); -static void ufsdirhash_init(void); static int ufsdirhash_recycle(int wanted); static uma_zone_t ufsdirhash_zone; @@ -1059,7 +1058,7 @@ ufsdirhash_recycle(int wanted) } -static void +void ufsdirhash_init() { ufsdirhash_zone = uma_zcreate("DIRHASH", DH_NBLKOFF * sizeof(doff_t), @@ -1067,7 +1066,13 @@ ufsdirhash_init() mtx_init(&ufsdirhash_mtx, "dirhash list", NULL, MTX_DEF); TAILQ_INIT(&ufsdirhash_list); } -SYSINIT(ufsdirhash, SI_SUB_PSEUDO, SI_ORDER_ANY, ufsdirhash_init, NULL) +void +ufsdirhash_uninit() +{ + KASSERT(TAILQ_EMPTY(&ufsdirhash_list), ("ufsdirhash_uninit")); + uma_zdestroy(ufsdirhash_zone); + mtx_destroy(&ufsdirhash_mtx); +} #endif /* UFS_DIRHASH */ diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h index bedbf5b..85b508a 100644 --- a/sys/ufs/ufs/ufs_extern.h +++ b/sys/ufs/ufs/ufs_extern.h @@ -80,6 +80,7 @@ int ufs_ihashins(struct inode *, int, struct vnode **); struct vnode * ufs_ihashlookup(dev_t, ino_t); void ufs_ihashrem(struct inode *); +void ufs_ihashuninit(void); int ufs_inactive(struct vop_inactive_args *); int ufs_init(struct vfsconf *); void ufs_itimes(struct vnode *vp); @@ -89,6 +90,7 @@ int ufs_reclaim(struct vop_reclaim_args *); void ffs_snapgone(struct inode *); int ufs_root(struct mount *, struct vnode **); int ufs_start(struct mount *, int, struct thread *); +int ufs_uninit(struct vfsconf *); int ufs_vinit(struct mount *, vop_t **, vop_t **, struct vnode **); /* diff --git a/sys/ufs/ufs/ufs_ihash.c b/sys/ufs/ufs/ufs_ihash.c index 9b0062a..75e0093 100644 --- a/sys/ufs/ufs/ufs_ihash.c +++ b/sys/ufs/ufs/ufs_ihash.c @@ -68,6 +68,17 @@ ufs_ihashinit() } /* + * Destroy the inode hash table. + */ +void +ufs_ihashuninit() +{ + + hashdestroy(ihashtbl, M_UFSIHASH, ihash); + mtx_destroy(&ufs_ihash_mtx); +} + +/* * Use the device/inum pair to find the incore inode, and return a pointer * to it. If it is in core, return it, even if it is locked. */ diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index 3bc4287..dcbe6f79 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -754,6 +754,21 @@ dqinit() } /* + * Shut down the quota system. + */ +void +dquninit() +{ + struct dquot *dq; + + hashdestroy(dqhashtbl, M_DQUOT, dqhash); + while ((dq = TAILQ_FIRST(&dqfreelist)) != NULL) { + TAILQ_REMOVE(&dqfreelist, dq, dq_freelist); + free(dq, M_DQUOT); + } +} + +/* * Obtain a dquot structure for the specified identifier and quota file * reading the information from the file if necessary. */ diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index 59e2390..442d823 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -40,6 +40,7 @@ */ #include "opt_quota.h" +#include "opt_ufs.h" #include <sys/param.h> #include <sys/systm.h> @@ -56,6 +57,10 @@ #include <ufs/ufs/inode.h> #include <ufs/ufs/ufsmount.h> #include <ufs/ufs/ufs_extern.h> +#ifdef UFS_DIRHASH +#include <ufs/ufs/dir.h> +#include <ufs/ufs/dirhash.h> +#endif MALLOC_DEFINE(M_UFSMNT, "UFS mount", "UFS mount structure"); /* @@ -171,15 +176,32 @@ int ufs_init(vfsp) struct vfsconf *vfsp; { - static int done; - if (done) - return (0); - done = 1; ufs_ihashinit(); #ifdef QUOTA dqinit(); #endif +#ifdef UFS_DIRHASH + ufsdirhash_init(); +#endif + return (0); +} + +/* + * Uninitialise UFS filesystems, done before module unload. + */ +int +ufs_uninit(vfsp) + struct vfsconf *vfsp; +{ + + ufs_ihashuninit(); +#ifdef QUOTA + dquninit(); +#endif +#ifdef UFS_DIRHASH + ufsdirhash_uninit(); +#endif return (0); } |