1 Upstream-Status: inappropriate
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.
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
13 genext2fs.c | 234 +++++++++++++---------------------------------------------
14 1 files changed, 53 insertions(+), 181 deletions(-)
16 diff --git a/genext2fs.c b/genext2fs.c
17 index 497c9af..51403a2 100644
20 @@ -604,6 +604,7 @@ typedef struct
26 struct hdlinks_s hdlinks;
28 @@ -648,9 +649,24 @@ swap_gd(groupdescriptor *gd)
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))
47 + for(i = 0; i <= EXT2_TIND_BLOCK; i++)
48 + nod->i_block[i] = swab32(nod->i_block[i]);
53 @@ -852,6 +868,8 @@ put_blk(blk_info *bi)
62 @@ -861,19 +879,23 @@ static inline uint32 *
63 get_blkmap(filesystem *fs, uint32 blk, blkmap_info **rbmi)
68 bmi = malloc(sizeof(*bmi));
70 error_msg_and_die("get_blkmap: out of memory");
71 - b = get_blk(fs, blk, &bmi->bi);
73 + bmi->b = get_blk(fs, blk, &bmi->bi);
74 + if (bmi->fs->swapit)
77 - return (uint32 *) b;
78 + return (uint32 *) bmi->b;
82 put_blkmap(blkmap_info *bmi)
84 + if (bmi->fs->swapit)
89 @@ -882,7 +904,9 @@ put_blkmap(blkmap_info *bmi)
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)
102 int grp, offset, boffset;
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));
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);
115 + b = get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi);
116 + ni->itab = ((inode *) b) + offset;
118 + swap_nod(ni->itab);
120 - return itab+offset;
125 put_nod(nod_info *ni)
127 + if (ni->fs->swapit)
128 + swap_nod(ni->itab);
132 @@ -936,6 +966,8 @@ get_dir(filesystem *fs, uint32 nod, dirwalker *dw)
133 dw->last_d = (directory *) dw->b;
135 memcpy(&dw->d, dw->last_d, sizeof(directory));
141 @@ -945,6 +977,8 @@ next_dir(dirwalker *dw)
143 directory *next_d = (directory *)((int8*)dw->last_d + dw->d.d_rec_len);
145 + if (dw->fs->swapit)
147 memcpy(dw->last_d, &dw->d, sizeof(directory));
149 if (((int8 *) next_d) >= ((int8 *) dw->b + BLOCKSIZE))
150 @@ -952,6 +986,8 @@ next_dir(dirwalker *dw)
153 memcpy(&dw->d, next_d, sizeof(directory));
154 + if (dw->fs->swapit)
159 @@ -959,6 +995,8 @@ next_dir(dirwalker *dw)
161 put_dir(dirwalker *dw)
163 + if (dw->fs->swapit)
165 memcpy(dw->last_d, &dw->d, sizeof(directory));
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;
172 + if (dw->fs->swapit)
174 memcpy(dw->last_d, &dw->d, sizeof(directory));
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
181 -// endianness swap of x-indirect blocks
183 -swap_goodblocks(filesystem *fs, inode *nod)
188 - blk_info *bi, *bi2, *bi3;
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)
196 - swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi));
198 - if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4)
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
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));
220 - swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi));
222 - if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4)
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));
241 - swap_block((uint8 *)b2);
244 - swap_block((uint8 *)b);
250 -swap_badblocks(filesystem *fs, inode *nod)
255 - blk_info *bi, *bi2, *bi3;
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)
263 - swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi));
265 - if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4)
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));
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));
277 - if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4)
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));
304 // endianness swap of the whole filesystem
306 swap_goodfs(filesystem *fs)
311 - for(i = 1; i < fs->sb->s_inodes_count; i++)
313 - inode *nod = get_nod(fs, i, &ni);
314 - if(nod->i_mode & FM_IFDIR)
319 - while((bk = walk_bw(fs, i, &bw, 0, 0)) != WALK_END)
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)))
330 - swap_goodblocks(fs, nod);
334 for(i=0;i<GRP_NBGROUPS(fs);i++)
335 swap_gd(&(fs->gd[i]));
337 @@ -2215,35 +2108,12 @@ swap_badfs(filesystem *fs)
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++)
344 - inode *nod = get_nod(fs, i, &ni);
346 - swap_badblocks(fs, nod);
347 - if(nod->i_mode & FM_IFDIR)
352 - while((bk = walk_bw(fs, i, &bw, 0, 0)) != WALK_END)
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))
366 // Allocate a new filesystem structure, allocate internal memory,
367 // and initialize the contents.
369 -alloc_fs(uint32 nbblocks)
370 +alloc_fs(uint32 nbblocks, int swapit)
374 @@ -2251,6 +2121,7 @@ alloc_fs(uint32 nbblocks)
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)
384 // initialize an empty 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)
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;
395 - fs = alloc_fs(nbblocks);
396 + fs = alloc_fs(nbblocks, swapit);
397 fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor))
398 + sizeof(superblock) + (BLOCKSIZE - 1))
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");
409 @@ -3014,7 +2885,8 @@ main(int argc, char **argv)
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,
418 populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL);