summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/pseudofs/pseudofs.c34
-rw-r--r--sys/fs/pseudofs/pseudofs.h8
-rw-r--r--sys/fs/pseudofs/pseudofs_fileno.c38
-rw-r--r--sys/fs/pseudofs/pseudofs_internal.h4
-rw-r--r--sys/fs/pseudofs/pseudofs_vncache.c11
-rw-r--r--sys/fs/pseudofs/pseudofs_vnops.c26
6 files changed, 59 insertions, 62 deletions
diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c
index 9464e9c..82ec971 100644
--- a/sys/fs/pseudofs/pseudofs.c
+++ b/sys/fs/pseudofs/pseudofs.c
@@ -73,7 +73,6 @@ _pfs_add_node(struct pfs_node *parent, struct pfs_node *node)
/* XXX should check for duplicate names etc. */
- mtx_lock(&parent->pn_info->pi_mutex);
node->pn_info = parent->pn_info;
node->pn_parent = parent;
node->pn_next = parent->pn_nodes;
@@ -81,7 +80,6 @@ _pfs_add_node(struct pfs_node *parent, struct pfs_node *node)
/* Propagate flag to all child nodes (and thus their vnodes) */
if ((parent->pn_flags & PFS_PROCDEP) != 0)
node->pn_flags |= PFS_PROCDEP;
- mtx_unlock(&parent->pn_info->pi_mutex);
return (0);
}
@@ -210,8 +208,8 @@ pfs_find_node(struct pfs_node *parent, const char *name)
for (node = parent->pn_nodes; node != NULL; node = node->pn_next)
if (strcmp(node->pn_name, name) == 0)
- return (node);
- return (NULL);
+ break;
+ return (node);
}
/*
@@ -220,7 +218,7 @@ pfs_find_node(struct pfs_node *parent, const char *name)
int
pfs_destroy(struct pfs_node *node)
{
- struct pfs_node *parent, *rover;
+ struct pfs_node *parent, **rover;
KASSERT(node != NULL,
("%s(): node is NULL", __func__));
@@ -238,20 +236,14 @@ pfs_destroy(struct pfs_node *node)
if ((parent = node->pn_parent) != NULL) {
KASSERT(parent->pn_info == node->pn_info,
("%s(): parent has different pn_info", __func__));
- mtx_lock(&node->pn_info->pi_mutex);
- if (parent->pn_nodes == node) {
- parent->pn_nodes = node->pn_next;
- } else {
- rover = parent->pn_nodes;
- while (rover->pn_next != NULL) {
- if (rover->pn_next == node) {
- rover->pn_next = node->pn_next;
- break;
- }
- rover = rover->pn_next;
+ rover = &parent->pn_nodes;
+ while (*rover != NULL) {
+ if (*rover == node) {
+ *rover = node->pn_next;
+ break;
}
+ rover = &(*rover)->pn_next;
}
- mtx_unlock(&node->pn_info->pi_mutex);
}
/* callback to free any private resources */
@@ -260,7 +252,7 @@ pfs_destroy(struct pfs_node *node)
/* revoke fileno and vnodes and release memory */
if (node->pn_fileno)
- pfs_fileno_free(node->pn_info, node);
+ pfs_fileno_free(node);
pfs_purge(node);
FREE(node, M_PFSNODES);
@@ -358,7 +350,7 @@ pfs_init(struct pfs_info *pi, struct vfsconf *vfc)
struct pfs_node *root;
int error;
- mtx_init(&pi->pi_mutex, "pseudofs", NULL, MTX_DEF);
+ mtx_assert(&Giant, MA_OWNED);
/* set up the root diretory */
MALLOC(root, struct pfs_node *, sizeof *root,
@@ -377,7 +369,6 @@ pfs_init(struct pfs_info *pi, struct vfsconf *vfc)
if (error) {
pfs_destroy(root);
pi->pi_root = NULL;
- mtx_destroy(&pi->pi_mutex);
return (error);
}
@@ -395,10 +386,11 @@ pfs_uninit(struct pfs_info *pi, struct vfsconf *vfc)
{
int error;
+ mtx_assert(&Giant, MA_OWNED);
+
pfs_destroy(pi->pi_root);
pi->pi_root = NULL;
pfs_fileno_uninit(pi);
- mtx_destroy(&pi->pi_mutex);
if (bootverbose)
printf("%s unregistered\n", pi->pi_name);
error = (pi->pi_uninit)(pi, vfc);
diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h
index bb1efd1..4fa3311 100644
--- a/sys/fs/pseudofs/pseudofs.h
+++ b/sys/fs/pseudofs/pseudofs.h
@@ -165,14 +165,18 @@ typedef int (*pfs_destroy_t)(PFS_DESTROY_ARGS);
/*
* pfs_info: describes a pseudofs instance
+ *
+ * The pi_mutex is only used to avoid using the global subr_unit lock for
+ * unrhdr. The rest of struct pfs_info is only modified while Giant is
+ * held (during vfs_init() and vfs_uninit()).
*/
struct pfs_info {
char pi_name[PFS_FSNAMELEN];
pfs_init_t pi_init;
pfs_init_t pi_uninit;
- /* members below this line aren't initialized */
+
+ /* members below this line are initialized at run time*/
struct pfs_node *pi_root;
- /* currently, the mutex is only used to protect the bitmap */
struct mtx pi_mutex;
struct unrhdr *pi_unrhdr;
};
diff --git a/sys/fs/pseudofs/pseudofs_fileno.c b/sys/fs/pseudofs/pseudofs_fileno.c
index 10c1617..155b0f5 100644
--- a/sys/fs/pseudofs/pseudofs_fileno.c
+++ b/sys/fs/pseudofs/pseudofs_fileno.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
@@ -50,12 +51,10 @@ __FBSDID("$FreeBSD$");
void
pfs_fileno_init(struct pfs_info *pi)
{
- struct unrhdr *up;
- up = new_unrhdr(3, INT_MAX, &pi->pi_mutex);
- mtx_lock(&pi->pi_mutex);
- pi->pi_unrhdr = up;
- mtx_unlock(&pi->pi_mutex);
+ mtx_assert(&Giant, MA_OWNED);
+ mtx_init(&pi->pi_mutex, "pfs_fileno", NULL, MTX_DEF);
+ pi->pi_unrhdr = new_unrhdr(3, INT_MAX / NO_PID, &pi->pi_mutex);
}
/*
@@ -64,30 +63,23 @@ pfs_fileno_init(struct pfs_info *pi)
void
pfs_fileno_uninit(struct pfs_info *pi)
{
- struct unrhdr *up;
- mtx_lock(&pi->pi_mutex);
-
- up = pi->pi_unrhdr;
+ mtx_assert(&Giant, MA_OWNED);
+ delete_unrhdr(pi->pi_unrhdr);
pi->pi_unrhdr = NULL;
-
- mtx_unlock(&pi->pi_mutex);
-
- delete_unrhdr(up);
+ mtx_destroy(&pi->pi_mutex);
}
/*
* Allocate a file number
*/
void
-pfs_fileno_alloc(struct pfs_info *pi, struct pfs_node *pn)
+pfs_fileno_alloc(struct pfs_node *pn)
{
- /* pi is not really necessary as it can be derived */
- KASSERT(pi == pn->pn_info, ("pn / pi mismatch"));
/* make sure our parent has a file number */
if (pn->pn_parent && !pn->pn_parent->pn_fileno)
- pfs_fileno_alloc(pi, pn->pn_parent);
+ pfs_fileno_alloc(pn->pn_parent);
switch (pn->pn_type) {
case pfstype_root:
@@ -98,7 +90,7 @@ pfs_fileno_alloc(struct pfs_info *pi, struct pfs_node *pn)
case pfstype_file:
case pfstype_symlink:
case pfstype_procdir:
- pn->pn_fileno = alloc_unr(pi->pi_unrhdr);
+ pn->pn_fileno = alloc_unr(pn->pn_info->pi_unrhdr);
break;
case pfstype_this:
KASSERT(pn->pn_parent != NULL,
@@ -108,7 +100,7 @@ pfs_fileno_alloc(struct pfs_info *pi, struct pfs_node *pn)
case pfstype_parent:
KASSERT(pn->pn_parent != NULL,
("pfstype_parent node has no parent"));
- if (pn->pn_parent == pi->pi_root) {
+ if (pn->pn_parent == pn->pn_info->pi_root) {
pn->pn_fileno = pn->pn_parent->pn_fileno;
break;
}
@@ -123,7 +115,7 @@ pfs_fileno_alloc(struct pfs_info *pi, struct pfs_node *pn)
}
#if 0
- printf("pfs_fileno_alloc(): %s: ", pi->pi_name);
+ printf("pfs_fileno_alloc(): %s: ", pn->pn_info->pi_name);
if (pn->pn_parent) {
if (pn->pn_parent->pn_parent) {
printf("%s/", pn->pn_parent->pn_parent->pn_name);
@@ -138,10 +130,8 @@ pfs_fileno_alloc(struct pfs_info *pi, struct pfs_node *pn)
* Release a file number
*/
void
-pfs_fileno_free(struct pfs_info *pi, struct pfs_node *pn)
+pfs_fileno_free(struct pfs_node *pn)
{
- /* pi is not really necessary as it can be derived */
- KASSERT(pi == pn->pn_info, ("pn / pi mismatch"));
switch (pn->pn_type) {
case pfstype_root:
@@ -151,7 +141,7 @@ pfs_fileno_free(struct pfs_info *pi, struct pfs_node *pn)
case pfstype_file:
case pfstype_symlink:
case pfstype_procdir:
- free_unr(pi->pi_unrhdr, pn->pn_fileno);
+ free_unr(pn->pn_info->pi_unrhdr, pn->pn_fileno);
break;
case pfstype_this:
case pfstype_parent:
diff --git a/sys/fs/pseudofs/pseudofs_internal.h b/sys/fs/pseudofs/pseudofs_internal.h
index 6abd704..8f213ed 100644
--- a/sys/fs/pseudofs/pseudofs_internal.h
+++ b/sys/fs/pseudofs/pseudofs_internal.h
@@ -61,7 +61,7 @@ int pfs_vncache_free (struct vnode *);
*/
void pfs_fileno_init (struct pfs_info *);
void pfs_fileno_uninit (struct pfs_info *);
-void pfs_fileno_alloc (struct pfs_info *, struct pfs_node *);
-void pfs_fileno_free (struct pfs_info *, struct pfs_node *);
+void pfs_fileno_alloc (struct pfs_node *);
+void pfs_fileno_free (struct pfs_node *);
#endif
diff --git a/sys/fs/pseudofs/pseudofs_vncache.c b/sys/fs/pseudofs/pseudofs_vncache.c
index e4d8db8..7544cb1 100644
--- a/sys/fs/pseudofs/pseudofs_vncache.c
+++ b/sys/fs/pseudofs/pseudofs_vncache.c
@@ -83,7 +83,9 @@ extern struct vop_vector pfs_vnodeops; /* XXX -> .h file */
void
pfs_vncache_load(void)
{
- mtx_init(&pfs_vncache_mutex, "pseudofs_vncache", NULL, MTX_DEF);
+
+ mtx_assert(&Giant, MA_OWNED);
+ mtx_init(&pfs_vncache_mutex, "pfs_vncache", NULL, MTX_DEF);
pfs_exit_tag = EVENTHANDLER_REGISTER(process_exit, pfs_exit, NULL,
EVENTHANDLER_PRI_ANY);
}
@@ -94,10 +96,11 @@ pfs_vncache_load(void)
void
pfs_vncache_unload(void)
{
+
+ mtx_assert(&Giant, MA_OWNED);
EVENTHANDLER_DEREGISTER(process_exit, pfs_exit_tag);
- if (pfs_vncache_entries != 0)
- printf("pfs_vncache_unload(): %d entries remaining\n",
- pfs_vncache_entries);
+ KASSERT(pfs_vncache_entries == 0,
+ ("%d vncache entries remaining", pfs_vncache_entries));
mtx_destroy(&pfs_vncache_mutex);
}
diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c
index 347513f..e36e102 100644
--- a/sys/fs/pseudofs/pseudofs_vnops.c
+++ b/sys/fs/pseudofs/pseudofs_vnops.c
@@ -81,6 +81,19 @@ SYSCTL_INT(_vfs_pfs, OID_AUTO, trace, CTLFLAG_RW, &pfs_trace, 0,
#endif
/*
+ *
+ */
+static uint32_t
+pfs_fileno(struct pfs_node *pn, pid_t pid)
+{
+ if (!pn->pn_fileno)
+ pfs_fileno_alloc(pn);
+ if (pid != NO_PID)
+ return (pn->pn_fileno * NO_PID + pid);
+ return (pn->pn_fileno);
+}
+
+/*
* Returns non-zero if given file is visible to given process. If the 'p'
* parameter is non-NULL, then it will hold a pointer to the process the
* given file belongs to on return and the process will be locked.
@@ -193,7 +206,7 @@ pfs_getattr(struct vop_getattr_args *va)
VATTR_NULL(vap);
vap->va_type = vn->v_type;
- vap->va_fileid = pn->pn_fileno;
+ vap->va_fileid = pfs_fileno(pn, pvd->pvd_pid);
vap->va_flags = 0;
vap->va_blocksize = PAGE_SIZE;
vap->va_bytes = vap->va_size = 0;
@@ -591,7 +604,6 @@ static int
pfs_readdir(struct vop_readdir_args *va)
{
struct vnode *vn = va->a_vp;
- struct pfs_info *pi = (struct pfs_info *)vn->v_mount->mnt_data;
struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
struct pfs_node *pd = pvd->pvd_pn;
pid_t pid = pvd->pvd_pid;
@@ -603,6 +615,8 @@ pfs_readdir(struct vop_readdir_args *va)
int error, i, resid;
char *buf, *ent;
+ KASSERT(pd->pn_info == vn->v_mount->mnt_data,
+ ("directory's pn_info does not match mountpoint's mnt_data"));
PFS_TRACE((pd->pn_name));
if (vn->v_type != VDIR)
@@ -639,12 +653,7 @@ pfs_readdir(struct vop_readdir_args *va)
entry->d_reclen = PFS_DELEN;
if (!pn->pn_parent)
pn->pn_parent = pd;
- if (!pn->pn_fileno)
- pfs_fileno_alloc(pi, pn);
- if (pid != NO_PID)
- entry->d_fileno = pn->pn_fileno * NO_PID + pid;
- else
- entry->d_fileno = pn->pn_fileno;
+ entry->d_fileno = pfs_fileno(pn, pid);
/* PFS_DELEN was picked to fit PFS_NAMLEN */
for (i = 0; i < PFS_NAMELEN - 1 && pn->pn_name[i] != '\0'; ++i)
entry->d_name[i] = pn->pn_name[i];
@@ -654,7 +663,6 @@ pfs_readdir(struct vop_readdir_args *va)
case pfstype_procdir:
KASSERT(p != NULL,
("reached procdir node with p == NULL"));
- entry->d_fileno = pn->pn_fileno * NO_PID + p->p_pid;
entry->d_namlen = snprintf(entry->d_name,
PFS_NAMELEN, "%d", p->p_pid);
/* fall through */
OpenPOWER on IntegriCloud