summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch
diff options
context:
space:
mode:
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.patch357
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 @@
1Upstream-Status: inappropriate
2
3From 3d47e37e21f6a2ced489d49e8bf5a5c24bb9baaf Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sun, 5 Jun 2011 09:36:11 -0500
6Subject: [PATCH 04/19] Add a dirwalker for walking through directory entries
7
8The code to walk directory items was messy, to say the least. Write a
9clean structure to do this.
10
11Also, remove d_name[0]. This is bad style, and newer compilers will
12think it is really a zero-length array and will abort if trying to write
13any 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
18diff --git a/genext2fs.c b/genext2fs.c
19index 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--
3561.7.4.1
357