summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch
diff options
context:
space:
mode:
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.patch421
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 @@
1Upstream-Status: inappropriate
2
3From 46d57a42a2185970807971f4d6d8f62b4facbaf5 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sun, 5 Jun 2011 15:00:15 -0500
6Subject: [PATCH 09/19] Move byte swapping into the get/put routines.
7
8Remove the full byte-swapping of the filesystem at start/end time, and
9instead byteswap each inode/block map/directory as it is read and written.
10This is getting ready for the change of not holding the entire filesystem
11in memory.
12---
13 genext2fs.c | 234 +++++++++++++---------------------------------------------
14 1 files changed, 53 insertions(+), 181 deletions(-)
15
16diff --git a/genext2fs.c b/genext2fs.c
17index 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--
4201.7.4.1
421