Page MenuHomeFreeBSD

D52156.id160983.diff
No OneTemporary

D52156.id160983.diff

diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h
--- a/sys/fs/pseudofs/pseudofs.h
+++ b/sys/fs/pseudofs/pseudofs.h
@@ -31,6 +31,7 @@
#ifndef _PSEUDOFS_H_INCLUDED
#define _PSEUDOFS_H_INCLUDED
+#include <sys/_sx.h>
#include <sys/jail.h>
/*
@@ -189,8 +190,9 @@
* 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 during
- * vfs_init() and vfs_uninit() of the consumer filesystem.
+ * for unrhdr, and the pi_mountlock is used to coordinate initialization of the
+ * consumer filesystem on first ount. The rest of struct pfs_info is only
+ * modified during pi_init() and pi_uninit() of the consumer filesystem.
*/
struct pfs_info {
char pi_name[PFS_FSNAMELEN];
@@ -198,6 +200,7 @@
pfs_init_t pi_uninit;
/* members below this line are initialized at run time */
+ struct sx pi_mountlock;
struct pfs_node *pi_root;
struct mtx pi_mutex;
struct unrhdr *pi_unrhdr;
@@ -249,7 +252,7 @@
int pfs_root (struct mount *mp, int flags,
struct vnode **vpp);
int pfs_statfs (struct mount *mp, struct statfs *sbp);
-int pfs_init (struct pfs_info *pi, struct vfsconf *vfc);
+int pfs_vfsinit (struct pfs_info *pi, struct vfsconf *vfc);
int pfs_uninit (struct pfs_info *pi, struct vfsconf *vfc);
/*
@@ -276,9 +279,9 @@
#define PSEUDOFS(name, version, flags) \
\
static struct pfs_info name##_info = { \
- #name, \
- name##_init, \
- name##_uninit, \
+ .pi_name = #name, \
+ .pi_init = name##_init, \
+ .pi_uninit = name##_uninit, \
}; \
\
static int \
@@ -287,8 +290,8 @@
} \
\
static int \
-_##name##_init(struct vfsconf *vfc) { \
- return (pfs_init(&name##_info, vfc)); \
+_##name##_vfsinit(struct vfsconf *vfc) { \
+ return (pfs_vfsinit(&name##_info, vfc)); \
} \
\
static int \
@@ -298,7 +301,7 @@
\
static struct vfsops name##_vfsops = { \
.vfs_cmount = pfs_cmount, \
- .vfs_init = _##name##_init, \
+ .vfs_init = _##name##_vfsinit, \
.vfs_mount = _##name##_mount, \
.vfs_root = pfs_root, \
.vfs_statfs = pfs_statfs, \
diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c
--- a/sys/fs/pseudofs/pseudofs.c
+++ b/sys/fs/pseudofs/pseudofs.c
@@ -41,12 +41,15 @@
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sbuf.h>
+#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/vnode.h>
#include <fs/pseudofs/pseudofs.h>
#include <fs/pseudofs/pseudofs_internal.h>
+static int pfs_init(struct pfs_info *pi, struct vfsconf *vfc);
+
static MALLOC_DEFINE(M_PFSNODES, "pfs_nodes", "pseudofs nodes");
SYSCTL_NODE(_vfs, OID_AUTO, pfs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
@@ -382,10 +385,18 @@
pfs_mount(struct pfs_info *pi, struct mount *mp)
{
struct statfs *sbp;
+ int error = 0;
if (mp->mnt_flag & MNT_UPDATE)
return (EOPNOTSUPP);
+ sx_xlock(&pi->pi_mountlock);
+ if (pi->pi_root == NULL)
+ error = pfs_init(pi, mp->mnt_vfc);
+ sx_xunlock(&pi->pi_mountlock);
+ if (error != 0)
+ return (error);
+
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_kern_flag |= MNTK_NOMSYNC;
@@ -454,9 +465,21 @@
}
/*
- * Initialize a pseudofs instance
+ * Initialize pseudofs synchronization bits. These will generally be needed
+ * in order to avoid problems with parallel mounting of pseudofs consumers.
*/
int
+pfs_vfsinit(struct pfs_info *pi, struct vfsconf *vfc)
+{
+
+ sx_init(&pi->pi_mountlock, "pfs mountlock");
+ return (0);
+}
+
+/*
+ * Initialize a pseudofs instance
+ */
+static int
pfs_init(struct pfs_info *pi, struct vfsconf *vfc)
{
struct pfs_node *root;
@@ -490,15 +513,21 @@
int
pfs_uninit(struct pfs_info *pi, struct vfsconf *vfc)
{
- int error;
+ if (pi->pi_root != NULL) {
+ int error;
+
+ error = (pi->pi_uninit)(pi, vfc);
+ if (error != 0)
+ return (error);
+
+ pfs_destroy(pi->pi_root);
+ pi->pi_root = NULL;
+ pfs_fileno_uninit(pi);
+ }
- pfs_destroy(pi->pi_root);
- pi->pi_root = NULL;
- pfs_fileno_uninit(pi);
if (bootverbose)
printf("%s unregistered\n", pi->pi_name);
- error = (pi->pi_uninit)(pi, vfc);
- return (error);
+ return (0);
}
/*
diff --git a/sys/modules/pseudofs/Makefile b/sys/modules/pseudofs/Makefile
--- a/sys/modules/pseudofs/Makefile
+++ b/sys/modules/pseudofs/Makefile
@@ -13,7 +13,7 @@
pfs_unmount \
pfs_root \
pfs_statfs \
- pfs_init \
+ pfs_vfsinit \
pfs_uninit \
pfs_create_dir \
pfs_create_file \

File Metadata

Mime Type
text/plain
Expires
Thu, Aug 6, 2:24 AM (15 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36062547
Default Alt Text
D52156.id160983.diff (4 KB)

Event Timeline