diff options
Diffstat (limited to 'meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch')
-rw-r--r-- | meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch | 421 |
1 files changed, 421 insertions, 0 deletions
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch new file mode 100644 index 0000000000..028fbb6b28 --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch | |||
@@ -0,0 +1,421 @@ | |||
1 | Upstream-Status: inappropriate | ||
2 | |||
3 | From 46d57a42a2185970807971f4d6d8f62b4facbaf5 Mon Sep 17 00:00:00 2001 | ||
4 | From: Corey Minyard <cminyard@mvista.com> | ||
5 | Date: Sun, 5 Jun 2011 15:00:15 -0500 | ||
6 | Subject: [PATCH 09/19] Move byte swapping into the get/put routines. | ||
7 | |||
8 | Remove the full byte-swapping of the filesystem at start/end time, and | ||
9 | instead byteswap each inode/block map/directory as it is read and written. | ||
10 | This is getting ready for the change of not holding the entire filesystem | ||
11 | in memory. | ||
12 | --- | ||
13 | genext2fs.c | 234 +++++++++++++--------------------------------------------- | ||
14 | 1 files changed, 53 insertions(+), 181 deletions(-) | ||
15 | |||
16 | diff --git a/genext2fs.c b/genext2fs.c | ||
17 | index 497c9af..51403a2 100644 | ||
18 | --- a/genext2fs.c | ||
19 | +++ b/genext2fs.c | ||
20 | @@ -604,6 +604,7 @@ typedef struct | ||
21 | superblock *sb; | ||
22 | groupdescriptor *gd; | ||
23 | uint32 nheadblocks; | ||
24 | + int swapit; | ||
25 | int32 hdlink_cnt; | ||
26 | struct hdlinks_s hdlinks; | ||
27 | } filesystem; | ||
28 | @@ -648,9 +649,24 @@ swap_gd(groupdescriptor *gd) | ||
29 | static void | ||
30 | swap_nod(inode *nod) | ||
31 | { | ||
32 | + uint32 nblk; | ||
33 | + | ||
34 | #define this nod | ||
35 | inode_decl | ||
36 | #undef this | ||
37 | + | ||
38 | + // block and character inodes store the major and minor in the | ||
39 | + // i_block, so we need to unswap to get those. Also, if it's | ||
40 | + // zero iblocks, put the data back like it belongs. | ||
41 | + nblk = nod->i_blocks / INOBLK; | ||
42 | + if ((nod->i_size && !nblk) | ||
43 | + || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) | ||
44 | + || ((nod->i_mode & FM_IFCHR) == FM_IFCHR)) | ||
45 | + { | ||
46 | + int i; | ||
47 | + for(i = 0; i <= EXT2_TIND_BLOCK; i++) | ||
48 | + nod->i_block[i] = swab32(nod->i_block[i]); | ||
49 | + } | ||
50 | } | ||
51 | |||
52 | static void | ||
53 | @@ -852,6 +868,8 @@ put_blk(blk_info *bi) | ||
54 | // owned by the user. | ||
55 | typedef struct | ||
56 | { | ||
57 | + filesystem *fs; | ||
58 | + uint8 *b; | ||
59 | blk_info *bi; | ||
60 | } blkmap_info; | ||
61 | |||
62 | @@ -861,19 +879,23 @@ static inline uint32 * | ||
63 | get_blkmap(filesystem *fs, uint32 blk, blkmap_info **rbmi) | ||
64 | { | ||
65 | blkmap_info *bmi; | ||
66 | - uint8 *b; | ||
67 | |||
68 | bmi = malloc(sizeof(*bmi)); | ||
69 | if (!bmi) | ||
70 | error_msg_and_die("get_blkmap: out of memory"); | ||
71 | - b = get_blk(fs, blk, &bmi->bi); | ||
72 | + bmi->fs = fs; | ||
73 | + bmi->b = get_blk(fs, blk, &bmi->bi); | ||
74 | + if (bmi->fs->swapit) | ||
75 | + swap_block(bmi->b); | ||
76 | *rbmi = bmi; | ||
77 | - return (uint32 *) b; | ||
78 | + return (uint32 *) bmi->b; | ||
79 | } | ||
80 | |||
81 | static inline void | ||
82 | put_blkmap(blkmap_info *bmi) | ||
83 | { | ||
84 | + if (bmi->fs->swapit) | ||
85 | + swap_block(bmi->b); | ||
86 | put_blk(bmi->bi); | ||
87 | free(bmi); | ||
88 | } | ||
89 | @@ -882,7 +904,9 @@ put_blkmap(blkmap_info *bmi) | ||
90 | // by the user. | ||
91 | typedef struct | ||
92 | { | ||
93 | + filesystem *fs; | ||
94 | blk_info *bi; | ||
95 | + inode *itab; | ||
96 | } nod_info; | ||
97 | |||
98 | // Return a given inode from a filesystem. Make sure to call put_nod() | ||
99 | @@ -891,8 +915,8 @@ static inline inode * | ||
100 | get_nod(filesystem *fs, uint32 nod, nod_info **rni) | ||
101 | { | ||
102 | int grp, offset, boffset; | ||
103 | - inode *itab; | ||
104 | nod_info *ni; | ||
105 | + uint8 *b; | ||
106 | |||
107 | offset = GRP_IBM_OFFSET(fs,nod) - 1; | ||
108 | boffset = offset / (BLOCKSIZE / sizeof(inode)); | ||
109 | @@ -901,14 +925,20 @@ get_nod(filesystem *fs, uint32 nod, nod_info **rni) | ||
110 | ni = malloc(sizeof(*ni)); | ||
111 | if (!ni) | ||
112 | error_msg_and_die("get_nod: out of memory"); | ||
113 | - itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi); | ||
114 | + ni->fs = fs; | ||
115 | + b = get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi); | ||
116 | + ni->itab = ((inode *) b) + offset; | ||
117 | + if (fs->swapit) | ||
118 | + swap_nod(ni->itab); | ||
119 | *rni = ni; | ||
120 | - return itab+offset; | ||
121 | + return ni->itab; | ||
122 | } | ||
123 | |||
124 | static inline void | ||
125 | put_nod(nod_info *ni) | ||
126 | { | ||
127 | + if (ni->fs->swapit) | ||
128 | + swap_nod(ni->itab); | ||
129 | put_blk(ni->bi); | ||
130 | free(ni); | ||
131 | } | ||
132 | @@ -936,6 +966,8 @@ get_dir(filesystem *fs, uint32 nod, dirwalker *dw) | ||
133 | dw->last_d = (directory *) dw->b; | ||
134 | |||
135 | memcpy(&dw->d, dw->last_d, sizeof(directory)); | ||
136 | + if (fs->swapit) | ||
137 | + swap_dir(&dw->d); | ||
138 | return &dw->d; | ||
139 | } | ||
140 | |||
141 | @@ -945,6 +977,8 @@ next_dir(dirwalker *dw) | ||
142 | { | ||
143 | directory *next_d = (directory *)((int8*)dw->last_d + dw->d.d_rec_len); | ||
144 | |||
145 | + if (dw->fs->swapit) | ||
146 | + swap_dir(&dw->d); | ||
147 | memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
148 | |||
149 | if (((int8 *) next_d) >= ((int8 *) dw->b + BLOCKSIZE)) | ||
150 | @@ -952,6 +986,8 @@ next_dir(dirwalker *dw) | ||
151 | |||
152 | dw->last_d = next_d; | ||
153 | memcpy(&dw->d, next_d, sizeof(directory)); | ||
154 | + if (dw->fs->swapit) | ||
155 | + swap_dir(&dw->d); | ||
156 | return &dw->d; | ||
157 | } | ||
158 | |||
159 | @@ -959,6 +995,8 @@ next_dir(dirwalker *dw) | ||
160 | static inline void | ||
161 | put_dir(dirwalker *dw) | ||
162 | { | ||
163 | + if (dw->fs->swapit) | ||
164 | + swap_dir(&dw->d); | ||
165 | memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
166 | |||
167 | if (dw->nod == 0) | ||
168 | @@ -998,6 +1036,8 @@ shrink_dir(dirwalker *dw, uint32 nod, const char *name, int nlen) | ||
169 | d->d_rec_len = sizeof(directory) + rndup(d->d_name_len, 4); | ||
170 | preclen = d->d_rec_len; | ||
171 | reclen -= preclen; | ||
172 | + if (dw->fs->swapit) | ||
173 | + swap_dir(&dw->d); | ||
174 | memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
175 | |||
176 | dw->last_d = (directory *) (((int8 *) dw->last_d) + preclen); | ||
177 | @@ -2050,159 +2090,12 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per | ||
178 | closedir(dh); | ||
179 | } | ||
180 | |||
181 | -// endianness swap of x-indirect blocks | ||
182 | -static void | ||
183 | -swap_goodblocks(filesystem *fs, inode *nod) | ||
184 | -{ | ||
185 | - uint32 i,j; | ||
186 | - int done=0; | ||
187 | - uint32 *b,*b2; | ||
188 | - blk_info *bi, *bi2, *bi3; | ||
189 | - | ||
190 | - uint32 nblk = nod->i_blocks / INOBLK; | ||
191 | - if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR)) | ||
192 | - for(i = 0; i <= EXT2_TIND_BLOCK; i++) | ||
193 | - nod->i_block[i] = swab32(nod->i_block[i]); | ||
194 | - if(nblk <= EXT2_IND_BLOCK) | ||
195 | - return; | ||
196 | - swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi)); | ||
197 | - put_blk(bi); | ||
198 | - if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4) | ||
199 | - return; | ||
200 | - /* Currently this will fail b'cos the number of blocks as stored | ||
201 | - in i_blocks also includes the indirection blocks (see | ||
202 | - walk_bw). But this function assumes that i_blocks only | ||
203 | - stores the count of data blocks ( Actually according to | ||
204 | - "Understanding the Linux Kernel" (Table 17-3 p502 1st Ed) | ||
205 | - i_blocks IS supposed to store the count of data blocks). so | ||
206 | - with a file of size 268K nblk would be 269.The above check | ||
207 | - will be false even though double indirection hasn't been | ||
208 | - started.This is benign as 0 means block 0 which has been | ||
209 | - zeroed out and therefore points back to itself from any offset | ||
210 | - */ | ||
211 | - // FIXME: I have fixed that, but I have the feeling the rest of | ||
212 | - // ths function needs to be fixed for the same reasons - Xav | ||
213 | - assert(nod->i_block[EXT2_DIND_BLOCK] != 0); | ||
214 | - for(i = 0; i < BLOCKSIZE/4; i++) | ||
215 | - if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) { | ||
216 | - swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi))[i], &bi2)); | ||
217 | - put_blk(bi); | ||
218 | - put_blk(bi2); | ||
219 | - } | ||
220 | - swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi)); | ||
221 | - put_blk(bi); | ||
222 | - if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4) | ||
223 | - return; | ||
224 | - /* Adding support for triple indirection */ | ||
225 | - b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK], &bi); | ||
226 | - for(i=0;i < BLOCKSIZE/4 && !done ; i++) { | ||
227 | - b2 = (uint32*)get_blk(fs,b[i], &bi2); | ||
228 | - for(j=0; j<BLOCKSIZE/4;j++) { | ||
229 | - if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 + | ||
230 | - (BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
231 | - i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
232 | - j*(BLOCKSIZE/4)) ) { | ||
233 | - swap_block(get_blk(fs,b2[j],&bi3)); | ||
234 | - put_blk(bi3); | ||
235 | - } | ||
236 | - else { | ||
237 | - done = 1; | ||
238 | - break; | ||
239 | - } | ||
240 | - } | ||
241 | - swap_block((uint8 *)b2); | ||
242 | - put_blk(bi2); | ||
243 | - } | ||
244 | - swap_block((uint8 *)b); | ||
245 | - put_blk(bi); | ||
246 | - return; | ||
247 | -} | ||
248 | - | ||
249 | -static void | ||
250 | -swap_badblocks(filesystem *fs, inode *nod) | ||
251 | -{ | ||
252 | - uint32 i,j; | ||
253 | - int done=0; | ||
254 | - uint32 *b,*b2; | ||
255 | - blk_info *bi, *bi2, *bi3; | ||
256 | - | ||
257 | - uint32 nblk = nod->i_blocks / INOBLK; | ||
258 | - if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR)) | ||
259 | - for(i = 0; i <= EXT2_TIND_BLOCK; i++) | ||
260 | - nod->i_block[i] = swab32(nod->i_block[i]); | ||
261 | - if(nblk <= EXT2_IND_BLOCK) | ||
262 | - return; | ||
263 | - swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi)); | ||
264 | - put_blk(bi); | ||
265 | - if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4) | ||
266 | - return; | ||
267 | - /* See comment in swap_goodblocks */ | ||
268 | - assert(nod->i_block[EXT2_DIND_BLOCK] != 0); | ||
269 | - swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi)); | ||
270 | - put_blk(bi); | ||
271 | - for(i = 0; i < BLOCKSIZE/4; i++) | ||
272 | - if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) { | ||
273 | - swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK],&bi))[i], &bi2)); | ||
274 | - put_blk(bi); | ||
275 | - put_blk(bi2); | ||
276 | - } | ||
277 | - if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4) | ||
278 | - return; | ||
279 | - /* Adding support for triple indirection */ | ||
280 | - b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK],&bi); | ||
281 | - swap_block((uint8 *)b); | ||
282 | - for(i=0;i < BLOCKSIZE/4 && !done ; i++) { | ||
283 | - b2 = (uint32*)get_blk(fs,b[i],&bi2); | ||
284 | - swap_block((uint8 *)b2); | ||
285 | - for(j=0; j<BLOCKSIZE/4;j++) { | ||
286 | - if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 + | ||
287 | - (BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
288 | - i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
289 | - j*(BLOCKSIZE/4)) ) { | ||
290 | - swap_block(get_blk(fs,b2[j],&bi3)); | ||
291 | - put_blk(bi3); | ||
292 | - } | ||
293 | - else { | ||
294 | - done = 1; | ||
295 | - break; | ||
296 | - } | ||
297 | - } | ||
298 | - put_blk(bi2); | ||
299 | - } | ||
300 | - put_blk(bi); | ||
301 | - return; | ||
302 | -} | ||
303 | - | ||
304 | // endianness swap of the whole filesystem | ||
305 | static void | ||
306 | swap_goodfs(filesystem *fs) | ||
307 | { | ||
308 | uint32 i; | ||
309 | - nod_info *ni; | ||
310 | |||
311 | - for(i = 1; i < fs->sb->s_inodes_count; i++) | ||
312 | - { | ||
313 | - inode *nod = get_nod(fs, i, &ni); | ||
314 | - if(nod->i_mode & FM_IFDIR) | ||
315 | - { | ||
316 | - blockwalker bw; | ||
317 | - uint32 bk; | ||
318 | - init_bw(&bw); | ||
319 | - while((bk = walk_bw(fs, i, &bw, 0, 0)) != WALK_END) | ||
320 | - { | ||
321 | - directory *d; | ||
322 | - uint8 *b; | ||
323 | - blk_info *bi; | ||
324 | - b = get_blk(fs, bk, &bi); | ||
325 | - for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + swab16(d->d_rec_len))) | ||
326 | - swap_dir(d); | ||
327 | - put_blk(bi); | ||
328 | - } | ||
329 | - } | ||
330 | - swap_goodblocks(fs, nod); | ||
331 | - swap_nod(nod); | ||
332 | - put_nod(ni); | ||
333 | - } | ||
334 | for(i=0;i<GRP_NBGROUPS(fs);i++) | ||
335 | swap_gd(&(fs->gd[i])); | ||
336 | swap_sb(fs->sb); | ||
337 | @@ -2215,35 +2108,12 @@ swap_badfs(filesystem *fs) | ||
338 | swap_sb(fs->sb); | ||
339 | for(i=0;i<GRP_NBGROUPS(fs);i++) | ||
340 | swap_gd(&(fs->gd[i])); | ||
341 | - for(i = 1; i < fs->sb->s_inodes_count; i++) | ||
342 | - { | ||
343 | - nod_info *ni; | ||
344 | - inode *nod = get_nod(fs, i, &ni); | ||
345 | - swap_nod(nod); | ||
346 | - swap_badblocks(fs, nod); | ||
347 | - if(nod->i_mode & FM_IFDIR) | ||
348 | - { | ||
349 | - blockwalker bw; | ||
350 | - uint32 bk; | ||
351 | - init_bw(&bw); | ||
352 | - while((bk = walk_bw(fs, i, &bw, 0, 0)) != WALK_END) | ||
353 | - { | ||
354 | - directory *d; | ||
355 | - uint8 *b; | ||
356 | - blk_info *bi; | ||
357 | - b = get_blk(fs, bk, &bi); | ||
358 | - for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
359 | - swap_dir(d); | ||
360 | - put_blk(bi); | ||
361 | - } | ||
362 | - } | ||
363 | - } | ||
364 | } | ||
365 | |||
366 | // Allocate a new filesystem structure, allocate internal memory, | ||
367 | // and initialize the contents. | ||
368 | static filesystem * | ||
369 | -alloc_fs(uint32 nbblocks) | ||
370 | +alloc_fs(uint32 nbblocks, int swapit) | ||
371 | { | ||
372 | filesystem *fs; | ||
373 | |||
374 | @@ -2251,6 +2121,7 @@ alloc_fs(uint32 nbblocks) | ||
375 | if (!fs) | ||
376 | error_msg_and_die("not enough memory for filesystem"); | ||
377 | memset(fs, 0, sizeof(*fs)); | ||
378 | + fs->swapit = swapit; | ||
379 | if(!(fs->data = calloc(nbblocks, BLOCKSIZE))) | ||
380 | error_msg_and_die("not enough memory for filesystem"); | ||
381 | fs->hdlink_cnt = HDLINK_CNT; | ||
382 | @@ -2265,7 +2136,7 @@ alloc_fs(uint32 nbblocks) | ||
383 | |||
384 | // initialize an empty filesystem | ||
385 | static filesystem * | ||
386 | -init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp) | ||
387 | +init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp, int swapit) | ||
388 | { | ||
389 | uint32 i; | ||
390 | filesystem *fs; | ||
391 | @@ -2313,7 +2184,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
392 | free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/; | ||
393 | free_blocks_per_group = nbblocks_per_group - overhead_per_group; | ||
394 | |||
395 | - fs = alloc_fs(nbblocks); | ||
396 | + fs = alloc_fs(nbblocks, swapit); | ||
397 | fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor)) | ||
398 | + sizeof(superblock) + (BLOCKSIZE - 1)) | ||
399 | / BLOCKSIZE); | ||
400 | @@ -2454,7 +2325,7 @@ load_fs(FILE * fh, int swapit) | ||
401 | fssize = (fssize + BLOCKSIZE - 1) / BLOCKSIZE; | ||
402 | if(fssize < 16) // totally arbitrary | ||
403 | error_msg_and_die("too small filesystem"); | ||
404 | - fs = alloc_fs(fssize); | ||
405 | + fs = alloc_fs(fssize, swapit); | ||
406 | if(fread(fs->data, BLOCKSIZE, fssize, fh) != fssize) | ||
407 | perror_msg_and_die("input filesystem image"); | ||
408 | |||
409 | @@ -3014,7 +2885,8 @@ main(int argc, char **argv) | ||
410 | } | ||
411 | if(fs_timestamp == -1) | ||
412 | fs_timestamp = time(NULL); | ||
413 | - fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp); | ||
414 | + fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp, | ||
415 | + bigendian); | ||
416 | } | ||
417 | |||
418 | populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL); | ||
419 | -- | ||
420 | 1.7.4.1 | ||
421 | |||