diff options
author | Philip Tricca <flihp@twobit.us> | 2015-06-17 15:30:58 -0700 |
---|---|---|
committer | Joe MacDonald <joe_macdonald@mentor.com> | 2015-08-08 16:43:23 -0400 |
commit | 1cd60863053fd8586684552cc323c14789dd54b5 (patch) | |
tree | 9e5b04a39568b4ec5ae5399b6d88c373ef96b3a2 | |
parent | 5cb8ef7d0403954ec947e743c36015738652809c (diff) | |
download | meta-selinux-1cd60863053fd8586684552cc323c14789dd54b5.tar.gz |
e2fsprogs: Implement xattr block cache with simple linked list.
Signed-off-by: Philip Tricca <flihp@twobit.us>
Signed-off-by: Joe MacDonald <joe_macdonald@mentor.com>
-rw-r--r-- | recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch | 181 | ||||
-rw-r--r-- | recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend | 1 |
2 files changed, 182 insertions, 0 deletions
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch new file mode 100644 index 0000000..38e6454 --- /dev/null +++ b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch | |||
@@ -0,0 +1,181 @@ | |||
1 | Implement the xattr block cache as an unsorted linked list. This requires the | ||
2 | add and rm functions be able to test for equality between xattr blocks. This | ||
3 | is implemented as two functions. The first compares individual entries and the | ||
4 | second compares the whole xattr block by iterating over the individual entries. | ||
5 | |||
6 | The xattr block cache keeps memory allocated on the heap around across | ||
7 | invocations of the set_inode_xattr function. To free this memory we implement | ||
8 | an xattr_cleanup function that iterates over the cache freeing resources | ||
9 | associated with each node. | ||
10 | |||
11 | Signed-off-by: Philip Tricca <flihp@twobit.us> | ||
12 | |||
13 | Index: 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_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend index 0705ec4..d8de9da 100644 --- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend +++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend | |||
@@ -6,4 +6,5 @@ SRC_URI += " \ | |||
6 | file://lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch \ | 6 | file://lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch \ |
7 | file://misc-xattr-create-xattr-block.patch \ | 7 | file://misc-xattr-create-xattr-block.patch \ |
8 | file://misc-xattr-create-xattr-block-node.patch \ | 8 | file://misc-xattr-create-xattr-block-node.patch \ |
9 | file://misc-xattr-create-xattr-cache.patch \ | ||
9 | " | 10 | " |