summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rootdir.c55
1 files changed, 42 insertions, 13 deletions
diff --git a/rootdir.c b/rootdir.c
index 34bf91c..94b0ddb 100644
--- a/rootdir.c
+++ b/rootdir.c
@@ -407,6 +407,47 @@ rootdir_gc_fakeself (void *hook, char **contents, ssize_t *contents_len)
/* The mtab translator to use by default for the "mounts" node. */
#define MTAB_TRANSLATOR "/hurd/mtab"
+static struct node *rootdir_mounts_node;
+static pthread_spinlock_t rootdir_mounts_node_lock =
+ PTHREAD_SPINLOCK_INITIALIZER;
+
+static struct node *
+rootdir_mounts_make_node (void *dir_hook, const void *entry_hook)
+{
+ struct node *np, *prev;
+
+ pthread_spin_lock (&rootdir_mounts_node_lock);
+ np = rootdir_mounts_node;
+ pthread_spin_unlock (&rootdir_mounts_node_lock);
+
+ if (np != NULL)
+ {
+ netfs_nref (np);
+ return np;
+ }
+
+ np = procfs_make_node (entry_hook, dir_hook);
+ if (np == NULL)
+ return NULL;
+
+ procfs_node_chtype (np, S_IFREG | S_IPTRANS);
+ procfs_node_chmod (np, 0444);
+
+ pthread_spin_lock (&rootdir_mounts_node_lock);
+ prev = rootdir_mounts_node;
+ if (rootdir_mounts_node == NULL)
+ rootdir_mounts_node = np;
+ pthread_spin_unlock (&rootdir_mounts_node_lock);
+
+ if (prev != NULL)
+ {
+ procfs_cleanup (np);
+ np = prev;
+ }
+
+ return np;
+}
+
static error_t
rootdir_mounts_get_translator (void *hook, char **argz, size_t *argz_len)
{
@@ -451,18 +492,6 @@ rootdir_symlink_make_node (void *dir_hook, const void *entry_hook)
return np;
}
-static struct node *
-rootdir_translator_make_node (void *dir_hook, const void *entry_hook)
-{
- struct node *np = procfs_make_node (entry_hook, dir_hook);
- if (np)
- {
- procfs_node_chtype (np, S_IFREG | S_IPTRANS);
- procfs_node_chmod (np, 0444);
- }
- return np;
-}
-
static const struct procfs_dir_entry rootdir_entries[] = {
{
.name = "self",
@@ -530,7 +559,7 @@ static const struct procfs_dir_entry rootdir_entries[] = {
.get_translator = rootdir_mounts_get_translator,
},
.ops = {
- .make_node = rootdir_translator_make_node,
+ .make_node = rootdir_mounts_make_node,
.exists = rootdir_mounts_exists,
}
},