summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/ufs/ufs/dirhash.h2
-rw-r--r--sys/ufs/ufs/quota.h1
-rw-r--r--sys/ufs/ufs/ufs_dirhash.c11
-rw-r--r--sys/ufs/ufs/ufs_extern.h2
-rw-r--r--sys/ufs/ufs/ufs_ihash.c11
-rw-r--r--sys/ufs/ufs/ufs_quota.c15
-rw-r--r--sys/ufs/ufs/ufs_vfsops.c30
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);
}
OpenPOWER on IntegriCloud