diff options
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/pseudofs/pseudofs.c | 34 | ||||
-rw-r--r-- | sys/fs/pseudofs/pseudofs.h | 8 | ||||
-rw-r--r-- | sys/fs/pseudofs/pseudofs_fileno.c | 38 | ||||
-rw-r--r-- | sys/fs/pseudofs/pseudofs_internal.h | 4 | ||||
-rw-r--r-- | sys/fs/pseudofs/pseudofs_vncache.c | 11 | ||||
-rw-r--r-- | sys/fs/pseudofs/pseudofs_vnops.c | 26 |
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 */ |