]> code.ossystems Code Review - openembedded-core.git/blob
028fbb6b28ee5cedcb4ee81ffee2868a0fc7e67b
[openembedded-core.git] /
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