diff options
Diffstat (limited to 'meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch')
-rw-r--r-- | meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch new file mode 100644 index 0000000000..014a69409f --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch | |||
@@ -0,0 +1,357 @@ | |||
1 | Upstream-Status: inappropriate | ||
2 | |||
3 | From 3d47e37e21f6a2ced489d49e8bf5a5c24bb9baaf Mon Sep 17 00:00:00 2001 | ||
4 | From: Corey Minyard <cminyard@mvista.com> | ||
5 | Date: Sun, 5 Jun 2011 09:36:11 -0500 | ||
6 | Subject: [PATCH 04/19] Add a dirwalker for walking through directory entries | ||
7 | |||
8 | The code to walk directory items was messy, to say the least. Write a | ||
9 | clean structure to do this. | ||
10 | |||
11 | Also, remove d_name[0]. This is bad style, and newer compilers will | ||
12 | think it is really a zero-length array and will abort if trying to write | ||
13 | any data to it, since the compiler thinks it has no contents. | ||
14 | --- | ||
15 | genext2fs.c | 210 +++++++++++++++++++++++++++++++++++++++++++---------------- | ||
16 | 1 files changed, 154 insertions(+), 56 deletions(-) | ||
17 | |||
18 | diff --git a/genext2fs.c b/genext2fs.c | ||
19 | index 0b5ba6f..03d1b27 100644 | ||
20 | --- a/genext2fs.c | ||
21 | +++ b/genext2fs.c | ||
22 | @@ -533,7 +533,6 @@ typedef struct | ||
23 | typedef struct | ||
24 | { | ||
25 | directory_decl | ||
26 | - char d_name[0]; | ||
27 | } directory; | ||
28 | |||
29 | typedef uint8 block[BLOCKSIZE]; | ||
30 | @@ -795,6 +794,8 @@ static inline uint8 * | ||
31 | get_workblk(void) | ||
32 | { | ||
33 | unsigned char* b=calloc(1,BLOCKSIZE); | ||
34 | + if (!b) | ||
35 | + error_msg_and_die("get_workblk() failed, out of memory"); | ||
36 | return b; | ||
37 | } | ||
38 | static inline void | ||
39 | @@ -902,6 +903,126 @@ put_nod(nod_info *ni) | ||
40 | free(ni); | ||
41 | } | ||
42 | |||
43 | +// Used to hold state information while walking a directory inode. | ||
44 | +typedef struct | ||
45 | +{ | ||
46 | + directory d; | ||
47 | + filesystem *fs; | ||
48 | + uint32 nod; | ||
49 | + directory *last_d; | ||
50 | + uint8 *b; | ||
51 | + blk_info *bi; | ||
52 | +} dirwalker; | ||
53 | + | ||
54 | +// Start a directory walk on the given inode. You must pass in a | ||
55 | +// dirwalker structure, then use that dirwalker for future operations. | ||
56 | +// Call put_dir when you are done walking the directory. | ||
57 | +static inline directory * | ||
58 | +get_dir(filesystem *fs, uint32 nod, dirwalker *dw) | ||
59 | +{ | ||
60 | + dw->fs = fs; | ||
61 | + dw->b = get_blk(fs, nod, &dw->bi); | ||
62 | + dw->nod = nod; | ||
63 | + dw->last_d = (directory *) dw->b; | ||
64 | + | ||
65 | + memcpy(&dw->d, dw->last_d, sizeof(directory)); | ||
66 | + return &dw->d; | ||
67 | +} | ||
68 | + | ||
69 | +// Move to the next directory. | ||
70 | +static inline directory * | ||
71 | +next_dir(dirwalker *dw) | ||
72 | +{ | ||
73 | + directory *next_d = (directory *)((int8*)dw->last_d + dw->d.d_rec_len); | ||
74 | + | ||
75 | + memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
76 | + | ||
77 | + if (((int8 *) next_d) >= ((int8 *) dw->b + BLOCKSIZE)) | ||
78 | + return NULL; | ||
79 | + | ||
80 | + dw->last_d = next_d; | ||
81 | + memcpy(&dw->d, next_d, sizeof(directory)); | ||
82 | + return &dw->d; | ||
83 | +} | ||
84 | + | ||
85 | +// Call then when you are done with the directory walk. | ||
86 | +static inline void | ||
87 | +put_dir(dirwalker *dw) | ||
88 | +{ | ||
89 | + memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
90 | + | ||
91 | + if (dw->nod == 0) | ||
92 | + free_workblk(dw->b); | ||
93 | + else | ||
94 | + put_blk(dw->bi); | ||
95 | +} | ||
96 | + | ||
97 | +// Create a new directory block with the given inode as it's destination | ||
98 | +// and append it to the current dirwalker. | ||
99 | +static directory * | ||
100 | +new_dir(filesystem *fs, uint32 dnod, const char *name, int nlen, dirwalker *dw) | ||
101 | +{ | ||
102 | + directory *d; | ||
103 | + | ||
104 | + dw->fs = fs; | ||
105 | + dw->b = get_workblk(); | ||
106 | + dw->nod = 0; | ||
107 | + dw->last_d = (directory *) dw->b; | ||
108 | + d = &dw->d; | ||
109 | + d->d_inode = dnod; | ||
110 | + d->d_rec_len = BLOCKSIZE; | ||
111 | + d->d_name_len = nlen; | ||
112 | + strncpy(((char *) dw->last_d) + sizeof(directory), name, nlen); | ||
113 | + return d; | ||
114 | +} | ||
115 | + | ||
116 | +// Shrink the current directory entry, make a new one with the free | ||
117 | +// space, and return the new directory entry (making it current). | ||
118 | +static inline directory * | ||
119 | +shrink_dir(dirwalker *dw, uint32 nod, const char *name, int nlen) | ||
120 | +{ | ||
121 | + int reclen, preclen; | ||
122 | + directory *d = &dw->d; | ||
123 | + | ||
124 | + reclen = d->d_rec_len; | ||
125 | + d->d_rec_len = sizeof(directory) + rndup(d->d_name_len, 4); | ||
126 | + preclen = d->d_rec_len; | ||
127 | + reclen -= preclen; | ||
128 | + memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
129 | + | ||
130 | + dw->last_d = (directory *) (((int8 *) dw->last_d) + preclen); | ||
131 | + d->d_rec_len = reclen; | ||
132 | + d->d_inode = nod; | ||
133 | + d->d_name_len = nlen; | ||
134 | + strncpy(((char *) dw->last_d) + sizeof(directory), name, nlen); | ||
135 | + | ||
136 | + return d; | ||
137 | +} | ||
138 | + | ||
139 | +// Return the current block the directory is walking | ||
140 | +static inline uint8 * | ||
141 | +dir_data(dirwalker *dw) | ||
142 | +{ | ||
143 | + return dw->b; | ||
144 | +} | ||
145 | + | ||
146 | +// Return the pointer to the name for the current directory | ||
147 | +static inline char * | ||
148 | +dir_name(dirwalker *dw) | ||
149 | +{ | ||
150 | + return ((char *) dw->last_d) + sizeof(directory); | ||
151 | +} | ||
152 | + | ||
153 | +// Set the name for the current directory. Note that this doesn't | ||
154 | +// verify that there is space for the directory name, you must do | ||
155 | +// that yourself. | ||
156 | +static void | ||
157 | +dir_set_name(dirwalker *dw, const char *name, int nlen) | ||
158 | +{ | ||
159 | + dw->d.d_name_len = nlen; | ||
160 | + strncpy(((char *) dw->last_d) + sizeof(directory), name, nlen); | ||
161 | +} | ||
162 | + | ||
163 | // allocate a given block/inode in the bitmap | ||
164 | // allocate first free if item == 0 | ||
165 | static uint32 | ||
166 | @@ -1354,11 +1475,10 @@ extend_blk(filesystem *fs, uint32 nod, block b, int amount) | ||
167 | static void | ||
168 | add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
169 | { | ||
170 | - blockwalker bw; | ||
171 | + blockwalker bw, lbw; | ||
172 | uint32 bk; | ||
173 | - uint8 *b; | ||
174 | - blk_info *bi; | ||
175 | directory *d; | ||
176 | + dirwalker dw; | ||
177 | int reclen, nlen; | ||
178 | inode *node; | ||
179 | inode *pnode; | ||
180 | @@ -1376,55 +1496,46 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
181 | if(reclen > BLOCKSIZE) | ||
182 | error_msg_and_die("bad name '%s' (too long)", name); | ||
183 | init_bw(&bw); | ||
184 | + lbw = bw; | ||
185 | while((bk = walk_bw(fs, dnod, &bw, 0, 0)) != WALK_END) // for all blocks in dir | ||
186 | { | ||
187 | - b = get_blk(fs, bk, &bi); | ||
188 | // for all dir entries in block | ||
189 | - for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
190 | + for(d = get_dir(fs, bk, &dw); d; d = next_dir(&dw)) | ||
191 | { | ||
192 | // if empty dir entry, large enough, use it | ||
193 | if((!d->d_inode) && (d->d_rec_len >= reclen)) | ||
194 | { | ||
195 | d->d_inode = nod; | ||
196 | node = get_nod(fs, nod, &ni); | ||
197 | + dir_set_name(&dw, name, nlen); | ||
198 | + put_dir(&dw); | ||
199 | node->i_links_count++; | ||
200 | - d->d_name_len = nlen; | ||
201 | - strncpy(d->d_name, name, nlen); | ||
202 | put_nod(ni); | ||
203 | goto out; | ||
204 | } | ||
205 | // if entry with enough room (last one?), shrink it & use it | ||
206 | if(d->d_rec_len >= (sizeof(directory) + rndup(d->d_name_len, 4) + reclen)) | ||
207 | { | ||
208 | - reclen = d->d_rec_len; | ||
209 | - d->d_rec_len = sizeof(directory) + rndup(d->d_name_len, 4); | ||
210 | - reclen -= d->d_rec_len; | ||
211 | - d = (directory*) (((int8*)d) + d->d_rec_len); | ||
212 | - d->d_rec_len = reclen; | ||
213 | - d->d_inode = nod; | ||
214 | node = get_nod(fs, nod, &ni); | ||
215 | + d = shrink_dir(&dw, nod, name, nlen); | ||
216 | + put_dir(&dw); | ||
217 | node->i_links_count++; | ||
218 | - d->d_name_len = nlen; | ||
219 | - strncpy(d->d_name, name, nlen); | ||
220 | put_nod(ni); | ||
221 | goto out; | ||
222 | } | ||
223 | } | ||
224 | + put_dir(&dw); | ||
225 | + lbw = bw; | ||
226 | } | ||
227 | // we found no free entry in the directory, so we add a block | ||
228 | - if(!(b = get_workblk())) | ||
229 | - error_msg_and_die("get_workblk() failed."); | ||
230 | - d = (directory*)b; | ||
231 | - d->d_inode = nod; | ||
232 | node = get_nod(fs, nod, &ni); | ||
233 | + d = new_dir(fs, nod, name, nlen, &dw); | ||
234 | node->i_links_count++; | ||
235 | put_nod(ni); | ||
236 | - d->d_rec_len = BLOCKSIZE; | ||
237 | - d->d_name_len = nlen; | ||
238 | - strncpy(d->d_name, name, nlen); | ||
239 | - extend_blk(fs, dnod, b, 1); | ||
240 | + next_dir(&dw); // Force the data into the buffer | ||
241 | + extend_blk(fs, dnod, dir_data(&dw), 1); | ||
242 | + put_dir(&dw); | ||
243 | pnode->i_size += BLOCKSIZE; | ||
244 | - free_workblk(b); | ||
245 | out: | ||
246 | put_nod(dni); | ||
247 | } | ||
248 | @@ -1435,20 +1546,18 @@ find_dir(filesystem *fs, uint32 nod, const char * name) | ||
249 | { | ||
250 | blockwalker bw; | ||
251 | uint32 bk; | ||
252 | - blk_info *bi; | ||
253 | int nlen = strlen(name); | ||
254 | init_bw(&bw); | ||
255 | while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END) | ||
256 | { | ||
257 | directory *d; | ||
258 | - uint8 *b; | ||
259 | - b = get_blk(fs, bk, &bi); | ||
260 | - for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
261 | - if(d->d_inode && (nlen == d->d_name_len) && !strncmp(d->d_name, name, nlen)) { | ||
262 | - put_blk(bi); | ||
263 | + dirwalker dw; | ||
264 | + for (d = get_dir(fs, bk, &dw); d; d=next_dir(&dw)) | ||
265 | + if(d->d_inode && (nlen == d->d_name_len) && !strncmp(dir_name(&dw), name, nlen)) { | ||
266 | + put_dir(&dw); | ||
267 | return d->d_inode; | ||
268 | } | ||
269 | - put_blk(bi); | ||
270 | + put_dir(&dw); | ||
271 | } | ||
272 | return 0; | ||
273 | } | ||
274 | @@ -2090,8 +2199,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
275 | { | ||
276 | uint32 i; | ||
277 | filesystem *fs; | ||
278 | - directory *d; | ||
279 | - uint8 * b; | ||
280 | + dirwalker dw; | ||
281 | uint32 nod, first_block; | ||
282 | uint32 nbgroups,nbinodes_per_group,overhead_per_group,free_blocks, | ||
283 | free_blocks_per_group,nbblocks_per_group,min_nbgroups; | ||
284 | @@ -2217,26 +2325,20 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
285 | itab0->i_links_count = 2; | ||
286 | put_nod(ni); | ||
287 | |||
288 | - if(!(b = get_workblk())) | ||
289 | - error_msg_and_die("get_workblk() failed."); | ||
290 | - d = (directory*)b; | ||
291 | - d->d_inode = EXT2_ROOT_INO; | ||
292 | - d->d_rec_len = sizeof(directory)+4; | ||
293 | - d->d_name_len = 1; | ||
294 | - strcpy(d->d_name, "."); | ||
295 | - d = (directory*)(b + d->d_rec_len); | ||
296 | - d->d_inode = EXT2_ROOT_INO; | ||
297 | - d->d_rec_len = BLOCKSIZE - (sizeof(directory)+4); | ||
298 | - d->d_name_len = 2; | ||
299 | - strcpy(d->d_name, ".."); | ||
300 | - extend_blk(fs, EXT2_ROOT_INO, b, 1); | ||
301 | + new_dir(fs, EXT2_ROOT_INO, ".", 1, &dw); | ||
302 | + shrink_dir(&dw, EXT2_ROOT_INO, "..", 2); | ||
303 | + next_dir(&dw); // Force the data into the buffer | ||
304 | + extend_blk(fs, EXT2_ROOT_INO, dir_data(&dw), 1); | ||
305 | + put_dir(&dw); | ||
306 | |||
307 | // make lost+found directory and reserve blocks | ||
308 | if(fs->sb.s_r_blocks_count) | ||
309 | { | ||
310 | inode *node; | ||
311 | + uint8 *b; | ||
312 | |||
313 | nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU, 0, 0, fs_timestamp, fs_timestamp); | ||
314 | + b = get_workblk(); | ||
315 | memset(b, 0, BLOCKSIZE); | ||
316 | ((directory*)b)->d_rec_len = BLOCKSIZE; | ||
317 | /* We run into problems with e2fsck if directory lost+found grows | ||
318 | @@ -2246,11 +2348,11 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
319 | fs->sb.s_r_blocks_count = fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS; | ||
320 | for(i = 1; i < fs->sb.s_r_blocks_count; i++) | ||
321 | extend_blk(fs, nod, b, 1); | ||
322 | + free_workblk(b); | ||
323 | node = get_nod(fs, nod, &ni); | ||
324 | node->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE; | ||
325 | put_nod(ni); | ||
326 | } | ||
327 | - free_workblk(b); | ||
328 | |||
329 | // administrative info | ||
330 | fs->sb.s_state = 1; | ||
331 | @@ -2368,19 +2470,15 @@ print_dir(filesystem *fs, uint32 nod) | ||
332 | while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END) | ||
333 | { | ||
334 | directory *d; | ||
335 | - uint8 *b; | ||
336 | - blk_info *bi; | ||
337 | - b = get_blk(fs, bk, &bi); | ||
338 | - for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
339 | + dirwalker dw; | ||
340 | + for (d = get_dir(fs, bk, &dw); d; d = next_dir(&dw)) | ||
341 | if(d->d_inode) | ||
342 | { | ||
343 | - int i; | ||
344 | printf("entry '"); | ||
345 | - for(i = 0; i < d->d_name_len; i++) | ||
346 | - putchar(d->d_name[i]); | ||
347 | + fwrite(dir_name(&dw), 1, d->d_name_len, stdout); | ||
348 | printf("' (inode %d): rec_len: %d (name_len: %d)\n", d->d_inode, d->d_rec_len, d->d_name_len); | ||
349 | } | ||
350 | - put_blk(bi); | ||
351 | + put_dir(&dw); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | -- | ||
356 | 1.7.4.1 | ||
357 | |||