summaryrefslogtreecommitdiff
path: root/debian/patches/0002-libnetfs-add-netfs_make_node_alloc-to-allocate-fat-n.patch
blob: 959f7188b5c31d7a7f06620ede2f0ead624cca1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
From 94fecd72f41542c8dfa82bdf7b47742f8c29b321 Mon Sep 17 00:00:00 2001
From: Justus Winter <4winter@informatik.uni-hamburg.de>
Date: Sun, 18 May 2014 13:34:12 +0200
Subject: [PATCH 02/11] libnetfs: add netfs_make_node_alloc to allocate fat
 nodes

libnetfs has two kind of nodes, struct node and struct netnode.
struct node is used to store libnetfs specific data, while struct
netnode contains user supplied data.  Previously, both objects were
allocated separatly, and a pointer from the node to the netnode
provided a mapping from the former to the latter.

Provide a function netfs_make_node_alloc that allocates both nodes in
a contiguous region.

This reduces the memory allocation overhead when creating nodes.  It
also makes the relation between node and netnode a simple offset
calculation.  Provide two functions to compute the netnode address
from the node address and vice-versa.

Most notably, this makes implementing a cache on top of libnetfs
easier.  Auxiliary data for the cache can be stored in the
user-defined netnode, and the fat node can be used as the value.

* libnetfs/make-node.c (init_node): Move initialization here.
(netfs_make_node): Use init_node.
(netfs_make_node_alloc): New function to allocate fat nodes.
* libnetfs/netfs.h (netfs_make_node_alloc): New declaration.
(_netfs_sizeof_struct_node): Likewise.
(netfs_node_netnode): Compute netnode address from node address.
(netfs_netnode_node): And vice-versa.
* libnetfs/init-init.c (_netfs_sizeof_struct_node): New variable.
---
 libnetfs/init-init.c |  3 +++
 libnetfs/make-node.c | 29 +++++++++++++++++++++++------
 libnetfs/netfs.h     | 27 +++++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/libnetfs/init-init.c b/libnetfs/init-init.c
index e98b656..a088ad5 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 f20ada1..6bd8109 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 aef4a3d..fbe2c60 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;
-- 
2.0.0.rc2