summaryrefslogtreecommitdiff
path: root/debian/patches/0001-libdiskfs-add-diskfs_make_node_alloc-to-allocate-fat.patch
blob: 6a873cdffd2830b2e8e9d60b08d81d3e4307c7c0 (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
139
140
141
142
143
144
145
146
147
148
149
From 80485401a9a5e9df03bd3a1503bc5e59d1f2e5c1 Mon Sep 17 00:00:00 2001
From: Justus Winter <4winter@informatik.uni-hamburg.de>
Date: Fri, 16 May 2014 23:06:33 +0200
Subject: [PATCH 01/14] libdiskfs: add diskfs_make_node_alloc to allocate fat
 nodes

libdiskfs has two kind of nodes, struct node and struct netnode.
struct node is used to store libdiskfs 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 diskfs_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 libdiskfs
easier.  Auxiliary data for the cache can be stored in the
user-defined netnode, and the fat node can be used as the value.

* libdiskfs/node-make.c (init_node): Move initialization here.
(diskfs_make_node): Use init_node.
(diskfs_make_node_alloc): New function to allocate fat nodes.
* libdiskfs/diskfs.h (diskfs_make_node_alloc): New declaration.
(_diskfs_sizeof_struct_node): Likewise.
(diskfs_node_disknode): Compute disknode address from node address.
(diskfs_disknode_node): And vice-versa.
* libdiskfs/init-init.c (_diskfs_sizeof_struct_node): New variable.
---
 libdiskfs/diskfs.h    | 27 +++++++++++++++++++++++++++
 libdiskfs/init-init.c |  4 ++++
 libdiskfs/node-make.c | 39 ++++++++++++++++++++++++++++++---------
 3 files changed, 61 insertions(+), 9 deletions(-)

diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index ae1a150..2c68aa3 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -686,6 +686,33 @@ diskfs_notice_filechange (struct node *np, enum file_changed_type type,
    The new node will have one hard reference and no light references.  */
 struct node *diskfs_make_node (struct disknode *dn);
 
+/* Create a new node structure.  Also allocate SIZE bytes for the
+   disknode.  The address of the disknode can be obtained using
+   diskfs_node_disknode.  The new node will have one hard reference
+   and no light references.  */
+struct node *diskfs_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 _diskfs_sizeof_struct_node;
+
+/* Return the address of the disknode for NODE.  NODE must have been
+   allocated using diskfs_make_node_alloc.  */
+static inline struct disknode *
+diskfs_node_disknode (struct node *node)
+{
+  return (struct disknode *) ((char *) node + _diskfs_sizeof_struct_node);
+}
+
+/* Return the address of the node for DISKNODE.  DISKNODE must have
+   been allocated using diskfs_make_node_alloc.  */
+static inline struct node *
+diskfs_disknode_node (struct disknode *disknode)
+{
+  return (struct node *) ((char *) disknode - _diskfs_sizeof_struct_node);
+}
+
 
 /* The library also exports the following functions; they are not generally
    useful unless you are redefining other functions the library provides. */
diff --git a/libdiskfs/init-init.c b/libdiskfs/init-init.c
index 35be7ed..7a7f248 100644
--- a/libdiskfs/init-init.c
+++ b/libdiskfs/init-init.c
@@ -25,6 +25,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <stdio.h>
 #include <maptime.h>
 
+/* For safe inlining of diskfs_node_disknode and
+   diskfs_disknode_node.  */
+size_t const _diskfs_sizeof_struct_node = sizeof (struct node);
+
 mach_port_t diskfs_default_pager;
 mach_port_t diskfs_auth_server_port;
 volatile struct mapped_time_value *diskfs_mtime;
diff --git a/libdiskfs/node-make.c b/libdiskfs/node-make.c
index 2b6ef2a..ff0cc0d 100644
--- a/libdiskfs/node-make.c
+++ b/libdiskfs/node-make.c
@@ -19,16 +19,9 @@
 #include <fcntl.h>
 
 
-/* Create a and return new node structure with DN as its physical disknode.
-   The node will have one hard reference and no light references.  */
-struct node *
-diskfs_make_node (struct disknode *dn)
+static struct node *
+init_node (struct node *np, struct disknode *dn)
 {
-  struct node *np = malloc (sizeof (struct node));
-
-  if (np == 0)
-    return 0;
-
   np->dn = dn;
   np->dn_set_ctime = 0;
   np->dn_set_atime = 0;
@@ -52,3 +45,31 @@ diskfs_make_node (struct disknode *dn)
 
   return np;
 }
+
+/* Create a and return new node structure with DN as its physical disknode.
+   The node will have one hard reference and no light references.  */
+struct node *
+diskfs_make_node (struct disknode *dn)
+{
+  struct node *np = malloc (sizeof (struct node));
+
+  if (np == 0)
+    return 0;
+
+  return init_node (np, dn);
+}
+
+/* Create a new node structure.  Also allocate SIZE bytes for the
+   disknode.  The address of the disknode can be obtained using
+   diskfs_node_disknode.  The new node will have one hard reference
+   and no light references.  */
+struct node *
+diskfs_make_node_alloc (size_t size)
+{
+  struct node *np = malloc (sizeof (struct node) + size);
+
+  if (np == NULL)
+    return NULL;
+
+  return init_node (np, diskfs_node_disknode (np));
+}
-- 
2.0.0.rc2