summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Tricca <flihp@twobit.us>2016-02-18 21:53:36 +0000
committerPhilip Tricca <flihp@twobit.us>2016-02-27 05:36:54 +0000
commitb2b3ea27e3e3ebcafda0972b999323d7683158cf (patch)
tree56621328c1f2c9527aef2129f6de28449ed63cf4
parenta7ff3c22ace4f44172a3300ad1a6c56ab60ee70c (diff)
downloadmeta-selinux-b2b3ea27e3e3ebcafda0972b999323d7683158cf.tar.gz
e2fsprogs: Superseded by upstream.
Signed-off-by: Philip Tricca <flihp@twobit.us>
-rw-r--r--recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-add-xattr-module-stub.patch57
-rw-r--r--recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch175
-rw-r--r--recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block.patch341
-rw-r--r--recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch181
-rw-r--r--recipes-devtools/e2fsprogs/e2fsprogs/mke2fs.c-create_inode.c-copy-xattrs.patch164
-rw-r--r--recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend12
6 files changed, 0 insertions, 930 deletions
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-add-xattr-module-stub.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-add-xattr-module-stub.patch
deleted file mode 100644
index 5a39abe..0000000
--- a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-add-xattr-module-stub.patch
+++ /dev/null
@@ -1,57 +0,0 @@
1This patch adds the structure for a module to duplicate xattr blocks as part
2of copying files with the '-d' option to mke2fs. The function stubs here are
3intended to be the public interface to the module. We also define a macro
4for dumping debug data specific to this module.
5
6Signed-off-by: Philip Tricca <flihp@twobit.us>
7
8Index: e2fsprogs-1.42.9/misc/xattr.c
9===================================================================
10--- /dev/null
11+++ e2fsprogs-1.42.9/misc/xattr.c
12@@ -0,0 +1,34 @@
13+#include "xattr.h"
14+
15+#include <stdio.h>
16+
17+#ifdef XATTR_DEBUG
18+#define XATTR_STDERR(fmt, args...) fprintf (stderr, fmt, ##args)
19+#else
20+#define XATTR_STDERR(fmt, args...) do {} while (0)
21+#endif
22+
23+
24+/* Free remaining resources after all files have been processed. */
25+void
26+xattr_cleanup ()
27+{
28+ XATTR_STDERR ("Cleaning up resources from xattrs.\n");
29+}
30+
31+/* This is the entry point to the xattr module. This function copies the xattrs
32+ * from the file at 'path' to the file system object at 'ino'.
33+ *
34+ * Parameters:
35+ * fs: the file system object for the fs we're operating on
36+ * ino: inode for the object we're labeling
37+ * path: path to the object we're copying xattrs from
38+ */
39+errcode_t
40+set_inode_xattr (ext2_filsys fs, ext2_ino_t ino, const char *path)
41+{
42+ errcode_t ret = 0;
43+
44+ XATTR_STDERR ("Copying xattrs from %s to inode 0x%x.\n", path, ino);
45+ return ret;
46+}
47Index: e2fsprogs-1.42.9/misc/xattr.h
48===================================================================
49--- /dev/null
50+++ e2fsprogs-1.42.9/misc/xattr.h
51@@ -0,0 +1,6 @@
52+#include "et/com_err.h"
53+#include "ext2fs/ext2fs.h"
54+
55+/* Copy xattrs from source file to destination inode */
56+errcode_t set_inode_xattrs(ext2_filsys fs, ext2_ino_t ino, const char *name);
57+void xattr_cleanup ();
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch
deleted file mode 100644
index f2e4582..0000000
--- a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch
+++ /dev/null
@@ -1,175 +0,0 @@
1Add two new functions to manage a cache of xattr blocks as well as a new struct
2to build a linked list of xattr blocks.
3
4xattr_add_block: Adds a block to the cache. This function is supplied with a
5pointer to the head of a linked list of xattr blocks and an xattr block to add.
6The purpose of this cache is to allow sharing of what would otherwise be
7duplicate xattr blocks and so duplicates are not allowed in this cache. If an
8identical block is already in the cache a pointer to this block will be
9returned.
10
11xattr_rm_block: Removes a block from the cache. This function is supplied with
12a pointer to the cache and a node that shall be removed from the cache. The
13cache is searched for the node and the node is removed if found.
14
15Both functions are integrated into the 'set_inode_xattr'. Here the logic is
16rearranged to cope with associating preexisting xattr blocks with inodes as
17well as creating new blocks when necessary.
18
19Signed-off-by: Philip Tricca <flihp@twobit.us>
20
21Index: e2fsprogs-1.42.9/misc/xattr.c
22===================================================================
23--- e2fsprogs-1.42.9.orig/misc/xattr.c
24+++ e2fsprogs-1.42.9/misc/xattr.c
25@@ -25,6 +25,19 @@
26 #define XATTR_STDERR(fmt, args...) do {} while (0)
27 #endif
28
29+/* nodes for simple linked list to track xattr blocks, calling it a cache
30+ * would be a stretch ...
31+ */
32+typedef struct xattr_node xattr_node_t;
33+
34+struct xattr_node {
35+ struct ext2_ext_attr_header *header;
36+ blk_t block;
37+ struct xattr_node *next;
38+};
39+
40+xattr_node_t *xattr_list_head = NULL;
41+
42 /* structure for mapping xattr name prefix data */
43 typedef struct xattr_prefix {
44 int index;
45@@ -48,6 +61,17 @@ xattr_prefix_t xattr_prefixes [] = {
46 { 0 },
47 };
48
49+/* free xattr node and the buffer holding the xattr block */
50+static void
51+xattr_free_node (xattr_node_t *node)
52+{
53+ if (node) {
54+ if (node->header)
55+ free (node->header);
56+ free (node);
57+ }
58+}
59+
60 /* Free remaining resources after all files have been processed. */
61 void
62 xattr_cleanup ()
63@@ -260,6 +284,28 @@ out:
64 return ret;
65 }
66
67+/* Add an xattr node to the list specified by head. This function will update
68+ * head as necessary. It will return a pointer to the xattr_node_t added to the
69+ * list. In the event that an identical xattr block is already on the list this
70+ * function will return a pointer to the pre-existing node.
71+ */
72+static xattr_node_t*
73+xattr_add_block (xattr_node_t **head, xattr_node_t *node)
74+{
75+ XATTR_STDERR ("Adding xattr to the the node list.\n");
76+ return node;
77+}
78+
79+/* Remove xattr node from list. Returns pointer to the node being removed.
80+ * NOTE: We're not comparing the xattr blocks, just the nodes.
81+ */
82+static xattr_node_t*
83+xattr_rm_block (xattr_node_t **head, xattr_node_t *node)
84+{
85+ XATTR_STDERR ("Removing xattr from the node list.\n");
86+ return node;
87+}
88+
89 /* This is the entry point to the xattr module. This function copies the xattrs
90 * from the file at 'path' to the file system object at 'ino'.
91 *
92@@ -274,16 +320,21 @@ set_inode_xattr (ext2_filsys fs, ext2_in
93 errcode_t ret = 0;
94 char *buf = NULL;
95 struct ext2_inode inode = { 0 };
96- blk_t block = 0;
97- struct ext2_ext_attr_header *header = NULL;
98+ xattr_node_t *node = NULL, *node_tmp = NULL;
99 uint32_t newcount = 0;
100
101 XATTR_STDERR ("Copying xattrs from %s to inode 0x%x.\n", path, ino);
102+ /* Create an xattr_node_t for it and add it to the cache if appropriate */
103+ if (!(node = calloc (1, sizeof (xattr_node_t)))) {
104+ com_err (__func__, errno, "calloc");
105+ ret = errno;
106+ goto out;
107+ }
108 /* Populate the xattr block for the file at path */
109- if (ret = xattr_build_block (path, &header, fs->blocksize)) {
110+ if (ret = xattr_build_block (path, &(node->header), fs->blocksize)) {
111 goto out;
112 }
113- if (header == NULL) {
114+ if (node->header == NULL) {
115 XATTR_STDERR ("set_inode_xattrs: no xattrs for %s\n", path);
116 goto out;
117 }
118@@ -291,23 +342,38 @@ set_inode_xattr (ext2_filsys fs, ext2_in
119 com_err(__func__, ret, "ext2fs_read_inode");
120 goto out;
121 }
122- if (ret = ext2fs_alloc_block (fs, 0, NULL, &block)) {
123- com_err(__func__, ret, "ext2fs_alloc_block: returned %d", ret);
124+ if (!(node_tmp = xattr_add_block (&xattr_list_head, node))) {
125+ fprintf (stderr, "Cannot add NULL node to xattr_block list.\n");
126 goto out;
127 }
128- ext2fs_mark_block_bitmap2 (fs->block_map, block);
129- XATTR_STDERR ("writing xattr block 0x%x to disk:\n", block);
130- if (ret = ext2fs_write_ext_attr (fs, block, header)) {
131- com_err(__func__, ret, "ext2fs_write_ext_attr: returned %d", ret);
132- goto out;
133+ if (node == node_tmp) {
134+ /* xattr block is new: add to list & write to disk */
135+ XATTR_STDERR ("no pre-existing xattr block, creating / adding\n");
136+ if (ret = ext2fs_alloc_block (fs, 0, NULL, &node->block)) {
137+ com_err(__func__, ret, "ext2fs_alloc_block: returned %d", ret);
138+ xattr_rm_block (&xattr_list_head, node);
139+ goto out;
140+ }
141+ ext2fs_mark_block_bitmap2 (fs->block_map, node->block);
142+ XATTR_STDERR ("writing xattr block 0x%x to disk:\n", node->block);
143+ if (ret = ext2fs_write_ext_attr (fs, node->block, node->header)) {
144+ com_err(__func__, ret, "ext2fs_write_ext_attr: returned %d", ret);
145+ xattr_rm_block (&xattr_list_head, node);
146+ goto out;
147+ }
148+ } else {
149+ /* already have an identical xattr block, free the one we just made */
150+ XATTR_STDERR ("using xattr from existing block: 0x%x\n", node_tmp->block);
151+ xattr_free_node (node);
152+ node = node_tmp;
153 }
154 /* point inode for current file to xattr block, update block count and
155 * write inode to disk
156 */
157- inode.i_file_acl = block;
158+ inode.i_file_acl = node->block;
159 if (ret = ext2fs_adjust_ea_refcount2(fs,
160- block,
161- (char*)header,
162+ node->block,
163+ (char*)(node->header),
164 1,
165 &newcount))
166 {
167@@ -321,7 +387,6 @@ set_inode_xattr (ext2_filsys fs, ext2_in
168 if (ret = ext2fs_write_inode (fs, ino, &inode))
169 com_err(__func__, ret, "ext2fs_write_inode: returned %d", ret);
170 out:
171- if (header)
172- free (header);
173+ xattr_free_node (node);
174 return ret;
175 }
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block.patch
deleted file mode 100644
index 5955b44..0000000
--- a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block.patch
+++ /dev/null
@@ -1,341 +0,0 @@
1To build the xattr disk block we process the output from listxattr and
2lgetxattr from the source file system object. This data is formated in a disk
3block according to the format specified in the kernel ext2 file system driver.
4See the comment block at the beginning of fs/ext2/xattr.c for details.
5
6Currently we only process attributes with the 'security.' prefix as our use
7case is SELinux labels and IMA. Additional prefixes can likely be supported with
8minimal effort but none have been tested.
9
10Once the xattr block has been created it is written to disk. The xattr block is
11associated with the appropriate file system object through the i_file_acl inode
12member and the inode is updated on disk.
13
14Signed-off-by: Philip Tricca <flihp@twobit.us>
15
16Index: e2fsprogs-1.42.9/misc/xattr.c
17===================================================================
18--- e2fsprogs-1.42.9.orig/misc/xattr.c
19+++ e2fsprogs-1.42.9/misc/xattr.c
20@@ -1,6 +1,23 @@
21 #include "xattr.h"
22
23+#include <attr/xattr.h>
24+#include <ctype.h>
25+#include <errno.h>
26+#include <ext2fs/ext2_ext_attr.h>
27+#include <linux/xattr.h>
28+#include <stdint.h>
29 #include <stdio.h>
30+#include <stdlib.h>
31+#include <string.h>
32+#include <sys/stat.h>
33+#include <sys/types.h>
34+#include <unistd.h>
35+
36+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
37+#define HEADER(ptr) ((struct ext2_ext_attr_header *)(ptr))
38+#define ENTRY(ptr) ((struct ext2_ext_attr_entry *)(ptr))
39+#define FIRST_ENTRY(ptr) ENTRY(HEADER(ptr) + 1)
40+#define VALUE(hdr, ent) (((char*)hdr) + (ent->e_value_offs))
41
42 #ifdef XATTR_DEBUG
43 #define XATTR_STDERR(fmt, args...) fprintf (stderr, fmt, ##args)
44@@ -8,6 +25,28 @@
45 #define XATTR_STDERR(fmt, args...) do {} while (0)
46 #endif
47
48+/* structure for mapping xattr name prefix data */
49+typedef struct xattr_prefix {
50+ int index;
51+ char *name;
52+ size_t length;
53+} xattr_prefix_t;
54+
55+xattr_prefix_t xattr_prefixes [] = {
56+/* Only interested in security prefix. Can support others though.
57+ {
58+ .index = EXT2_XATTR_INDEX_USER,
59+ .name = XATTR_USER_PREFIX,
60+ .length = XATTR_USER_PREFIX_LEN,
61+ },
62+*/
63+ {
64+ .index = EXT2_XATTR_INDEX_SECURITY,
65+ .name = XATTR_SECURITY_PREFIX,
66+ .length = XATTR_SECURITY_PREFIX_LEN,
67+ },
68+ { 0 },
69+};
70
71 /* Free remaining resources after all files have been processed. */
72 void
73@@ -16,6 +55,211 @@ xattr_cleanup ()
74 XATTR_STDERR ("Cleaning up resources from xattrs.\n");
75 }
76
77+/* Get value for named xattr from file at path.
78+ * Returns pointer to allocated block for value and length in length param.
79+ * If no value, return NULL pointer and length of 0.
80+ * On error return NULL pointer and length set to -1.
81+ */
82+static char*
83+xattr_get_value (const char *path, const char *name, ssize_t *length)
84+{
85+ char *value = NULL;
86+
87+ *length = lgetxattr (path, name, NULL, 0);
88+ if (*length == -1) {
89+ com_err (__func__, errno, "lgetattr");
90+ goto out;
91+ }
92+ if (*length == 0) {
93+ fprintf (stderr, "xattr %s has value length 0\n", name);
94+ goto out;
95+ }
96+ value = calloc (1, *length);
97+ if (value == NULL) {
98+ com_err (__func__, errno, "calloc");
99+ goto out;
100+ }
101+ *length = lgetxattr (path, name, value, *length);
102+ if (*length == -1) {
103+ com_err (__func__, errno, "lgetattr");
104+ goto value_err;
105+ }
106+out:
107+ return value;
108+
109+value_err:
110+ if (value)
111+ free (value);
112+ return NULL;
113+}
114+
115+/* Get all attribute names for file at path. Return pointer to allocated memory
116+ * block holding all names and the length through parameter size.
117+ * If no xattrs: return NULL and set size to 0
118+ * If error: return NULL and set size to -1
119+ */
120+static char*
121+xattr_get_names (const char *path, ssize_t *size)
122+{
123+ char *names = NULL;
124+
125+ *size = llistxattr (path, NULL, 0);
126+ if (*size == -1) {
127+ com_err (__func__, errno, "llistxattr");
128+ goto out;
129+ }
130+ if (*size == 0) {
131+ /* no xattrs */
132+ goto out;
133+ }
134+ names = calloc (1, *size);
135+ if (names == NULL) {
136+ com_err (__func__, errno, "calloc");
137+ goto out;
138+ }
139+ *size = llistxattr (path, names, *size);
140+ if (*size == -1) {
141+ com_err (__func__, errno, "llistxattr");
142+ goto cleanup;
143+ }
144+ if (*size == 0) {
145+ fprintf (stdout, "Conflicting data, no xattrs for file: %s\n", path);
146+ goto cleanup;
147+ }
148+out:
149+ return names;
150+
151+cleanup:
152+ if (names)
153+ free (names);
154+ return NULL;
155+}
156+
157+/* return pointer to next string in xattr name block, don't go beyond length
158+ */
159+static inline char*
160+next_name (char *name, size_t length)
161+{
162+ int i = 0;
163+
164+ for (i = 0; i < length; ++i)
165+ if (name [i] == '\0') {
166+ ++i;
167+ break;
168+ }
169+
170+ return name + i;
171+}
172+
173+/* Find entry in xattr_table with matching prefix. */
174+static const xattr_prefix_t*
175+xattr_find_prefix (char *name, size_t length)
176+{
177+ int i = 0;
178+
179+ XATTR_STDERR ("find_attr_data: searching for prefix from xattr name: %s\n", name);
180+ for (i = 0; xattr_prefixes[i].index != 0; ++i) {
181+ if (!strncmp (name, xattr_prefixes[i].name, MIN (length, xattr_prefixes[i].length))) {
182+ XATTR_STDERR ("found match in table with index: %d\n", xattr_prefixes[i].index);
183+ return &xattr_prefixes[i];
184+ }
185+ }
186+ return NULL;
187+}
188+
189+/* Query file at path for attributes. build up structure the file system
190+ * expects of an extended attribute disk block (header parameter).
191+ *
192+ * The main loop walks through the xattr names one at a time. It gets the value
193+ * for each named xattr and copies the data into the xattr block pointed to by
194+ * the header parameter. To do this the loop also tracks the location of the
195+ * associated entry and value. Values start at the end of the buffer and grow
196+ * back towards the header while the entries start immediately after the header
197+ * and grow towards the end of the block.
198+ *
199+ * See the comment block at the beginning of the xattr.c file in the ext2 file
200+ * system code in the kernel: fs/ext2/xattr.c
201+ * Assume the xattr block pointed to by header parameter is initialized to 0s.
202+ */
203+static int
204+xattr_build_block (const char *path,
205+ struct ext2_ext_attr_header **header,
206+ size_t header_length)
207+{
208+ struct ext2_ext_attr_entry *entry = NULL;
209+ char *names = NULL, *value = NULL, *name_curr = NULL;
210+ ssize_t names_length = 0, value_length = 0;
211+ size_t name_length = 0, value_index = 0, len_rem = 0;
212+ const xattr_prefix_t *prefix = NULL;
213+ int ret = 0;
214+
215+ XATTR_STDERR ("xattr_build_block for file: %s\n", path);
216+ *header = NULL;
217+ names = xattr_get_names (path, &names_length);
218+ if (names == NULL) {
219+ // no xattrs for file @ path or error
220+ ret = names_length;
221+ goto out;
222+ }
223+ *header = calloc (1, header_length);
224+ if (*header == NULL) {
225+ com_err (__func__, errno, "calloc");
226+ goto out;
227+ }
228+ (*header)->h_magic = EXT2_EXT_ATTR_MAGIC;
229+ (*header)->h_blocks = 1;
230+ /* Values start at end of buffer. NOTE: It must be moved before a value can
231+ * be stored.
232+ */
233+ value_index = header_length;
234+ for (name_curr = names, entry = FIRST_ENTRY(*header), len_rem = names_length;
235+ name_curr < names + names_length;
236+ len_rem = names_length - (name_curr - names),
237+ name_curr = next_name (name_curr, len_rem),
238+ entry = EXT2_EXT_ATTR_NEXT(entry))
239+ {
240+ XATTR_STDERR ("xattr_build_block: processing xattr with name %s\n", name_curr);
241+ name_length = strnlen (name_curr, len_rem);
242+ prefix = xattr_find_prefix (name_curr, name_length);
243+ if (!prefix) {
244+ fprintf (stderr, "Don't currently handle xattr: %s\n", name_curr);
245+ continue;
246+ }
247+ value = xattr_get_value (path, name_curr, &value_length);
248+ if (value == NULL) {
249+ // no xattr value or error
250+ fprintf (stderr, "failed to get value, skipping\n");
251+ goto next;
252+ }
253+ /* setup offsets and lengths for name and value */
254+ entry->e_name_len = name_length - prefix->length;
255+ entry->e_name_index = prefix->index;
256+ /* Can't know these till we know the length of the value. */
257+ entry->e_value_offs = value_index -= EXT2_EXT_ATTR_SIZE(value_length);
258+ entry->e_value_size = value_length;
259+ /* Check to be sure entry name and value don't overlap before copy. */
260+ if (EXT2_EXT_ATTR_NAME(entry) + entry->e_name_len > VALUE(*header, entry)) {
261+ fprintf (stderr, "xattr entry name and value overlap! Too much xattr data.");
262+ ret = -1;
263+ goto out;
264+ }
265+ /* copy name and value data then calculate the hash */
266+ memcpy (EXT2_EXT_ATTR_NAME(entry),
267+ name_curr + prefix->length,
268+ entry->e_name_len);
269+ memcpy (VALUE(*header, entry), value, entry->e_value_size);
270+ entry->e_hash = ext2fs_ext_attr_hash_entry (entry, VALUE(*header, entry));
271+next:
272+ if (value)
273+ free (value);
274+ }
275+ XATTR_STDERR ("xattr_build_block: done building xattr buffer\n");
276+out:
277+ if (names)
278+ free (names);
279+ return ret;
280+}
281+
282 /* This is the entry point to the xattr module. This function copies the xattrs
283 * from the file at 'path' to the file system object at 'ino'.
284 *
285@@ -28,7 +272,56 @@ errcode_t
286 set_inode_xattr (ext2_filsys fs, ext2_ino_t ino, const char *path)
287 {
288 errcode_t ret = 0;
289+ char *buf = NULL;
290+ struct ext2_inode inode = { 0 };
291+ blk_t block = 0;
292+ struct ext2_ext_attr_header *header = NULL;
293+ uint32_t newcount = 0;
294
295 XATTR_STDERR ("Copying xattrs from %s to inode 0x%x.\n", path, ino);
296+ /* Populate the xattr block for the file at path */
297+ if (ret = xattr_build_block (path, &header, fs->blocksize)) {
298+ goto out;
299+ }
300+ if (header == NULL) {
301+ XATTR_STDERR ("set_inode_xattrs: no xattrs for %s\n", path);
302+ goto out;
303+ }
304+ if (ret = ext2fs_read_inode (fs, ino, &inode)) {
305+ com_err(__func__, ret, "ext2fs_read_inode");
306+ goto out;
307+ }
308+ if (ret = ext2fs_alloc_block (fs, 0, NULL, &block)) {
309+ com_err(__func__, ret, "ext2fs_alloc_block: returned %d", ret);
310+ goto out;
311+ }
312+ ext2fs_mark_block_bitmap2 (fs->block_map, block);
313+ XATTR_STDERR ("writing xattr block 0x%x to disk:\n", block);
314+ if (ret = ext2fs_write_ext_attr (fs, block, header)) {
315+ com_err(__func__, ret, "ext2fs_write_ext_attr: returned %d", ret);
316+ goto out;
317+ }
318+ /* point inode for current file to xattr block, update block count and
319+ * write inode to disk
320+ */
321+ inode.i_file_acl = block;
322+ if (ret = ext2fs_adjust_ea_refcount2(fs,
323+ block,
324+ (char*)header,
325+ 1,
326+ &newcount))
327+ {
328+ com_err(__func__, ret, "ext2fs_adjust_ea_refcount");
329+ goto out;
330+ }
331+ if (ret = ext2fs_iblk_add_blocks (fs, &inode, 1)) {
332+ com_err(__func__, ret, "ext2fs_iblk_add_blocks failed");
333+ goto out;
334+ }
335+ if (ret = ext2fs_write_inode (fs, ino, &inode))
336+ com_err(__func__, ret, "ext2fs_write_inode: returned %d", ret);
337+out:
338+ if (header)
339+ free (header);
340 return ret;
341 }
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch
deleted file mode 100644
index 38e6454..0000000
--- a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch
+++ /dev/null
@@ -1,181 +0,0 @@
1Implement the xattr block cache as an unsorted linked list. This requires the
2add and rm functions be able to test for equality between xattr blocks. This
3is implemented as two functions. The first compares individual entries and the
4second compares the whole xattr block by iterating over the individual entries.
5
6The xattr block cache keeps memory allocated on the heap around across
7invocations of the set_inode_xattr function. To free this memory we implement
8an xattr_cleanup function that iterates over the cache freeing resources
9associated with each node.
10
11Signed-off-by: Philip Tricca <flihp@twobit.us>
12
13Index: e2fsprogs-1.42.9/misc/xattr.c
14===================================================================
15--- e2fsprogs-1.42.9.orig/misc/xattr.c
16+++ e2fsprogs-1.42.9/misc/xattr.c
17@@ -5,6 +5,7 @@
18 #include <errno.h>
19 #include <ext2fs/ext2_ext_attr.h>
20 #include <linux/xattr.h>
21+#include <stdbool.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25@@ -25,6 +26,9 @@
26 #define XATTR_STDERR(fmt, args...) do {} while (0)
27 #endif
28
29+static size_t cache_hit = 0;
30+static size_t cache_miss = 0;
31+
32 /* nodes for simple linked list to track xattr blocks, calling it a cache
33 * would be a stretch ...
34 */
35@@ -76,7 +80,18 @@ xattr_free_node (xattr_node_t *node)
36 void
37 xattr_cleanup ()
38 {
39+ xattr_node_t *curr = NULL, *tmp = NULL;
40+ size_t count = 0;
41+
42 XATTR_STDERR ("Cleaning up resources from xattrs.\n");
43+ for (curr = xattr_list_head; curr != NULL; ++count) {
44+ tmp = curr;
45+ curr = curr->next;
46+ xattr_free_node (tmp);
47+ }
48+ XATTR_STDERR ("Freed %d xattr_node_ts.\n", count);
49+ XATTR_STDERR ("Cache hits: %u\n", cache_hit);
50+ XATTR_STDERR ("Cache miss: %u\n", cache_miss);
51 }
52
53 /* Get value for named xattr from file at path.
54@@ -284,6 +299,58 @@ out:
55 return ret;
56 }
57
58+static bool
59+xattr_entry_isequal (struct ext2_ext_attr_header *header_a,
60+ struct ext2_ext_attr_entry *entry_a,
61+ struct ext2_ext_attr_header *header_b,
62+ struct ext2_ext_attr_entry *entry_b)
63+{
64+ if (entry_a->e_hash == entry_b->e_hash ||
65+ entry_a->e_name_index == entry_b->e_name_index ||
66+ entry_a->e_name_len == entry_b->e_name_len ||
67+ entry_a->e_value_size == entry_b->e_value_size)
68+ {
69+ /* If entry header data all matches we check name and value */
70+ if (memcmp (EXT2_EXT_ATTR_NAME(entry_a),
71+ EXT2_EXT_ATTR_NAME(entry_b),
72+ MIN (entry_a->e_name_len, entry_b->e_name_len)) != 0)
73+ return false;
74+ if (memcmp (VALUE(header_a, entry_a),
75+ VALUE(header_b, entry_b),
76+ MIN(entry_a->e_value_size, entry_b->e_value_size)) != 0)
77+ return false;
78+ return true;
79+ } else {
80+ return false;
81+ }
82+}
83+
84+static bool
85+xattr_block_isequal (struct ext2_ext_attr_header *header_a,
86+ struct ext2_ext_attr_header *header_b)
87+{
88+ struct ext2_ext_attr_entry *entry_a = NULL, *entry_b = NULL;
89+
90+ XATTR_STDERR ("equality test: xattr blocks at 0x%x and 0x%x\n", header_a, header_b);
91+ for (entry_a = FIRST_ENTRY(header_a), entry_b = FIRST_ENTRY(header_b);
92+ !EXT2_EXT_IS_LAST_ENTRY(entry_a) && !EXT2_EXT_IS_LAST_ENTRY(entry_b);
93+ entry_a = EXT2_EXT_ATTR_NEXT(entry_a), entry_b = EXT2_EXT_ATTR_NEXT(entry_b))
94+ {
95+ if (!xattr_entry_isequal (header_a, entry_a, header_b, entry_b)) {
96+ /* bail as soon as we find entries that don't match */
97+ XATTR_STDERR ("entries do not match\n");
98+ return false;
99+ }
100+ }
101+ /* Be sure we're on the last element from each block. */
102+ if (EXT2_EXT_IS_LAST_ENTRY(entry_a) && EXT2_EXT_IS_LAST_ENTRY(entry_b)) {
103+ XATTR_STDERR ("entries match\n");
104+ return true;
105+ } else {
106+ return false;
107+ }
108+}
109+
110 /* Add an xattr node to the list specified by head. This function will update
111 * head as necessary. It will return a pointer to the xattr_node_t added to the
112 * list. In the event that an identical xattr block is already on the list this
113@@ -292,7 +359,31 @@ out:
114 static xattr_node_t*
115 xattr_add_block (xattr_node_t **head, xattr_node_t *node)
116 {
117+ xattr_node_t *curr_node = NULL, *prev_node = NULL;
118+
119 XATTR_STDERR ("Adding xattr to the the node list.\n");
120+ if (node == NULL)
121+ return NULL;
122+ /* list is empty, node becomes first node */
123+ if (!(*head)) {
124+ *head = node;
125+ return node;
126+ }
127+ for (curr_node = *head; curr_node != NULL; curr_node = curr_node->next)
128+ {
129+ /* cache hit */
130+ if (xattr_block_isequal (node->header, curr_node->header)) {
131+ ++cache_hit;
132+ return curr_node;
133+ }
134+ /* end of list */
135+ if (curr_node->next == NULL) {
136+ ++cache_miss;
137+ curr_node->next = node;
138+ return node;
139+ }
140+ }
141+ /* should never reach: assert? */
142 return node;
143 }
144
145@@ -302,8 +393,27 @@ xattr_add_block (xattr_node_t **head, xa
146 static xattr_node_t*
147 xattr_rm_block (xattr_node_t **head, xattr_node_t *node)
148 {
149+ xattr_node_t *curr_node = NULL, *prev_node = NULL;
150+
151 XATTR_STDERR ("Removing xattr from the node list.\n");
152- return node;
153+ /* no list, or empty list: nothing to search though */
154+ if (!head || !(*head))
155+ return NULL;
156+
157+ for (prev_node = NULL, curr_node = *head;
158+ curr_node != NULL;
159+ prev_node = curr_node, curr_node = curr_node->next)
160+ {
161+ if (node == curr_node) {
162+ if (prev_node)
163+ prev_node->next = curr_node->next;
164+ else
165+ *head = curr_node->next;
166+ return curr_node;
167+ }
168+ }
169+ /* reached end of list, no match */
170+ return NULL;
171 }
172
173 /* This is the entry point to the xattr module. This function copies the xattrs
174@@ -386,6 +496,7 @@ set_inode_xattr (ext2_filsys fs, ext2_in
175 }
176 if (ret = ext2fs_write_inode (fs, ino, &inode))
177 com_err(__func__, ret, "ext2fs_write_inode: returned %d", ret);
178+ return ret;
179 out:
180 xattr_free_node (node);
181 return ret;
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/mke2fs.c-create_inode.c-copy-xattrs.patch b/recipes-devtools/e2fsprogs/e2fsprogs/mke2fs.c-create_inode.c-copy-xattrs.patch
deleted file mode 100644
index 8b0109f..0000000
--- a/recipes-devtools/e2fsprogs/e2fsprogs/mke2fs.c-create_inode.c-copy-xattrs.patch
+++ /dev/null
@@ -1,164 +0,0 @@
1Insert calls into xattr module to copy xattrs for each file system object
2copied by mke2fs when '-d' is specified. This requires a call to
3set_inode_xattr in two places:
4misc/create_inode.c: to copy xattrs as part of the recursive traversal
5of the source directory
6misc/mke2fs.c: to copy the xattr block associated with the root of the
7file system
8
9Insert a call to xattr_cleanup to free any resources that need special
10handling in the xattr module.
11
12We also add the necessary rules to Makefile.in to build the xattr module
13and link it into executables as required.
14
15Signed-off-by: Philip Tricca <flihp@twobit.us>
16
17Index: e2fsprogs-1.42.9/misc/mke2fs.c
18===================================================================
19--- e2fsprogs-1.42.9.orig/misc/mke2fs.c
20+++ e2fsprogs-1.42.9/misc/mke2fs.c
21@@ -56,6 +56,7 @@ extern int optind;
22 #include "../version.h"
23 #include "quota/mkquota.h"
24 #include "create_inode.h"
25+#include "xattr.h"
26
27 #define STRIDE_LENGTH 8
28
29@@ -2744,6 +2745,11 @@ no_journal:
30 hdlinks.count = 0;
31 current_fs = fs;
32 root = EXT2_ROOT_INO;
33+ retval = set_inode_xattr (fs, EXT2_ROOT_INO, root_dir);
34+ if (retval) {
35+ fprintf(stderr, "%s", _("Error setting xattr for inode: 0x%x\n"), EXT2_ROOT_INO);
36+ return retval;
37+ }
38 retval = populate_fs(root, root_dir);
39 if (retval) {
40 fprintf(stderr, "%s",
41@@ -2751,6 +2757,7 @@ no_journal:
42 return retval;
43 } else if (!quiet)
44 printf("%s", _("done\n"));
45+ xattr_cleanup();
46 }
47
48 if (!quiet)
49Index: e2fsprogs-1.42.9/misc/create_inode.c
50===================================================================
51--- e2fsprogs-1.42.9.orig/misc/create_inode.c
52+++ e2fsprogs-1.42.9/misc/create_inode.c
53@@ -1,5 +1,6 @@
54 #include "create_inode.h"
55 #include <limits.h>
56+#include "xattr.h"
57
58 #if __STDC_VERSION__ < 199901L
59 # if __GNUC__ >= 2
60@@ -549,6 +550,12 @@ errcode_t populate_fs(ext2_ino_t parent_
61 return retval;
62 }
63
64+ if ((retval = set_inode_xattr (current_fs, ino, name))) {
65+ com_err(__func__, retval,
66+ _("while setting xattrs for \"%s\""), name);
67+ return retval;
68+ }
69+
70 /* Save the hardlink ino */
71 if (save_inode) {
72 /*
73Index: e2fsprogs-1.42.9/debugfs/Makefile.in
74===================================================================
75--- e2fsprogs-1.42.9.orig/debugfs/Makefile.in
76+++ e2fsprogs-1.42.9/debugfs/Makefile.in
77@@ -18,7 +18,7 @@ MK_CMDS= _SS_DIR_OVERRIDE=../lib/ss ../l
78
79 DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \
80 lsdel.o dump.o set_fields.o logdump.o htree.o unused.o e2freefrag.o \
81- filefrag.o extent_cmds.o extent_inode.o zap.o create_inode.o
82+ filefrag.o extent_cmds.o extent_inode.o zap.o create_inode.o xattr.o
83
84 RO_DEBUG_OBJS= ro_debug_cmds.o ro_debugfs.o util.o ncheck.o icheck.o ls.o \
85 lsdel.o logdump.o htree.o e2freefrag.o filefrag.o extent_cmds.o \
86@@ -29,12 +29,16 @@ SRCS= debug_cmds.c $(srcdir)/debugfs.c $
87 $(srcdir)/dump.c $(srcdir)/set_fields.c ${srcdir}/logdump.c \
88 $(srcdir)/htree.c $(srcdir)/unused.c ${srcdir}/../misc/e2freefrag.c \
89 $(srcdir)/filefrag.c $(srcdir)/extent_inode.c $(srcdir)/zap.c \
90- $(srcdir)/../misc/create_inode.c
91+ $(srcdir)/../misc/create_inode.c $(srcdir)/../misc/xattr.c
92
93 CREATE_INODE_DEPS= $(srcdir)/../misc/create_inode.h \
94 $(srcdir)/../misc/create_inode.c $(top_builddir)/lib/config.h \
95 $(srcdir)/../lib/ext2fs/ext2fs.h $(srcdir)/../lib/et/com_err.h \
96- $(srcdir)/../lib/e2p/e2p.h $(srcdir)/../misc/nls-enable.h
97+ $(srcdir)/../lib/e2p/e2p.h $(srcdir)/../misc/nls-enable.h \
98+ $(srcdir)/../misc/xattr.h
99+
100+XATTR_DEPS= $(srcdir)/../misc/xattr.h $(srcdir)/../misc/xattr.h \
101+ $(srcdir)/../lib/et/com_err.h $(srcdir)/../lib/ext2fs/ext2fs.h
102
103 LIBS= $(LIBEXT2FS) $(LIBE2P) $(LIBSS) $(LIBCOM_ERR) $(LIBBLKID) \
104 $(LIBUUID)
105@@ -92,6 +96,11 @@ create_inode.o: $(CREATE_INODE_DEPS)
106 $(Q) $(CC) -c $(ALL_CFLAGS) -I$(srcdir) \
107 $(srcdir)/../misc/create_inode.c -DDEBUGFS -o $@
108
109+xattr.o: $(XATTR_DEPS)
110+ $(E) " CC $@"
111+ $(Q) $(CC) -c $(ALL_CFLAGS) -I$(srcdir) \
112+ $(srcdir)/../misc/xattr.c -o $@
113+
114 debugfs.8: $(DEP_SUBSTITUTE) $(srcdir)/debugfs.8.in
115 $(E) " SUBST $@"
116 $(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/debugfs.8.in debugfs.8
117Index: e2fsprogs-1.42.9/misc/Makefile.in
118===================================================================
119--- e2fsprogs-1.42.9.orig/misc/Makefile.in
120+++ e2fsprogs-1.42.9/misc/Makefile.in
121@@ -43,7 +43,7 @@ LPROGS= @E2INITRD_PROG@
122 TUNE2FS_OBJS= tune2fs.o util.o
123 MKLPF_OBJS= mklost+found.o
124 MKE2FS_OBJS= mke2fs.o util.o profile.o prof_err.o default_profile.o \
125- create_inode.o
126+ create_inode.o xattr.o
127 CHATTR_OBJS= chattr.o
128 LSATTR_OBJS= lsattr.o
129 UUIDGEN_OBJS= uuidgen.o
130@@ -62,7 +62,7 @@ PROFILED_TUNE2FS_OBJS= profiled/tune2fs.
131 PROFILED_MKLPF_OBJS= profiled/mklost+found.o
132 PROFILED_MKE2FS_OBJS= profiled/mke2fs.o profiled/util.o profiled/profile.o \
133 profiled/prof_err.o profiled/default_profile.o \
134- profiled/create_inode.o
135+ profiled/create_inode.o profiled/xattr.o
136 PROFILED_CHATTR_OBJS= profiled/chattr.o
137 PROFILED_LSATTR_OBJS= profiled/lsattr.o
138 PROFILED_UUIDGEN_OBJS= profiled/uuidgen.o
139@@ -84,7 +84,8 @@ SRCS= $(srcdir)/tune2fs.c $(srcdir)/mklo
140 $(srcdir)/uuidgen.c $(srcdir)/blkid.c $(srcdir)/logsave.c \
141 $(srcdir)/filefrag.c $(srcdir)/base_device.c \
142 $(srcdir)/ismounted.c $(srcdir)/../e2fsck/profile.c \
143- $(srcdir)/e2undo.c $(srcdir)/e2freefrag.c $(srcdir)/create_inode.c
144+ $(srcdir)/e2undo.c $(srcdir)/e2freefrag.c $(srcdir)/create_inode.c \
145+ $(srcdir)/xattr.c
146
147 LIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
148 DEPLIBS= $(LIBEXT2FS) $(DEPLIBCOM_ERR)
149@@ -634,7 +635,8 @@ mke2fs.o: $(srcdir)/mke2fs.c $(top_build
150 $(srcdir)/util.h profile.h prof_err.h $(top_srcdir)/version.h \
151 $(srcdir)/nls-enable.h $(top_srcdir)/lib/quota/mkquota.h $(srcdir)/create_inode.h\
152 $(top_srcdir)/lib/quota/quotaio.h $(top_srcdir)/lib/quota/dqblk_v2.h \
153- $(top_srcdir)/lib/quota/quotaio_tree.h $(top_srcdir)/lib/../e2fsck/dict.h
154+ $(top_srcdir)/lib/quota/quotaio_tree.h $(top_srcdir)/lib/../e2fsck/dict.h \
155+ $(srcdir)/xattr.h
156 chattr.o: $(srcdir)/chattr.c $(top_builddir)/lib/config.h \
157 $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
158 $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/et/com_err.h \
159@@ -716,3 +718,5 @@ create_inode.o: $(srcdir)/create_inode.h
160 $(top_builddir)/lib/config.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
161 $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/e2p/e2p.h \
162 $(srcdir)/nls-enable.h
163+xattr.o: $(srcdir)/xattr.h $(srcdir)/xattr.c \
164+ $(top_builddir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2fs.h
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
deleted file mode 100644
index 2aa7902..0000000
--- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
+++ /dev/null
@@ -1,12 +0,0 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
2
3DEPENDS += "linux-libc-headers attr"
4
5SRC_URI += " \
6 file://misc-xattr-add-xattr-module-stub.patch \
7 file://mke2fs.c-create_inode.c-copy-xattrs.patch \
8 file://lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch \
9 file://misc-xattr-create-xattr-block.patch \
10 file://misc-xattr-create-xattr-block-node.patch \
11 file://misc-xattr-create-xattr-cache.patch \
12"