summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libnetfs/init-init.c3
-rw-r--r--libnetfs/make-node.c29
-rw-r--r--libnetfs/netfs.h27
3 files changed, 53 insertions, 6 deletions
diff --git a/libnetfs/init-init.c b/libnetfs/init-init.c
index e98b6562..a088ad51 100644
--- a/libnetfs/init-init.c
+++ b/libnetfs/init-init.c
@@ -21,6 +21,9 @@
#include "netfs.h"
+/* For safe inlining of netfs_node_netnode and netfs_netnode_node. */
+size_t const _netfs_sizeof_struct_node = sizeof (struct node);
+
pthread_spinlock_t netfs_node_refcnt_lock = PTHREAD_SPINLOCK_INITIALIZER;
struct node *netfs_root_node = 0;
diff --git a/libnetfs/make-node.c b/libnetfs/make-node.c
index f20ada18..6bd8109c 100644
--- a/libnetfs/make-node.c
+++ b/libnetfs/make-node.c
@@ -21,13 +21,9 @@
#include "netfs.h"
#include <hurd/fshelp.h>
-struct node *
-netfs_make_node (struct netnode *nn)
+static struct node *
+init_node (struct node *np, struct netnode *nn)
{
- struct node *np = malloc (sizeof (struct node));
- if (! np)
- return NULL;
-
np->nn = nn;
pthread_mutex_init (&np->lock, NULL);
@@ -40,3 +36,24 @@ netfs_make_node (struct netnode *nn)
return np;
}
+
+struct node *
+netfs_make_node (struct netnode *nn)
+{
+ struct node *np = malloc (sizeof (struct node));
+ if (! np)
+ return NULL;
+
+ return init_node (np, nn);
+}
+
+struct node *
+netfs_make_node_alloc (size_t size)
+{
+ struct node *np = malloc (sizeof (struct node) + size);
+
+ if (np == NULL)
+ return NULL;
+
+ return init_node (np, netfs_node_netnode (np));
+}
diff --git a/libnetfs/netfs.h b/libnetfs/netfs.h
index aef4a3dd..fbe2c60d 100644
--- a/libnetfs/netfs.h
+++ b/libnetfs/netfs.h
@@ -372,6 +372,33 @@ extern int netfs_maxsymlinks;
If an error occurs, NULL is returned. */
struct node *netfs_make_node (struct netnode *);
+/* Create a new node structure. Also allocate SIZE bytes for the
+ netnode. The address of the netnode can be obtained using
+ netfs_node_netnode. The new node will have one hard reference and
+ no light references. If an error occurs, NULL is returned. */
+struct node *netfs_make_node_alloc (size_t size);
+
+/* To avoid breaking the ABI whenever sizeof (struct node) changes, we
+ explicitly provide the size. The following two functions will use
+ this value for offset calculations. */
+extern const size_t _netfs_sizeof_struct_node;
+
+/* Return the address of the netnode for NODE. NODE must have been
+ allocated using netfs_make_node_alloc. */
+static inline struct netnode *
+netfs_node_netnode (struct node *node)
+{
+ return (struct netnode *) ((char *) node + _netfs_sizeof_struct_node);
+}
+
+/* Return the address of the node for NETNODE. NETNODE must have been
+ allocated using netfs_make_node_alloc. */
+static inline struct node *
+netfs_netnode_node (struct netnode *netnode)
+{
+ return (struct node *) ((char *) netnode - _netfs_sizeof_struct_node);
+}
+
/* Whenever node->references is to be touched, this lock must be
held. Cf. netfs_nrele, netfs_nput, netfs_nref and netfs_drop_node. */
extern pthread_spinlock_t netfs_node_refcnt_lock;