summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorDexuan Cui <dexuan.cui@intel.com>2012-03-29 00:35:09 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-04-02 04:31:48 +0100
commit79c806cb404c2d85aeec45b40ea6adbeae9f6346 (patch)
tree5627bb72a24373b931e6a3d4190335bc904cfd88 /meta
parent84b7541abc2d7e59c22891219fce97d320d3bb33 (diff)
downloadpoky-79c806cb404c2d85aeec45b40ea6adbeae9f6346.tar.gz
genext2fs: support large files and filesystems without using large amounts of memory
update_to_1.95.patch was generated by making a diff bewteen the 1.4.1 release and the latest 1.9.5 version in the cvs repo: http://genext2fs.cvs.sourceforge.net/viewvc/genext2fs/genext2fs/genext2fs.c?revision=1.95 The patches 0001-0019 come from mailing list of genext2fs-devel http://sourceforge.net/mailarchive/forum.php?forum_name=genext2fs-devel&max_rows=100&style=flat&viewmonth=201106 (From OE-Core rev: 8f17e499cf91191727c8767e839738cb39c21655) Signed-off-by: Dexuan Cui <dexuan.cui@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0001-Fix-warnings-remove-some-unused-macros.patch72
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0002-Add-put_blk-and-put_nod-routines.patch1123
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0003-Add-get_blkmap-and-put_blkmap.patch222
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch357
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0005-Make-filesystem-struct-not-an-overloay.patch374
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch272
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0007-Move-hdlinks-into-the-filesystem-structure.patch175
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0008-Separate-out-the-creation-of-the-filesystem-structur.patch95
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch421
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0010-Convert-over-to-keeping-the-filesystem-on-disk.patch839
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0011-Copy-files-into-the-filesystem-a-piece-at-a-time.patch103
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0012-Add-rev-1-support-large-file-support-and-rework-hole.patch211
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0013-Add-volume-id-support.patch86
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0014-Remove-unneeded-setting-of-s_reserved.patch28
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0015-Rework-creating-the-lost-found-directory.patch57
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0016-Fix-the-documentation-for-the-new-L-option.patch29
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0017-Fix-file-same-comparison.patch30
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0018-Handle-files-changing-while-we-are-working.patch89
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0019-Make-sure-superblock-is-clear-on-allocation.patch42
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/fix-nbblocks-cast.patch18
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/update_to_1.95.patch119
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs_1.4.1.bb24
22 files changed, 4776 insertions, 10 deletions
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0001-Fix-warnings-remove-some-unused-macros.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0001-Fix-warnings-remove-some-unused-macros.patch
new file mode 100644
index 0000000000..f981b449ba
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0001-Fix-warnings-remove-some-unused-macros.patch
@@ -0,0 +1,72 @@
1Upstream-Status: inappropriate
2
3From 1399df7672ec309523bcd067da24d72aa624f783 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Wed, 1 Jun 2011 07:51:24 -0500
6Subject: [PATCH 01/19] Fix warnings, remove some unused macros.
7
8These are some annoying warnings with newer toolchains. And NAMLEN is
9never used, so just get rid of it.
10---
11 genext2fs.c | 15 +++++++++------
12 1 files changed, 9 insertions(+), 6 deletions(-)
13
14diff --git a/genext2fs.c b/genext2fs.c
15index f0d797d..284862d 100644
16--- a/genext2fs.c
17+++ b/genext2fs.c
18@@ -107,10 +107,8 @@
19
20 #if HAVE_DIRENT_H
21 # include <dirent.h>
22-# define NAMLEN(dirent) strlen((dirent)->d_name)
23 #else
24 # define dirent direct
25-# define NAMLEN(dirent) (dirent)->d_namlen
26 # if HAVE_SYS_NDIR_H
27 # include <sys/ndir.h>
28 # endif
29@@ -1441,7 +1439,8 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size
30 if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1)))
31 error_msg_and_die("not enough mem to read file '%s'", name);
32 if(f)
33- fread(b, size, 1, f); // FIXME: ugly. use mmap() ...
34+ if (fread(b, size, 1, f) != 1) // FIXME: ugly. use mmap() ...
35+ error_msg_and_die("fread failed");
36 extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
37 free(b);
38 }
39@@ -1673,7 +1672,9 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per
40 if(chdir(dent->d_name) < 0)
41 perror_msg_and_die(dent->d_name);
42 add2fs_from_dir(fs, this_nod, squash_uids, squash_perms, fs_timestamp, stats);
43- chdir("..");
44+ if (chdir("..") == -1)
45+ perror_msg_and_die("..");
46+
47 break;
48 default:
49 break;
50@@ -1687,7 +1688,8 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per
51 if(chdir(dent->d_name) < 0)
52 perror_msg_and_die(name);
53 add2fs_from_dir(fs, nod, squash_uids, squash_perms, fs_timestamp, stats);
54- chdir("..");
55+ if (chdir("..") == -1)
56+ perror_msg_and_die("..");
57 }
58 continue;
59 }
60@@ -1733,7 +1735,8 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per
61 if(chdir(dent->d_name) < 0)
62 perror_msg_and_die(name);
63 add2fs_from_dir(fs, nod, squash_uids, squash_perms, fs_timestamp, stats);
64- chdir("..");
65+ if (chdir("..") == -1)
66+ perror_msg_and_die("..");
67 break;
68 default:
69 error_msg("ignoring entry %s", name);
70--
711.7.4.1
72
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0002-Add-put_blk-and-put_nod-routines.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0002-Add-put_blk-and-put_nod-routines.patch
new file mode 100644
index 0000000000..ddcd052edc
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0002-Add-put_blk-and-put_nod-routines.patch
@@ -0,0 +1,1123 @@
1Upstream-Status: inappropriate
2
3From 8dd6e604777ffeb4d30921592f199cd9bcc8a3e2 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sat, 4 Jun 2011 15:23:29 -0500
6Subject: [PATCH 02/19] Add put_blk and put_nod routines
7
8Add the routines to mark that we are done with a block or inode, and
9add the info structures so that get and put will work. This doesn't
10do anything functionally, just getting ready for future changes.
11
12Most of the changes are pretty straightforward. There were changes in
13get_nod() because it could use a later block than the one actually
14fetches. And walk_bw() needed some special handling to avoid using data
15after the put routine.
16---
17 genext2fs.c | 480 ++++++++++++++++++++++++++++++++++++++++-------------------
18 1 files changed, 330 insertions(+), 150 deletions(-)
19
20diff --git a/genext2fs.c b/genext2fs.c
21index 284862d..bd06369 100644
22--- a/genext2fs.c
23+++ b/genext2fs.c
24@@ -236,18 +236,22 @@ struct stats {
25 (((fs)->sb.s_blocks_count - fs->sb.s_first_data_block + \
26 (fs)->sb.s_blocks_per_group - 1) / (fs)->sb.s_blocks_per_group)
27
28-// Get group block bitmap (bbm) given the group number
29-#define GRP_GET_GROUP_BBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap) )
30+// Get/put group block bitmap (bbm) given the group number
31+#define GRP_GET_GROUP_BBM(fs,grp,bi) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap,(bi)) )
32+#define GRP_PUT_GROUP_BBM(bi) ( put_blk((bi)) )
33
34-// Get group inode bitmap (ibm) given the group number
35-#define GRP_GET_GROUP_IBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_inode_bitmap) )
36+// Get/put group inode bitmap (ibm) given the group number
37+#define GRP_GET_GROUP_IBM(fs,grp,bi) ( get_blk((fs),(fs)->gd[(grp)].bg_inode_bitmap,(bi)) )
38+#define GRP_PUT_GROUP_IBM(bi) ( put_blk((bi)) )
39
40 // Given an inode number find the group it belongs to
41 #define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb.s_inodes_per_group)
42
43-//Given an inode number get the inode bitmap that covers it
44-#define GRP_GET_INODE_BITMAP(fs,nod) \
45- ( GRP_GET_GROUP_IBM((fs),GRP_GROUP_OF_INODE((fs),(nod))) )
46+//Given an inode number get/put the inode bitmap that covers it
47+#define GRP_GET_INODE_BITMAP(fs,nod,bi) \
48+ ( GRP_GET_GROUP_IBM((fs),GRP_GROUP_OF_INODE((fs),(nod)),(bi)) )
49+#define GRP_PUT_INODE_BITMAP(bi) \
50+ ( GRP_PUT_GROUP_IBM((bi)) )
51
52 //Given an inode number find its offset within the inode bitmap that covers it
53 #define GRP_IBM_OFFSET(fs,nod) \
54@@ -256,9 +260,11 @@ struct stats {
55 // Given a block number find the group it belongs to
56 #define GRP_GROUP_OF_BLOCK(fs,blk) ( ((blk)-1) / (fs)->sb.s_blocks_per_group)
57
58-//Given a block number get the block bitmap that covers it
59-#define GRP_GET_BLOCK_BITMAP(fs,blk) \
60- ( GRP_GET_GROUP_BBM((fs),GRP_GROUP_OF_BLOCK((fs),(blk))) )
61+//Given a block number get/put the block bitmap that covers it
62+#define GRP_GET_BLOCK_BITMAP(fs,blk,bi) \
63+ ( GRP_GET_GROUP_BBM((fs),GRP_GROUP_OF_BLOCK((fs),(blk)),(bi)) )
64+#define GRP_PUT_BLOCK_BITMAP(bi) \
65+ ( GRP_PUT_GROUP_BBM((bi)) )
66
67 //Given a block number find its offset within the block bitmap that covers it
68 #define GRP_BBM_OFFSET(fs,blk) \
69@@ -811,24 +817,59 @@ allocated(block b, uint32 item)
70 return b[(item-1) / 8] & (1 << ((item-1) % 8));
71 }
72
73-// return a given block from a filesystem
74+// Used by get_blk/put_blk to hold information about a block owned
75+// by the user.
76+typedef struct
77+{
78+ int dummy;
79+} blk_info;
80+
81+// Return a given block from a filesystem. Make sure to call
82+// put_blk when you are done with it.
83 static inline uint8 *
84-get_blk(filesystem *fs, uint32 blk)
85+get_blk(filesystem *fs, uint32 blk, blk_info **rbi)
86 {
87 return (uint8*)fs + blk*BLOCKSIZE;
88 }
89
90-// return a given inode from a filesystem
91+static inline void
92+put_blk(blk_info *bi)
93+{
94+}
95+
96+// Used by get_nod/put_nod to hold information about an inode owned
97+// by the user.
98+typedef struct
99+{
100+ blk_info *bi;
101+} nod_info;
102+
103+// Return a given inode from a filesystem. Make sure to call put_nod()
104+// when you are done with the inode.
105 static inline inode *
106-get_nod(filesystem *fs, uint32 nod)
107+get_nod(filesystem *fs, uint32 nod, nod_info **rni)
108 {
109- int grp,offset;
110+ int grp, offset, boffset;
111 inode *itab;
112+ nod_info *ni;
113
114- offset = GRP_IBM_OFFSET(fs,nod);
115+ offset = GRP_IBM_OFFSET(fs,nod) - 1;
116+ boffset = offset / (BLOCKSIZE / sizeof(inode));
117+ offset %= BLOCKSIZE / sizeof(inode);
118 grp = GRP_GROUP_OF_INODE(fs,nod);
119- itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table);
120- return itab+offset-1;
121+ ni = malloc(sizeof(*ni));
122+ if (!ni)
123+ error_msg_and_die("get_nod: out of memory");
124+ itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi);
125+ *rni = ni;
126+ return itab+offset;
127+}
128+
129+static inline void
130+put_nod(nod_info *ni)
131+{
132+ put_blk(ni->bi);
133+ free(ni);
134 }
135
136 // allocate a given block/inode in the bitmap
137@@ -870,12 +911,17 @@ alloc_blk(filesystem *fs, uint32 nod)
138 {
139 uint32 bk=0;
140 uint32 grp,nbgroups;
141+ blk_info *bi;
142
143 grp = GRP_GROUP_OF_INODE(fs,nod);
144 nbgroups = GRP_NBGROUPS(fs);
145- if(!(bk = allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), 0))) {
146- for(grp=0;grp<nbgroups && !bk;grp++)
147- bk=allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap),0);
148+ bk = allocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), 0);
149+ put_blk(bi);
150+ if (!bk) {
151+ for (grp=0; grp<nbgroups && !bk; grp++) {
152+ bk = allocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), 0);
153+ put_blk(bi);
154+ }
155 grp--;
156 }
157 if (!bk)
158@@ -892,10 +938,12 @@ static void
159 free_blk(filesystem *fs, uint32 bk)
160 {
161 uint32 grp;
162+ blk_info *bi;
163
164 grp = bk / fs->sb.s_blocks_per_group;
165 bk %= fs->sb.s_blocks_per_group;
166- deallocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), bk);
167+ deallocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), bk);
168+ put_blk(bi);
169 fs->gd[grp].bg_free_blocks_count++;
170 fs->sb.s_free_blocks_count++;
171 }
172@@ -906,6 +954,7 @@ alloc_nod(filesystem *fs)
173 {
174 uint32 nod,best_group=0;
175 uint32 grp,nbgroups,avefreei;
176+ blk_info *bi;
177
178 nbgroups = GRP_NBGROUPS(fs);
179
180@@ -923,8 +972,10 @@ alloc_nod(filesystem *fs)
181 fs->gd[grp].bg_free_blocks_count > fs->gd[best_group].bg_free_blocks_count)
182 best_group = grp;
183 }
184- if (!(nod = allocate(get_blk(fs,fs->gd[best_group].bg_inode_bitmap),0)))
185+ if (!(nod = allocate(get_blk(fs, fs->gd[best_group].bg_inode_bitmap,
186+ &bi), 0)))
187 error_msg_and_die("couldn't allocate an inode (no free inode)");
188+ put_blk(bi);
189 if(!(fs->gd[best_group].bg_free_inodes_count--))
190 error_msg_and_die("group descr. free blocks count == 0 (corrupted fs?)");
191 if(!(fs->sb.s_free_inodes_count--))
192@@ -968,24 +1019,35 @@ static uint32
193 walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
194 {
195 uint32 *bkref = 0;
196+ uint32 bk = 0;
197 uint32 *b;
198 int extend = 0, reduce = 0;
199+ inode *inod;
200+ nod_info *ni;
201+ uint32 *iblk;
202+ blk_info *bi1 = NULL, *bi2 = NULL, *bi3 = NULL;
203+
204 if(create && (*create) < 0)
205 reduce = 1;
206- if(bw->bnum >= get_nod(fs, nod)->i_blocks / INOBLK)
207+ inod = get_nod(fs, nod, &ni);
208+ if(bw->bnum >= inod->i_blocks / INOBLK)
209 {
210 if(create && (*create) > 0)
211 {
212 (*create)--;
213 extend = 1;
214 }
215- else
216+ else
217+ {
218+ put_nod(ni);
219 return WALK_END;
220+ }
221 }
222+ iblk = inod->i_block;
223 // first direct block
224 if(bw->bpdir == EXT2_INIT_BLOCK)
225 {
226- bkref = &get_nod(fs, nod)->i_block[bw->bpdir = 0];
227+ bkref = &iblk[bw->bpdir = 0];
228 if(extend) // allocate first block
229 *bkref = hole ? 0 : alloc_blk(fs,nod);
230 if(reduce) // free first block
231@@ -994,7 +1056,7 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
232 // direct block
233 else if(bw->bpdir < EXT2_NDIR_BLOCKS)
234 {
235- bkref = &get_nod(fs, nod)->i_block[++bw->bpdir];
236+ bkref = &iblk[++bw->bpdir];
237 if(extend) // allocate block
238 *bkref = hole ? 0 : alloc_blk(fs,nod);
239 if(reduce) // free block
240@@ -1007,10 +1069,10 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
241 bw->bpdir = EXT2_IND_BLOCK;
242 bw->bpind = 0;
243 if(extend) // allocate indirect block
244- get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod);
245+ iblk[bw->bpdir] = alloc_blk(fs,nod);
246 if(reduce) // free indirect block
247- free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
248- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
249+ free_blk(fs, iblk[bw->bpdir]);
250+ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
251 bkref = &b[bw->bpind];
252 if(extend) // allocate first block
253 *bkref = hole ? 0 : alloc_blk(fs,nod);
254@@ -1021,7 +1083,7 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
255 else if((bw->bpdir == EXT2_IND_BLOCK) && (bw->bpind < BLOCKSIZE/4 - 1))
256 {
257 bw->bpind++;
258- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
259+ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
260 bkref = &b[bw->bpind];
261 if(extend) // allocate block
262 *bkref = hole ? 0 : alloc_blk(fs,nod);
263@@ -1036,15 +1098,15 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
264 bw->bpind = 0;
265 bw->bpdind = 0;
266 if(extend) // allocate double indirect block
267- get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod);
268+ iblk[bw->bpdir] = alloc_blk(fs,nod);
269 if(reduce) // free double indirect block
270- free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
271- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
272+ free_blk(fs, iblk[bw->bpdir]);
273+ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
274 if(extend) // allocate first indirect block
275 b[bw->bpind] = alloc_blk(fs,nod);
276 if(reduce) // free firstindirect block
277 free_blk(fs, b[bw->bpind]);
278- b = (uint32*)get_blk(fs, b[bw->bpind]);
279+ b = (uint32*)get_blk(fs, b[bw->bpind], &bi1);
280 bkref = &b[bw->bpdind];
281 if(extend) // allocate first block
282 *bkref = hole ? 0 : alloc_blk(fs,nod);
283@@ -1055,8 +1117,8 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
284 else if((bw->bpdir == EXT2_DIND_BLOCK) && (bw->bpdind < BLOCKSIZE/4 - 1))
285 {
286 bw->bpdind++;
287- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
288- b = (uint32*)get_blk(fs, b[bw->bpind]);
289+ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
290+ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
291 bkref = &b[bw->bpdind];
292 if(extend) // allocate block
293 *bkref = hole ? 0 : alloc_blk(fs,nod);
294@@ -1069,12 +1131,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
295 bw->bnum++;
296 bw->bpdind = 0;
297 bw->bpind++;
298- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
299+ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
300 if(extend) // allocate indirect block
301 b[bw->bpind] = alloc_blk(fs,nod);
302 if(reduce) // free indirect block
303 free_blk(fs, b[bw->bpind]);
304- b = (uint32*)get_blk(fs, b[bw->bpind]);
305+ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
306 bkref = &b[bw->bpdind];
307 if(extend) // allocate first block
308 *bkref = hole ? 0 : alloc_blk(fs,nod);
309@@ -1094,20 +1156,20 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
310 bw->bpdind = 0;
311 bw->bptind = 0;
312 if(extend) // allocate triple indirect block
313- get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod);
314+ iblk[bw->bpdir] = alloc_blk(fs,nod);
315 if(reduce) // free triple indirect block
316- free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
317- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
318+ free_blk(fs, iblk[bw->bpdir]);
319+ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
320 if(extend) // allocate first double indirect block
321 b[bw->bpind] = alloc_blk(fs,nod);
322 if(reduce) // free first double indirect block
323 free_blk(fs, b[bw->bpind]);
324- b = (uint32*)get_blk(fs, b[bw->bpind]);
325+ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
326 if(extend) // allocate first indirect block
327 b[bw->bpdind] = alloc_blk(fs,nod);
328 if(reduce) // free first indirect block
329 free_blk(fs, b[bw->bpind]);
330- b = (uint32*)get_blk(fs, b[bw->bpdind]);
331+ b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
332 bkref = &b[bw->bptind];
333 if(extend) // allocate first data block
334 *bkref = hole ? 0 : alloc_blk(fs,nod);
335@@ -1121,9 +1183,9 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
336 (bw->bptind < BLOCKSIZE/4 -1) )
337 {
338 bw->bptind++;
339- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
340- b = (uint32*)get_blk(fs, b[bw->bpind]);
341- b = (uint32*)get_blk(fs, b[bw->bpdind]);
342+ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
343+ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
344+ b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
345 bkref = &b[bw->bptind];
346 if(extend) // allocate data block
347 *bkref = hole ? 0 : alloc_blk(fs,nod);
348@@ -1140,13 +1202,13 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
349 bw->bnum++;
350 bw->bptind = 0;
351 bw->bpdind++;
352- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
353- b = (uint32*)get_blk(fs, b[bw->bpind]);
354+ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
355+ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
356 if(extend) // allocate single indirect block
357 b[bw->bpdind] = alloc_blk(fs,nod);
358 if(reduce) // free indirect block
359 free_blk(fs, b[bw->bpind]);
360- b = (uint32*)get_blk(fs, b[bw->bpdind]);
361+ b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
362 bkref = &b[bw->bptind];
363 if(extend) // allocate first data block
364 *bkref = hole ? 0 : alloc_blk(fs,nod);
365@@ -1163,17 +1225,17 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
366 bw->bpdind = 0;
367 bw->bptind = 0;
368 bw->bpind++;
369- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
370+ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
371 if(extend) // allocate double indirect block
372 b[bw->bpind] = alloc_blk(fs,nod);
373 if(reduce) // free double indirect block
374 free_blk(fs, b[bw->bpind]);
375- b = (uint32*)get_blk(fs, b[bw->bpind]);
376+ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
377 if(extend) // allocate single indirect block
378 b[bw->bpdind] = alloc_blk(fs,nod);
379 if(reduce) // free indirect block
380 free_blk(fs, b[bw->bpind]);
381- b = (uint32*)get_blk(fs, b[bw->bpdind]);
382+ b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
383 bkref = &b[bw->bptind];
384 if(extend) // allocate first block
385 *bkref = hole ? 0 : alloc_blk(fs,nod);
386@@ -1184,15 +1246,28 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
387 error_msg_and_die("file too big !");
388 /* End change for walking triple indirection */
389
390- if(*bkref)
391+ bk = *bkref;
392+ if (bi3)
393+ put_blk(bi3);
394+ if (bi2)
395+ put_blk(bi2);
396+ if (bi1)
397+ put_blk(bi1);
398+
399+ if(bk)
400 {
401+ blk_info *bi;
402+ uint8 *block;
403 bw->bnum++;
404- if(!reduce && !allocated(GRP_GET_BLOCK_BITMAP(fs,*bkref), GRP_BBM_OFFSET(fs,*bkref)))
405- error_msg_and_die("[block %d of inode %d is unallocated !]", *bkref, nod);
406+ block = GRP_GET_BLOCK_BITMAP(fs,bk,&bi);
407+ if(!reduce && !allocated(block, GRP_BBM_OFFSET(fs,bk)))
408+ error_msg_and_die("[block %d of inode %d is unallocated !]", bk, nod);
409+ GRP_PUT_BLOCK_BITMAP(bi);
410 }
411 if(extend)
412- get_nod(fs, nod)->i_blocks = bw->bnum * INOBLK;
413- return *bkref;
414+ inod->i_blocks = bw->bnum * INOBLK;
415+ put_nod(ni);
416+ return bk;
417 }
418
419 // add blocks to an inode (file/dir/etc...)
420@@ -1202,15 +1277,19 @@ extend_blk(filesystem *fs, uint32 nod, block b, int amount)
421 int create = amount;
422 blockwalker bw, lbw;
423 uint32 bk;
424+ nod_info *ni;
425+ inode *inod;
426+
427+ inod = get_nod(fs, nod, &ni);
428 init_bw(&bw);
429 if(amount < 0)
430 {
431 uint32 i;
432- for(i = 0; i < get_nod(fs, nod)->i_blocks / INOBLK + amount; i++)
433+ for(i = 0; i < inod->i_blocks / INOBLK + amount; i++)
434 walk_bw(fs, nod, &bw, 0, 0);
435 while(walk_bw(fs, nod, &bw, &create, 0) != WALK_END)
436 /*nop*/;
437- get_nod(fs, nod)->i_blocks += amount * INOBLK;
438+ inod->i_blocks += amount * INOBLK;
439 }
440 else
441 {
442@@ -1232,8 +1311,11 @@ extend_blk(filesystem *fs, uint32 nod, block b, int amount)
443 }
444 if((bk = walk_bw(fs, nod, &bw, &create, !copyb)) == WALK_END)
445 break;
446- if(copyb)
447- memcpy(get_blk(fs, bk), b + BLOCKSIZE * (amount - create - 1), BLOCKSIZE);
448+ if(copyb) {
449+ blk_info *bi;
450+ memcpy(get_blk(fs, bk, &bi), b + BLOCKSIZE * (amount - create - 1), BLOCKSIZE);
451+ put_blk(bi);
452+ }
453 }
454 }
455 }
456@@ -1245,12 +1327,14 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
457 blockwalker bw;
458 uint32 bk;
459 uint8 *b;
460+ blk_info *bi;
461 directory *d;
462 int reclen, nlen;
463 inode *node;
464 inode *pnode;
465+ nod_info *dni, *ni;
466
467- pnode = get_nod(fs, dnod);
468+ pnode = get_nod(fs, dnod, &dni);
469 if((pnode->i_mode & FM_IFMT) != FM_IFDIR)
470 error_msg_and_die("can't add '%s' to a non-directory", name);
471 if(!*name)
472@@ -1264,7 +1348,7 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
473 init_bw(&bw);
474 while((bk = walk_bw(fs, dnod, &bw, 0, 0)) != WALK_END) // for all blocks in dir
475 {
476- b = get_blk(fs, bk);
477+ b = get_blk(fs, bk, &bi);
478 // for all dir entries in block
479 for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))
480 {
481@@ -1272,11 +1356,12 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
482 if((!d->d_inode) && (d->d_rec_len >= reclen))
483 {
484 d->d_inode = nod;
485- node = get_nod(fs, nod);
486+ node = get_nod(fs, nod, &ni);
487 node->i_links_count++;
488 d->d_name_len = nlen;
489 strncpy(d->d_name, name, nlen);
490- return;
491+ put_nod(ni);
492+ goto out;
493 }
494 // if entry with enough room (last one?), shrink it & use it
495 if(d->d_rec_len >= (sizeof(directory) + rndup(d->d_name_len, 4) + reclen))
496@@ -1287,11 +1372,12 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
497 d = (directory*) (((int8*)d) + d->d_rec_len);
498 d->d_rec_len = reclen;
499 d->d_inode = nod;
500- node = get_nod(fs, nod);
501+ node = get_nod(fs, nod, &ni);
502 node->i_links_count++;
503 d->d_name_len = nlen;
504 strncpy(d->d_name, name, nlen);
505- return;
506+ put_nod(ni);
507+ goto out;
508 }
509 }
510 }
511@@ -1300,14 +1386,17 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
512 error_msg_and_die("get_workblk() failed.");
513 d = (directory*)b;
514 d->d_inode = nod;
515- node = get_nod(fs, nod);
516+ node = get_nod(fs, nod, &ni);
517 node->i_links_count++;
518+ put_nod(ni);
519 d->d_rec_len = BLOCKSIZE;
520 d->d_name_len = nlen;
521 strncpy(d->d_name, name, nlen);
522 extend_blk(fs, dnod, b, 1);
523- get_nod(fs, dnod)->i_size += BLOCKSIZE;
524+ pnode->i_size += BLOCKSIZE;
525 free_workblk(b);
526+out:
527+ put_nod(dni);
528 }
529
530 // find an entry in a directory
531@@ -1316,16 +1405,20 @@ find_dir(filesystem *fs, uint32 nod, const char * name)
532 {
533 blockwalker bw;
534 uint32 bk;
535+ blk_info *bi;
536 int nlen = strlen(name);
537 init_bw(&bw);
538 while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
539 {
540 directory *d;
541 uint8 *b;
542- b = get_blk(fs, bk);
543+ b = get_blk(fs, bk, &bi);
544 for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))
545- if(d->d_inode && (nlen == d->d_name_len) && !strncmp(d->d_name, name, nlen))
546+ if(d->d_inode && (nlen == d->d_name_len) && !strncmp(d->d_name, name, nlen)) {
547+ put_blk(bi);
548 return d->d_inode;
549+ }
550+ put_blk(bi);
551 }
552 return 0;
553 }
554@@ -1361,10 +1454,12 @@ void
555 chmod_fs(filesystem *fs, uint32 nod, uint16 mode, uint16 uid, uint16 gid)
556 {
557 inode *node;
558- node = get_nod(fs, nod);
559+ nod_info *ni;
560+ node = get_nod(fs, nod, &ni);
561 node->i_mode = (node->i_mode & ~FM_IMASK) | (mode & FM_IMASK);
562 node->i_uid = uid;
563 node->i_gid = gid;
564+ put_nod(ni);
565 }
566
567 // create a simple inode
568@@ -1373,33 +1468,34 @@ mknod_fs(filesystem *fs, uint32 parent_nod, const char *name, uint16 mode, uint1
569 {
570 uint32 nod;
571 inode *node;
572+ nod_info *ni;
573+
574+ nod = alloc_nod(fs);
575+ node = get_nod(fs, nod, &ni);
576+ node->i_mode = mode;
577+ add2dir(fs, parent_nod, nod, name);
578+ switch(mode & FM_IFMT)
579 {
580- nod = alloc_nod(fs);
581- node = get_nod(fs, nod);
582- node->i_mode = mode;
583- add2dir(fs, parent_nod, nod, name);
584- switch(mode & FM_IFMT)
585- {
586- case FM_IFLNK:
587- mode = FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO;
588- break;
589- case FM_IFBLK:
590- case FM_IFCHR:
591- ((uint8*)get_nod(fs, nod)->i_block)[0] = minor;
592- ((uint8*)get_nod(fs, nod)->i_block)[1] = major;
593- break;
594- case FM_IFDIR:
595- add2dir(fs, nod, nod, ".");
596- add2dir(fs, nod, parent_nod, "..");
597- fs->gd[GRP_GROUP_OF_INODE(fs,nod)].bg_used_dirs_count++;
598- break;
599- }
600+ case FM_IFLNK:
601+ mode = FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO;
602+ break;
603+ case FM_IFBLK:
604+ case FM_IFCHR:
605+ ((uint8*)node->i_block)[0] = minor;
606+ ((uint8*)node->i_block)[1] = major;
607+ break;
608+ case FM_IFDIR:
609+ add2dir(fs, nod, nod, ".");
610+ add2dir(fs, nod, parent_nod, "..");
611+ fs->gd[GRP_GROUP_OF_INODE(fs,nod)].bg_used_dirs_count++;
612+ break;
613 }
614 node->i_uid = uid;
615 node->i_gid = gid;
616 node->i_atime = mtime;
617 node->i_ctime = ctime;
618 node->i_mtime = mtime;
619+ put_nod(ni);
620 return nod;
621 }
622
623@@ -1416,14 +1512,19 @@ static uint32
624 mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint8 *b, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime)
625 {
626 uint32 nod = mknod_fs(fs, parent_nod, name, FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO, uid, gid, 0, 0, ctime, mtime);
627- extend_blk(fs, nod, 0, - (int)get_nod(fs, nod)->i_blocks / INOBLK);
628- get_nod(fs, nod)->i_size = size;
629+ nod_info *ni;
630+ inode *node = get_nod(fs, nod, &ni);
631+
632+ extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK);
633+ node->i_size = size;
634 if(size <= 4 * (EXT2_TIND_BLOCK+1))
635 {
636- strncpy((char*)get_nod(fs, nod)->i_block, (char*)b, size);
637+ strncpy((char *)node->i_block, (char *)b, size);
638+ put_nod(ni);
639 return nod;
640 }
641 extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
642+ put_nod(ni);
643 return nod;
644 }
645
646@@ -1433,8 +1534,11 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size
647 {
648 uint8 * b;
649 uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime);
650- extend_blk(fs, nod, 0, - (int)get_nod(fs, nod)->i_blocks / INOBLK);
651- get_nod(fs, nod)->i_size = size;
652+ nod_info *ni;
653+ inode *node = get_nod(fs, nod, &ni);
654+
655+ extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK);
656+ node->i_size = size;
657 if (size) {
658 if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1)))
659 error_msg_and_die("not enough mem to read file '%s'", name);
660@@ -1444,6 +1548,7 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size
661 extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
662 free(b);
663 }
664+ put_nod(ni);
665 return nod;
666 }
667
668@@ -1766,6 +1871,7 @@ swap_goodblocks(filesystem *fs, inode *nod)
669 uint32 i,j;
670 int done=0;
671 uint32 *b,*b2;
672+ blk_info *bi, *bi2, *bi3;
673
674 uint32 nblk = nod->i_blocks / INOBLK;
675 if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR))
676@@ -1773,7 +1879,8 @@ swap_goodblocks(filesystem *fs, inode *nod)
677 nod->i_block[i] = swab32(nod->i_block[i]);
678 if(nblk <= EXT2_IND_BLOCK)
679 return;
680- swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK]));
681+ swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi));
682+ put_blk(bi);
683 if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4)
684 return;
685 /* Currently this will fail b'cos the number of blocks as stored
686@@ -1791,29 +1898,37 @@ swap_goodblocks(filesystem *fs, inode *nod)
687 // ths function needs to be fixed for the same reasons - Xav
688 assert(nod->i_block[EXT2_DIND_BLOCK] != 0);
689 for(i = 0; i < BLOCKSIZE/4; i++)
690- if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i )
691- swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]));
692- swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]));
693+ if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) {
694+ swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi))[i], &bi2));
695+ put_blk(bi);
696+ put_blk(bi2);
697+ }
698+ swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi));
699+ put_blk(bi);
700 if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4)
701 return;
702 /* Adding support for triple indirection */
703- b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK]);
704+ b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK], &bi);
705 for(i=0;i < BLOCKSIZE/4 && !done ; i++) {
706- b2 = (uint32*)get_blk(fs,b[i]);
707+ b2 = (uint32*)get_blk(fs,b[i], &bi2);
708 for(j=0; j<BLOCKSIZE/4;j++) {
709 if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 +
710 (BLOCKSIZE/4)*(BLOCKSIZE/4) +
711 i*(BLOCKSIZE/4)*(BLOCKSIZE/4) +
712- j*(BLOCKSIZE/4)) )
713- swap_block(get_blk(fs,b2[j]));
714+ j*(BLOCKSIZE/4)) ) {
715+ swap_block(get_blk(fs,b2[j],&bi3));
716+ put_blk(bi3);
717+ }
718 else {
719 done = 1;
720 break;
721 }
722 }
723 swap_block((uint8 *)b2);
724+ put_blk(bi2);
725 }
726 swap_block((uint8 *)b);
727+ put_blk(bi);
728 return;
729 }
730
731@@ -1823,6 +1938,7 @@ swap_badblocks(filesystem *fs, inode *nod)
732 uint32 i,j;
733 int done=0;
734 uint32 *b,*b2;
735+ blk_info *bi, *bi2, *bi3;
736
737 uint32 nblk = nod->i_blocks / INOBLK;
738 if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR))
739@@ -1830,35 +1946,44 @@ swap_badblocks(filesystem *fs, inode *nod)
740 nod->i_block[i] = swab32(nod->i_block[i]);
741 if(nblk <= EXT2_IND_BLOCK)
742 return;
743- swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK]));
744+ swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi));
745+ put_blk(bi);
746 if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4)
747 return;
748 /* See comment in swap_goodblocks */
749 assert(nod->i_block[EXT2_DIND_BLOCK] != 0);
750- swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]));
751+ swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi));
752+ put_blk(bi);
753 for(i = 0; i < BLOCKSIZE/4; i++)
754- if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i )
755- swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]));
756+ if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) {
757+ swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK],&bi))[i], &bi2));
758+ put_blk(bi);
759+ put_blk(bi2);
760+ }
761 if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4)
762 return;
763 /* Adding support for triple indirection */
764- b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK]);
765+ b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK],&bi);
766 swap_block((uint8 *)b);
767 for(i=0;i < BLOCKSIZE/4 && !done ; i++) {
768- b2 = (uint32*)get_blk(fs,b[i]);
769+ b2 = (uint32*)get_blk(fs,b[i],&bi2);
770 swap_block((uint8 *)b2);
771 for(j=0; j<BLOCKSIZE/4;j++) {
772 if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 +
773 (BLOCKSIZE/4)*(BLOCKSIZE/4) +
774 i*(BLOCKSIZE/4)*(BLOCKSIZE/4) +
775- j*(BLOCKSIZE/4)) )
776- swap_block(get_blk(fs,b2[j]));
777+ j*(BLOCKSIZE/4)) ) {
778+ swap_block(get_blk(fs,b2[j],&bi3));
779+ put_blk(bi3);
780+ }
781 else {
782 done = 1;
783 break;
784 }
785 }
786+ put_blk(bi2);
787 }
788+ put_blk(bi);
789 return;
790 }
791
792@@ -1867,9 +1992,11 @@ static void
793 swap_goodfs(filesystem *fs)
794 {
795 uint32 i;
796+ nod_info *ni;
797+
798 for(i = 1; i < fs->sb.s_inodes_count; i++)
799 {
800- inode *nod = get_nod(fs, i);
801+ inode *nod = get_nod(fs, i, &ni);
802 if(nod->i_mode & FM_IFDIR)
803 {
804 blockwalker bw;
805@@ -1879,13 +2006,16 @@ swap_goodfs(filesystem *fs)
806 {
807 directory *d;
808 uint8 *b;
809- b = get_blk(fs, bk);
810+ blk_info *bi;
811+ b = get_blk(fs, bk, &bi);
812 for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + swab16(d->d_rec_len)))
813 swap_dir(d);
814+ put_blk(bi);
815 }
816 }
817 swap_goodblocks(fs, nod);
818 swap_nod(nod);
819+ put_nod(ni);
820 }
821 for(i=0;i<GRP_NBGROUPS(fs);i++)
822 swap_gd(&(fs->gd[i]));
823@@ -1901,7 +2031,8 @@ swap_badfs(filesystem *fs)
824 swap_gd(&(fs->gd[i]));
825 for(i = 1; i < fs->sb.s_inodes_count; i++)
826 {
827- inode *nod = get_nod(fs, i);
828+ nod_info *ni;
829+ inode *nod = get_nod(fs, i, &ni);
830 swap_nod(nod);
831 swap_badblocks(fs, nod);
832 if(nod->i_mode & FM_IFDIR)
833@@ -1913,9 +2044,11 @@ swap_badfs(filesystem *fs)
834 {
835 directory *d;
836 uint8 *b;
837- b = get_blk(fs, bk);
838+ blk_info *bi;
839+ b = get_blk(fs, bk, &bi);
840 for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))
841 swap_dir(d);
842+ put_blk(bi);
843 }
844 }
845 }
846@@ -1936,6 +2069,8 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
847 uint32 j;
848 uint8 *bbm,*ibm;
849 inode *itab0;
850+ blk_info *bi;
851+ nod_info *ni;
852
853 if(nbresrvd < 0)
854 error_msg_and_die("reserved blocks value is invalid. Note: options have changed, see --help or the man page.");
855@@ -2014,9 +2149,8 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
856 /* Mark non-filesystem blocks and inodes as allocated */
857 /* Mark system blocks and inodes as allocated */
858 for(i = 0; i<nbgroups;i++) {
859-
860 /* Block bitmap */
861- bbm = get_blk(fs,fs->gd[i].bg_block_bitmap);
862+ bbm = get_blk(fs,fs->gd[i].bg_block_bitmap, &bi);
863 //non-filesystem blocks
864 for(j = fs->gd[i].bg_free_blocks_count
865 + overhead_per_group + 1; j <= BLOCKSIZE * 8; j++)
866@@ -2024,9 +2158,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
867 //system blocks
868 for(j = 1; j <= overhead_per_group; j++)
869 allocate(bbm, j);
870+ put_blk(bi);
871
872 /* Inode bitmap */
873- ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap);
874+ ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap, &bi);
875 //non-filesystem inodes
876 for(j = fs->sb.s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++)
877 allocate(ibm, j);
878@@ -2035,6 +2170,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
879 if(i == 0)
880 for(j = 1; j < EXT2_FIRST_INO; j++)
881 allocate(ibm, j);
882+ put_blk(bi);
883 }
884
885 // make root inode and directory
886@@ -2042,13 +2178,14 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
887 /* Also increment the directory count for group 0 */
888 fs->gd[0].bg_free_inodes_count--;
889 fs->gd[0].bg_used_dirs_count = 1;
890- itab0 = (inode *)get_blk(fs,fs->gd[0].bg_inode_table);
891- itab0[EXT2_ROOT_INO-1].i_mode = FM_IFDIR | FM_IRWXU | FM_IRGRP | FM_IROTH | FM_IXGRP | FM_IXOTH;
892- itab0[EXT2_ROOT_INO-1].i_ctime = fs_timestamp;
893- itab0[EXT2_ROOT_INO-1].i_mtime = fs_timestamp;
894- itab0[EXT2_ROOT_INO-1].i_atime = fs_timestamp;
895- itab0[EXT2_ROOT_INO-1].i_size = BLOCKSIZE;
896- itab0[EXT2_ROOT_INO-1].i_links_count = 2;
897+ itab0 = get_nod(fs, EXT2_ROOT_INO, &ni);
898+ itab0->i_mode = FM_IFDIR | FM_IRWXU | FM_IRGRP | FM_IROTH | FM_IXGRP | FM_IXOTH;
899+ itab0->i_ctime = fs_timestamp;
900+ itab0->i_mtime = fs_timestamp;
901+ itab0->i_atime = fs_timestamp;
902+ itab0->i_size = BLOCKSIZE;
903+ itab0->i_links_count = 2;
904+ put_nod(ni);
905
906 if(!(b = get_workblk()))
907 error_msg_and_die("get_workblk() failed.");
908@@ -2067,6 +2204,8 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
909 // make lost+found directory and reserve blocks
910 if(fs->sb.s_r_blocks_count)
911 {
912+ inode *node;
913+
914 nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU, 0, 0, fs_timestamp, fs_timestamp);
915 memset(b, 0, BLOCKSIZE);
916 ((directory*)b)->d_rec_len = BLOCKSIZE;
917@@ -2077,7 +2216,9 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
918 fs->sb.s_r_blocks_count = fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS;
919 for(i = 1; i < fs->sb.s_r_blocks_count; i++)
920 extend_blk(fs, nod, b, 1);
921- get_nod(fs, nod)->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE;
922+ node = get_nod(fs, nod, &ni);
923+ node->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE;
924+ put_nod(ni);
925 }
926 free_workblk(b);
927
928@@ -2153,16 +2294,23 @@ write_blocks(filesystem *fs, uint32 nod, FILE* f)
929 {
930 blockwalker bw;
931 uint32 bk;
932- int32 fsize = get_nod(fs, nod)->i_size;
933+ nod_info *ni;
934+ inode *node = get_nod(fs, nod, &ni);
935+ int32 fsize = node->i_size;
936+ blk_info *bi;
937+
938 init_bw(&bw);
939 while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
940 {
941 if(fsize <= 0)
942 error_msg_and_die("wrong size while saving inode %d", nod);
943- if(fwrite(get_blk(fs, bk), (fsize > BLOCKSIZE) ? BLOCKSIZE : fsize, 1, f) != 1)
944+ if(fwrite(get_blk(fs, bk, &bi),
945+ (fsize > BLOCKSIZE) ? BLOCKSIZE : fsize, 1, f) != 1)
946 error_msg_and_die("error while saving inode %d", nod);
947+ put_blk(bi);
948 fsize -= BLOCKSIZE;
949 }
950+ put_nod(ni);
951 }
952
953
954@@ -2171,8 +2319,11 @@ static void
955 print_dev(filesystem *fs, uint32 nod)
956 {
957 int minor, major;
958- minor = ((uint8*)get_nod(fs, nod)->i_block)[0];
959- major = ((uint8*)get_nod(fs, nod)->i_block)[1];
960+ nod_info *ni;
961+ inode *node = get_nod(fs, nod, &ni);
962+ minor = ((uint8*)node->i_block)[0];
963+ major = ((uint8*)node->i_block)[1];
964+ put_nod(ni);
965 printf("major: %d, minor: %d\n", major, minor);
966 }
967
968@@ -2188,7 +2339,8 @@ print_dir(filesystem *fs, uint32 nod)
969 {
970 directory *d;
971 uint8 *b;
972- b = get_blk(fs, bk);
973+ blk_info *bi;
974+ b = get_blk(fs, bk, &bi);
975 for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))
976 if(d->d_inode)
977 {
978@@ -2198,6 +2350,7 @@ print_dir(filesystem *fs, uint32 nod)
979 putchar(d->d_name[i]);
980 printf("' (inode %d): rec_len: %d (name_len: %d)\n", d->d_inode, d->d_rec_len, d->d_name_len);
981 }
982+ put_blk(bi);
983 }
984 }
985
986@@ -2205,14 +2358,18 @@ print_dir(filesystem *fs, uint32 nod)
987 static void
988 print_link(filesystem *fs, uint32 nod)
989 {
990- if(!get_nod(fs, nod)->i_blocks)
991- printf("links to '%s'\n", (char*)get_nod(fs, nod)->i_block);
992+ nod_info *ni;
993+ inode *node = get_nod(fs, nod, &ni);
994+
995+ if(!node->i_blocks)
996+ printf("links to '%s'\n", (char*)node->i_block);
997 else
998 {
999 printf("links to '");
1000 write_blocks(fs, nod, stdout);
1001 printf("'\n");
1002 }
1003+ put_nod(ni);
1004 }
1005
1006 // make a ls-like printout of permissions
1007@@ -2281,8 +2438,12 @@ print_inode(filesystem *fs, uint32 nod)
1008 {
1009 char *s;
1010 char perms[11];
1011- if(!get_nod(fs, nod)->i_mode)
1012- return;
1013+ nod_info *ni;
1014+ inode *node = get_nod(fs, nod, &ni);
1015+ blk_info *bi;
1016+
1017+ if(!node->i_mode)
1018+ goto out;
1019 switch(nod)
1020 {
1021 case EXT2_BAD_INO:
1022@@ -2304,15 +2465,18 @@ print_inode(filesystem *fs, uint32 nod)
1023 default:
1024 s = (nod >= EXT2_FIRST_INO) ? "normal" : "unknown reserved";
1025 }
1026- printf("inode %d (%s, %d links): ", nod, s, get_nod(fs, nod)->i_links_count);
1027- if(!allocated(GRP_GET_INODE_BITMAP(fs,nod), GRP_IBM_OFFSET(fs,nod)))
1028+ printf("inode %d (%s, %d links): ", nod, s, node->i_links_count);
1029+ if(!allocated(GRP_GET_INODE_BITMAP(fs,nod,&bi), GRP_IBM_OFFSET(fs,nod)))
1030 {
1031+ GRP_PUT_INODE_BITMAP(bi);
1032 printf("unallocated\n");
1033- return;
1034+ goto out;
1035 }
1036- make_perms(get_nod(fs, nod)->i_mode, perms);
1037- printf("%s, size: %d byte%s (%d block%s)\n", perms, plural(get_nod(fs, nod)->i_size), plural(get_nod(fs, nod)->i_blocks / INOBLK));
1038- switch(get_nod(fs, nod)->i_mode & FM_IFMT)
1039+ GRP_PUT_INODE_BITMAP(bi);
1040+ make_perms(node->i_mode, perms);
1041+ printf("%s, size: %d byte%s (%d block%s)\n", perms,
1042+ plural(node->i_size), plural(node->i_blocks / INOBLK));
1043+ switch(node->i_mode & FM_IFMT)
1044 {
1045 case FM_IFSOCK:
1046 list_blocks(fs, nod);
1047@@ -2340,6 +2504,8 @@ print_inode(filesystem *fs, uint32 nod)
1048 list_blocks(fs, nod);
1049 }
1050 printf("Done with inode %d\n",nod);
1051+out:
1052+ put_nod(ni);
1053 }
1054
1055 // describes various fields in a filesystem
1056@@ -2347,6 +2513,7 @@ static void
1057 print_fs(filesystem *fs)
1058 {
1059 uint32 i;
1060+ blk_info *bi;
1061 uint8 *ibm;
1062
1063 printf("%d blocks (%d free, %d reserved), first data block: %d\n",
1064@@ -2369,13 +2536,16 @@ print_fs(filesystem *fs)
1065 fs->gd[i].bg_block_bitmap, fs->gd[i].bg_inode_bitmap,
1066 fs->gd[i].bg_inode_table);
1067 printf("block bitmap allocation:\n");
1068- print_bm(GRP_GET_GROUP_BBM(fs, i),fs->sb.s_blocks_per_group);
1069+ print_bm(GRP_GET_GROUP_BBM(fs, i, &bi),
1070+ fs->sb.s_blocks_per_group);
1071+ GRP_PUT_GROUP_BBM(bi);
1072 printf("inode bitmap allocation:\n");
1073- ibm = GRP_GET_GROUP_IBM(fs, i);
1074+ ibm = GRP_GET_GROUP_IBM(fs, i, &bi);
1075 print_bm(ibm, fs->sb.s_inodes_per_group);
1076 for (i = 1; i <= fs->sb.s_inodes_per_group; i++)
1077 if (allocated(ibm, i))
1078 print_inode(fs, i);
1079+ GRP_PUT_GROUP_IBM(bi);
1080 }
1081 }
1082
1083@@ -2646,9 +2816,17 @@ main(int argc, char **argv)
1084
1085 if(emptyval) {
1086 uint32 b;
1087- for(b = 1; b < fs->sb.s_blocks_count; b++)
1088- if(!allocated(GRP_GET_BLOCK_BITMAP(fs,b),GRP_BBM_OFFSET(fs,b)))
1089- memset(get_blk(fs, b), emptyval, BLOCKSIZE);
1090+ for(b = 1; b < fs->sb.s_blocks_count; b++) {
1091+ blk_info *bi;
1092+ if(!allocated(GRP_GET_BLOCK_BITMAP(fs,b,&bi),
1093+ GRP_BBM_OFFSET(fs,b))) {
1094+ blk_info *bi2;
1095+ memset(get_blk(fs, b, &bi2), emptyval,
1096+ BLOCKSIZE);
1097+ put_blk(bi2);
1098+ }
1099+ GRP_PUT_BLOCK_BITMAP(bi);
1100+ }
1101 }
1102 if(verbose)
1103 print_fs(fs);
1104@@ -2658,13 +2836,15 @@ main(int argc, char **argv)
1105 char fname[MAX_FILENAME];
1106 char *p;
1107 FILE *fh;
1108+ nod_info *ni;
1109 if(!(nod = find_path(fs, EXT2_ROOT_INO, gopt[i])))
1110 error_msg_and_die("path %s not found in filesystem", gopt[i]);
1111 while((p = strchr(gopt[i], '/')))
1112 *p = '_';
1113 SNPRINTF(fname, MAX_FILENAME-1, "%s.blk", gopt[i]);
1114 fh = xfopen(fname, "wb");
1115- fprintf(fh, "%d:", get_nod(fs, nod)->i_size);
1116+ fprintf(fh, "%d:", get_nod(fs, nod, &ni)->i_size);
1117+ put_nod(ni);
1118 flist_blocks(fs, nod, fh);
1119 fclose(fh);
1120 }
1121--
11221.7.4.1
1123
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0003-Add-get_blkmap-and-put_blkmap.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0003-Add-get_blkmap-and-put_blkmap.patch
new file mode 100644
index 0000000000..1442dfaaed
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0003-Add-get_blkmap-and-put_blkmap.patch
@@ -0,0 +1,222 @@
1Upstream-Status: inappropriate
2
3From c196bdeae7932c5d54bbdb7e7574d3cdae46ad02 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sat, 4 Jun 2011 22:04:24 -0500
6Subject: [PATCH 03/19] Add get_blkmap and put_blkmap.
7
8Add routines for getting an putting a block map. This does not do
9anything functional, but is getting ready for when blockmaps are
10byteswapped when being read and written.
11---
12 genext2fs.c | 84 ++++++++++++++++++++++++++++++++++++++++-------------------
13 1 files changed, 57 insertions(+), 27 deletions(-)
14
15diff --git a/genext2fs.c b/genext2fs.c
16index bd06369..0b5ba6f 100644
17--- a/genext2fs.c
18+++ b/genext2fs.c
19@@ -837,6 +837,36 @@ put_blk(blk_info *bi)
20 {
21 }
22
23+// Used by get_blkmap/put_blkmap to hold information about an block map
24+// owned by the user.
25+typedef struct
26+{
27+ blk_info *bi;
28+} blkmap_info;
29+
30+// Return a given block map from a filesystem. Make sure to call
31+// put_blkmap when you are done with it.
32+static inline uint32 *
33+get_blkmap(filesystem *fs, uint32 blk, blkmap_info **rbmi)
34+{
35+ blkmap_info *bmi;
36+ uint8 *b;
37+
38+ bmi = malloc(sizeof(*bmi));
39+ if (!bmi)
40+ error_msg_and_die("get_blkmap: out of memory");
41+ b = get_blk(fs, blk, &bmi->bi);
42+ *rbmi = bmi;
43+ return (uint32 *) b;
44+}
45+
46+static inline void
47+put_blkmap(blkmap_info *bmi)
48+{
49+ put_blk(bmi->bi);
50+ free(bmi);
51+}
52+
53 // Used by get_nod/put_nod to hold information about an inode owned
54 // by the user.
55 typedef struct
56@@ -1020,12 +1050,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
57 {
58 uint32 *bkref = 0;
59 uint32 bk = 0;
60+ blkmap_info *bmi1 = NULL, *bmi2 = NULL, *bmi3 = NULL;
61 uint32 *b;
62 int extend = 0, reduce = 0;
63 inode *inod;
64 nod_info *ni;
65 uint32 *iblk;
66- blk_info *bi1 = NULL, *bi2 = NULL, *bi3 = NULL;
67
68 if(create && (*create) < 0)
69 reduce = 1;
70@@ -1072,7 +1102,7 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
71 iblk[bw->bpdir] = alloc_blk(fs,nod);
72 if(reduce) // free indirect block
73 free_blk(fs, iblk[bw->bpdir]);
74- b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
75+ b = get_blkmap(fs, iblk[bw->bpdir], &bmi1);
76 bkref = &b[bw->bpind];
77 if(extend) // allocate first block
78 *bkref = hole ? 0 : alloc_blk(fs,nod);
79@@ -1083,7 +1113,7 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
80 else if((bw->bpdir == EXT2_IND_BLOCK) && (bw->bpind < BLOCKSIZE/4 - 1))
81 {
82 bw->bpind++;
83- b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
84+ b = get_blkmap(fs, iblk[bw->bpdir], &bmi1);
85 bkref = &b[bw->bpind];
86 if(extend) // allocate block
87 *bkref = hole ? 0 : alloc_blk(fs,nod);
88@@ -1101,12 +1131,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
89 iblk[bw->bpdir] = alloc_blk(fs,nod);
90 if(reduce) // free double indirect block
91 free_blk(fs, iblk[bw->bpdir]);
92- b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
93+ b = get_blkmap(fs, iblk[bw->bpdir], &bmi1);
94 if(extend) // allocate first indirect block
95 b[bw->bpind] = alloc_blk(fs,nod);
96 if(reduce) // free firstindirect block
97 free_blk(fs, b[bw->bpind]);
98- b = (uint32*)get_blk(fs, b[bw->bpind], &bi1);
99+ b = get_blkmap(fs, b[bw->bpind], &bmi2);
100 bkref = &b[bw->bpdind];
101 if(extend) // allocate first block
102 *bkref = hole ? 0 : alloc_blk(fs,nod);
103@@ -1117,8 +1147,8 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
104 else if((bw->bpdir == EXT2_DIND_BLOCK) && (bw->bpdind < BLOCKSIZE/4 - 1))
105 {
106 bw->bpdind++;
107- b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
108- b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
109+ b = get_blkmap(fs, iblk[bw->bpdir], &bmi1);
110+ b = get_blkmap(fs, b[bw->bpind], &bmi2);
111 bkref = &b[bw->bpdind];
112 if(extend) // allocate block
113 *bkref = hole ? 0 : alloc_blk(fs,nod);
114@@ -1131,12 +1161,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
115 bw->bnum++;
116 bw->bpdind = 0;
117 bw->bpind++;
118- b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
119+ b = get_blkmap(fs, iblk[bw->bpdir], &bmi1);
120 if(extend) // allocate indirect block
121 b[bw->bpind] = alloc_blk(fs,nod);
122 if(reduce) // free indirect block
123 free_blk(fs, b[bw->bpind]);
124- b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
125+ b = get_blkmap(fs, b[bw->bpind], &bmi2);
126 bkref = &b[bw->bpdind];
127 if(extend) // allocate first block
128 *bkref = hole ? 0 : alloc_blk(fs,nod);
129@@ -1159,17 +1189,17 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
130 iblk[bw->bpdir] = alloc_blk(fs,nod);
131 if(reduce) // free triple indirect block
132 free_blk(fs, iblk[bw->bpdir]);
133- b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
134+ b = get_blkmap(fs, iblk[bw->bpdir], &bmi1);
135 if(extend) // allocate first double indirect block
136 b[bw->bpind] = alloc_blk(fs,nod);
137 if(reduce) // free first double indirect block
138 free_blk(fs, b[bw->bpind]);
139- b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
140+ b = get_blkmap(fs, b[bw->bpind], &bmi2);
141 if(extend) // allocate first indirect block
142 b[bw->bpdind] = alloc_blk(fs,nod);
143 if(reduce) // free first indirect block
144 free_blk(fs, b[bw->bpind]);
145- b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
146+ b = get_blkmap(fs, b[bw->bpdind], &bmi3);
147 bkref = &b[bw->bptind];
148 if(extend) // allocate first data block
149 *bkref = hole ? 0 : alloc_blk(fs,nod);
150@@ -1183,9 +1213,9 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
151 (bw->bptind < BLOCKSIZE/4 -1) )
152 {
153 bw->bptind++;
154- b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
155- b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
156- b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
157+ b = get_blkmap(fs, iblk[bw->bpdir], &bmi1);
158+ b = get_blkmap(fs, b[bw->bpind], &bmi2);
159+ b = get_blkmap(fs, b[bw->bpdind], &bmi3);
160 bkref = &b[bw->bptind];
161 if(extend) // allocate data block
162 *bkref = hole ? 0 : alloc_blk(fs,nod);
163@@ -1202,13 +1232,13 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
164 bw->bnum++;
165 bw->bptind = 0;
166 bw->bpdind++;
167- b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
168- b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
169+ b = get_blkmap(fs, iblk[bw->bpdir], &bmi1);
170+ b = get_blkmap(fs, b[bw->bpind], &bmi2);
171 if(extend) // allocate single indirect block
172 b[bw->bpdind] = alloc_blk(fs,nod);
173 if(reduce) // free indirect block
174 free_blk(fs, b[bw->bpind]);
175- b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
176+ b = get_blkmap(fs, b[bw->bpdind], &bmi3);
177 bkref = &b[bw->bptind];
178 if(extend) // allocate first data block
179 *bkref = hole ? 0 : alloc_blk(fs,nod);
180@@ -1225,17 +1255,17 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
181 bw->bpdind = 0;
182 bw->bptind = 0;
183 bw->bpind++;
184- b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
185+ b = get_blkmap(fs, iblk[bw->bpdir], &bmi1);
186 if(extend) // allocate double indirect block
187 b[bw->bpind] = alloc_blk(fs,nod);
188 if(reduce) // free double indirect block
189 free_blk(fs, b[bw->bpind]);
190- b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
191+ b = get_blkmap(fs, b[bw->bpind], &bmi2);
192 if(extend) // allocate single indirect block
193 b[bw->bpdind] = alloc_blk(fs,nod);
194 if(reduce) // free indirect block
195 free_blk(fs, b[bw->bpind]);
196- b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
197+ b = get_blkmap(fs, b[bw->bpdind], &bmi3);
198 bkref = &b[bw->bptind];
199 if(extend) // allocate first block
200 *bkref = hole ? 0 : alloc_blk(fs,nod);
201@@ -1247,12 +1277,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
202 /* End change for walking triple indirection */
203
204 bk = *bkref;
205- if (bi3)
206- put_blk(bi3);
207- if (bi2)
208- put_blk(bi2);
209- if (bi1)
210- put_blk(bi1);
211+ if (bmi3)
212+ put_blkmap(bmi3);
213+ if (bmi2)
214+ put_blkmap(bmi2);
215+ if (bmi1)
216+ put_blkmap(bmi1);
217
218 if(bk)
219 {
220--
2211.7.4.1
222
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
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0005-Make-filesystem-struct-not-an-overloay.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0005-Make-filesystem-struct-not-an-overloay.patch
new file mode 100644
index 0000000000..ccc33feaac
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0005-Make-filesystem-struct-not-an-overloay.patch
@@ -0,0 +1,374 @@
1Upstream-Status: inappropriate
2
3From f2090608aef32f3012b1c5943b73314176bce832 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sun, 5 Jun 2011 10:09:51 -0500
6Subject: [PATCH 05/19] Make filesystem struct not an overloay
7
8Having the filesystem structure just be a big overlay for the raw data
9means you can't easily carry along any useful metadata in it. So
10modify the filesystem structure to not be an overlay, but allocate the
11data and various pieces to be components inside the structure.
12---
13 genext2fs.c | 150 +++++++++++++++++++++++++++++++++--------------------------
14 1 files changed, 84 insertions(+), 66 deletions(-)
15
16diff --git a/genext2fs.c b/genext2fs.c
17index 03d1b27..46c9605 100644
18--- a/genext2fs.c
19+++ b/genext2fs.c
20@@ -233,8 +233,8 @@ struct stats {
21
22 // Number of groups in the filesystem
23 #define GRP_NBGROUPS(fs) \
24- (((fs)->sb.s_blocks_count - fs->sb.s_first_data_block + \
25- (fs)->sb.s_blocks_per_group - 1) / (fs)->sb.s_blocks_per_group)
26+ (((fs)->sb->s_blocks_count - fs->sb->s_first_data_block + \
27+ (fs)->sb->s_blocks_per_group - 1) / (fs)->sb->s_blocks_per_group)
28
29 // Get/put group block bitmap (bbm) given the group number
30 #define GRP_GET_GROUP_BBM(fs,grp,bi) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap,(bi)) )
31@@ -245,7 +245,7 @@ struct stats {
32 #define GRP_PUT_GROUP_IBM(bi) ( put_blk((bi)) )
33
34 // Given an inode number find the group it belongs to
35-#define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb.s_inodes_per_group)
36+#define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb->s_inodes_per_group)
37
38 //Given an inode number get/put the inode bitmap that covers it
39 #define GRP_GET_INODE_BITMAP(fs,nod,bi) \
40@@ -255,10 +255,10 @@ struct stats {
41
42 //Given an inode number find its offset within the inode bitmap that covers it
43 #define GRP_IBM_OFFSET(fs,nod) \
44- ( (nod) - GRP_GROUP_OF_INODE((fs),(nod))*(fs)->sb.s_inodes_per_group )
45+ ( (nod) - GRP_GROUP_OF_INODE((fs),(nod))*(fs)->sb->s_inodes_per_group )
46
47 // Given a block number find the group it belongs to
48-#define GRP_GROUP_OF_BLOCK(fs,blk) ( ((blk)-1) / (fs)->sb.s_blocks_per_group)
49+#define GRP_GROUP_OF_BLOCK(fs,blk) ( ((blk)-1) / (fs)->sb->s_blocks_per_group)
50
51 //Given a block number get/put the block bitmap that covers it
52 #define GRP_GET_BLOCK_BITMAP(fs,blk,bi) \
53@@ -268,7 +268,7 @@ struct stats {
54
55 //Given a block number find its offset within the block bitmap that covers it
56 #define GRP_BBM_OFFSET(fs,blk) \
57- ( (blk) - GRP_GROUP_OF_BLOCK((fs),(blk))*(fs)->sb.s_blocks_per_group )
58+ ( (blk) - GRP_GROUP_OF_BLOCK((fs),(blk))*(fs)->sb->s_blocks_per_group )
59
60
61 // used types
62@@ -577,9 +577,10 @@ typedef struct
63 #if BLOCKSIZE == 1024
64 typedef struct
65 {
66- block zero; // The famous block 0
67- superblock sb; // The superblock
68- groupdescriptor gd[0]; // The group descriptors
69+ uint8 *data;
70+ superblock *sb;
71+ groupdescriptor *gd;
72+ uint32 nheadblocks;
73 } filesystem;
74 #else
75 #error UNHANDLED BLOCKSIZE
76@@ -830,7 +831,7 @@ typedef struct
77 static inline uint8 *
78 get_blk(filesystem *fs, uint32 blk, blk_info **rbi)
79 {
80- return (uint8*)fs + blk*BLOCKSIZE;
81+ return fs->data + blk*BLOCKSIZE;
82 }
83
84 static inline void
85@@ -1079,9 +1080,9 @@ alloc_blk(filesystem *fs, uint32 nod)
86 error_msg_and_die("couldn't allocate a block (no free space)");
87 if(!(fs->gd[grp].bg_free_blocks_count--))
88 error_msg_and_die("group descr %d. free blocks count == 0 (corrupted fs?)",grp);
89- if(!(fs->sb.s_free_blocks_count--))
90+ if(!(fs->sb->s_free_blocks_count--))
91 error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)");
92- return fs->sb.s_blocks_per_group*grp + bk;
93+ return fs->sb->s_blocks_per_group*grp + bk;
94 }
95
96 // free a block
97@@ -1091,12 +1092,12 @@ free_blk(filesystem *fs, uint32 bk)
98 uint32 grp;
99 blk_info *bi;
100
101- grp = bk / fs->sb.s_blocks_per_group;
102- bk %= fs->sb.s_blocks_per_group;
103+ grp = bk / fs->sb->s_blocks_per_group;
104+ bk %= fs->sb->s_blocks_per_group;
105 deallocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), bk);
106 put_blk(bi);
107 fs->gd[grp].bg_free_blocks_count++;
108- fs->sb.s_free_blocks_count++;
109+ fs->sb->s_free_blocks_count++;
110 }
111
112 // allocate an inode
113@@ -1114,7 +1115,7 @@ alloc_nod(filesystem *fs)
114 /* find the one with the most free blocks and allocate node there */
115 /* Idea from find_group_dir in fs/ext2/ialloc.c in 2.4.19 kernel */
116 /* We do it for all inodes. */
117- avefreei = fs->sb.s_free_inodes_count / nbgroups;
118+ avefreei = fs->sb->s_free_inodes_count / nbgroups;
119 for(grp=0; grp<nbgroups; grp++) {
120 if (fs->gd[grp].bg_free_inodes_count < avefreei ||
121 fs->gd[grp].bg_free_inodes_count == 0)
122@@ -1129,9 +1130,9 @@ alloc_nod(filesystem *fs)
123 put_blk(bi);
124 if(!(fs->gd[best_group].bg_free_inodes_count--))
125 error_msg_and_die("group descr. free blocks count == 0 (corrupted fs?)");
126- if(!(fs->sb.s_free_inodes_count--))
127+ if(!(fs->sb->s_free_inodes_count--))
128 error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)");
129- return fs->sb.s_inodes_per_group*best_group+nod;
130+ return fs->sb->s_inodes_per_group*best_group+nod;
131 }
132
133 // print a bitmap allocation
134@@ -1451,7 +1452,7 @@ extend_blk(filesystem *fs, uint32 nod, block b, int amount)
135 while(create)
136 {
137 int i, copyb = 0;
138- if(!(fs->sb.s_reserved[200] & OP_HOLES))
139+ if(!(fs->sb->s_reserved[200] & OP_HOLES))
140 copyb = 1;
141 else
142 for(i = 0; i < BLOCKSIZE / 4; i++)
143@@ -2133,7 +2134,7 @@ swap_goodfs(filesystem *fs)
144 uint32 i;
145 nod_info *ni;
146
147- for(i = 1; i < fs->sb.s_inodes_count; i++)
148+ for(i = 1; i < fs->sb->s_inodes_count; i++)
149 {
150 inode *nod = get_nod(fs, i, &ni);
151 if(nod->i_mode & FM_IFDIR)
152@@ -2158,17 +2159,17 @@ swap_goodfs(filesystem *fs)
153 }
154 for(i=0;i<GRP_NBGROUPS(fs);i++)
155 swap_gd(&(fs->gd[i]));
156- swap_sb(&fs->sb);
157+ swap_sb(fs->sb);
158 }
159
160 static void
161 swap_badfs(filesystem *fs)
162 {
163 uint32 i;
164- swap_sb(&fs->sb);
165+ swap_sb(fs->sb);
166 for(i=0;i<GRP_NBGROUPS(fs);i++)
167 swap_gd(&(fs->gd[i]));
168- for(i = 1; i < fs->sb.s_inodes_count; i++)
169+ for(i = 1; i < fs->sb->s_inodes_count; i++)
170 {
171 nod_info *ni;
172 inode *nod = get_nod(fs, i, &ni);
173@@ -2242,24 +2243,32 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
174 free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/;
175 free_blocks_per_group = nbblocks_per_group - overhead_per_group;
176
177- if(!(fs = (filesystem*)calloc(nbblocks, BLOCKSIZE)))
178+ fs = malloc(sizeof(*fs));
179+ if (!fs)
180 error_msg_and_die("not enough memory for filesystem");
181+ fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor))
182+ + sizeof(superblock) + (BLOCKSIZE - 1))
183+ / BLOCKSIZE);
184+ if(!(fs->data = calloc(nbblocks, BLOCKSIZE)))
185+ error_msg_and_die("not enough memory for filesystem");
186+ fs->sb = (superblock *) (fs->data + BLOCKSIZE);
187+ fs->gd = (groupdescriptor *) (fs->sb + 1);
188
189 // create the superblock for an empty filesystem
190- fs->sb.s_inodes_count = nbinodes_per_group * nbgroups;
191- fs->sb.s_blocks_count = nbblocks;
192- fs->sb.s_r_blocks_count = nbresrvd;
193- fs->sb.s_free_blocks_count = free_blocks;
194- fs->sb.s_free_inodes_count = fs->sb.s_inodes_count - EXT2_FIRST_INO + 1;
195- fs->sb.s_first_data_block = first_block;
196- fs->sb.s_log_block_size = BLOCKSIZE >> 11;
197- fs->sb.s_log_frag_size = BLOCKSIZE >> 11;
198- fs->sb.s_blocks_per_group = nbblocks_per_group;
199- fs->sb.s_frags_per_group = nbblocks_per_group;
200- fs->sb.s_inodes_per_group = nbinodes_per_group;
201- fs->sb.s_wtime = fs_timestamp;
202- fs->sb.s_magic = EXT2_MAGIC_NUMBER;
203- fs->sb.s_lastcheck = fs_timestamp;
204+ fs->sb->s_inodes_count = nbinodes_per_group * nbgroups;
205+ fs->sb->s_blocks_count = nbblocks;
206+ fs->sb->s_r_blocks_count = nbresrvd;
207+ fs->sb->s_free_blocks_count = free_blocks;
208+ fs->sb->s_free_inodes_count = fs->sb->s_inodes_count - EXT2_FIRST_INO + 1;
209+ fs->sb->s_first_data_block = first_block;
210+ fs->sb->s_log_block_size = BLOCKSIZE >> 11;
211+ fs->sb->s_log_frag_size = BLOCKSIZE >> 11;
212+ fs->sb->s_blocks_per_group = nbblocks_per_group;
213+ fs->sb->s_frags_per_group = nbblocks_per_group;
214+ fs->sb->s_inodes_per_group = nbinodes_per_group;
215+ fs->sb->s_wtime = fs_timestamp;
216+ fs->sb->s_magic = EXT2_MAGIC_NUMBER;
217+ fs->sb->s_lastcheck = fs_timestamp;
218
219 // set up groupdescriptors
220 for(i=0, bbmpos=gdsz+2, ibmpos=bbmpos+1, itblpos=ibmpos+1;
221@@ -2301,7 +2310,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
222 /* Inode bitmap */
223 ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap, &bi);
224 //non-filesystem inodes
225- for(j = fs->sb.s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++)
226+ for(j = fs->sb->s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++)
227 allocate(ibm, j);
228
229 //system inodes
230@@ -2332,7 +2341,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
231 put_dir(&dw);
232
233 // make lost+found directory and reserve blocks
234- if(fs->sb.s_r_blocks_count)
235+ if(fs->sb->s_r_blocks_count)
236 {
237 inode *node;
238 uint8 *b;
239@@ -2344,23 +2353,23 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
240 /* We run into problems with e2fsck if directory lost+found grows
241 * bigger than this. Need to find out why this happens - sundar
242 */
243- if (fs->sb.s_r_blocks_count > fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS )
244- fs->sb.s_r_blocks_count = fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS;
245- for(i = 1; i < fs->sb.s_r_blocks_count; i++)
246+ if (fs->sb->s_r_blocks_count > fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS )
247+ fs->sb->s_r_blocks_count = fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS;
248+ for(i = 1; i < fs->sb->s_r_blocks_count; i++)
249 extend_blk(fs, nod, b, 1);
250 free_workblk(b);
251 node = get_nod(fs, nod, &ni);
252- node->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE;
253+ node->i_size = fs->sb->s_r_blocks_count * BLOCKSIZE;
254 put_nod(ni);
255 }
256
257 // administrative info
258- fs->sb.s_state = 1;
259- fs->sb.s_max_mnt_count = 20;
260+ fs->sb->s_state = 1;
261+ fs->sb->s_max_mnt_count = 20;
262
263 // options for me
264 if(holes)
265- fs->sb.s_reserved[200] |= OP_HOLES;
266+ fs->sb->s_reserved[200] |= OP_HOLES;
267
268 return fs;
269 }
270@@ -2377,20 +2386,29 @@ load_fs(FILE * fh, int swapit)
271 fssize = (fssize + BLOCKSIZE - 1) / BLOCKSIZE;
272 if(fssize < 16) // totally arbitrary
273 error_msg_and_die("too small filesystem");
274- if(!(fs = (filesystem*)calloc(fssize, BLOCKSIZE)))
275+ fs = malloc(sizeof(*fs));
276+ if (!fs)
277+ error_msg_and_die("not enough memory for filesystem");
278+ if(!(fs->data = calloc(fssize, BLOCKSIZE)))
279 error_msg_and_die("not enough memory for filesystem");
280- if(fread(fs, BLOCKSIZE, fssize, fh) != fssize)
281+ if(fread(fs->data, BLOCKSIZE, fssize, fh) != fssize)
282 perror_msg_and_die("input filesystem image");
283+ fs->sb = (superblock *) (fs->data + BLOCKSIZE);
284+ fs->gd = (groupdescriptor *) (fs->sb + 1);
285 if(swapit)
286 swap_badfs(fs);
287- if(fs->sb.s_rev_level || (fs->sb.s_magic != EXT2_MAGIC_NUMBER))
288+ if(fs->sb->s_rev_level || (fs->sb->s_magic != EXT2_MAGIC_NUMBER))
289 error_msg_and_die("not a suitable ext2 filesystem");
290+ fs->nheadblocks = (((GRP_NBGROUPS(fs) * sizeof(groupdescriptor))
291+ + sizeof(superblock) + (BLOCKSIZE - 1))
292+ / BLOCKSIZE);
293 return fs;
294 }
295
296 static void
297 free_fs(filesystem *fs)
298 {
299+ free(fs->data);
300 free(fs);
301 }
302
303@@ -2645,19 +2663,19 @@ print_fs(filesystem *fs)
304 uint8 *ibm;
305
306 printf("%d blocks (%d free, %d reserved), first data block: %d\n",
307- fs->sb.s_blocks_count, fs->sb.s_free_blocks_count,
308- fs->sb.s_r_blocks_count, fs->sb.s_first_data_block);
309- printf("%d inodes (%d free)\n", fs->sb.s_inodes_count,
310- fs->sb.s_free_inodes_count);
311+ fs->sb->s_blocks_count, fs->sb->s_free_blocks_count,
312+ fs->sb->s_r_blocks_count, fs->sb->s_first_data_block);
313+ printf("%d inodes (%d free)\n", fs->sb->s_inodes_count,
314+ fs->sb->s_free_inodes_count);
315 printf("block size = %d, frag size = %d\n",
316- fs->sb.s_log_block_size ? (fs->sb.s_log_block_size << 11) : 1024,
317- fs->sb.s_log_frag_size ? (fs->sb.s_log_frag_size << 11) : 1024);
318+ fs->sb->s_log_block_size ? (fs->sb->s_log_block_size << 11) : 1024,
319+ fs->sb->s_log_frag_size ? (fs->sb->s_log_frag_size << 11) : 1024);
320 printf("number of groups: %d\n",GRP_NBGROUPS(fs));
321 printf("%d blocks per group,%d frags per group,%d inodes per group\n",
322- fs->sb.s_blocks_per_group, fs->sb.s_frags_per_group,
323- fs->sb.s_inodes_per_group);
324+ fs->sb->s_blocks_per_group, fs->sb->s_frags_per_group,
325+ fs->sb->s_inodes_per_group);
326 printf("Size of inode table: %d blocks\n",
327- (int)(fs->sb.s_inodes_per_group * sizeof(inode) / BLOCKSIZE));
328+ (int)(fs->sb->s_inodes_per_group * sizeof(inode) / BLOCKSIZE));
329 for (i = 0; i < GRP_NBGROUPS(fs); i++) {
330 printf("Group No: %d\n", i+1);
331 printf("block bitmap: block %d,inode bitmap: block %d, inode table: block %d\n",
332@@ -2665,12 +2683,12 @@ print_fs(filesystem *fs)
333 fs->gd[i].bg_inode_table);
334 printf("block bitmap allocation:\n");
335 print_bm(GRP_GET_GROUP_BBM(fs, i, &bi),
336- fs->sb.s_blocks_per_group);
337+ fs->sb->s_blocks_per_group);
338 GRP_PUT_GROUP_BBM(bi);
339 printf("inode bitmap allocation:\n");
340 ibm = GRP_GET_GROUP_IBM(fs, i, &bi);
341- print_bm(ibm, fs->sb.s_inodes_per_group);
342- for (i = 1; i <= fs->sb.s_inodes_per_group; i++)
343+ print_bm(ibm, fs->sb->s_inodes_per_group);
344+ for (i = 1; i <= fs->sb->s_inodes_per_group; i++)
345 if (allocated(ibm, i))
346 print_inode(fs, i);
347 GRP_PUT_GROUP_IBM(bi);
348@@ -2680,11 +2698,11 @@ print_fs(filesystem *fs)
349 static void
350 dump_fs(filesystem *fs, FILE * fh, int swapit)
351 {
352- uint32 nbblocks = fs->sb.s_blocks_count;
353- fs->sb.s_reserved[200] = 0;
354+ uint32 nbblocks = fs->sb->s_blocks_count;
355+ fs->sb->s_reserved[200] = 0;
356 if(swapit)
357 swap_goodfs(fs);
358- if(fwrite(fs, BLOCKSIZE, nbblocks, fh) < nbblocks)
359+ if(fwrite(fs->data, BLOCKSIZE, nbblocks, fh) < nbblocks)
360 perror_msg_and_die("output filesystem image");
361 if(swapit)
362 swap_badfs(fs);
363@@ -2944,7 +2962,7 @@ main(int argc, char **argv)
364
365 if(emptyval) {
366 uint32 b;
367- for(b = 1; b < fs->sb.s_blocks_count; b++) {
368+ for(b = 1; b < fs->sb->s_blocks_count; b++) {
369 blk_info *bi;
370 if(!allocated(GRP_GET_BLOCK_BITMAP(fs,b,&bi),
371 GRP_BBM_OFFSET(fs,b))) {
372--
3731.7.4.1
374
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch
new file mode 100644
index 0000000000..494e3f9e8d
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch
@@ -0,0 +1,272 @@
1Upstream-Status: inappropriate
2
3From ea6cbe2880e02026667b9007db9a742be7dcd52b Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sun, 5 Jun 2011 10:26:11 -0500
6Subject: [PATCH 06/19] Improve the efficiency of extend_blk
7
8When doing multiple extensions operations on the same inode, extend_blk()
9would search to the end every time. In the current structure, that means
10when creating the reserved blocks, it could parse over the block list
11many thousands of time on a large filesystem. For an 800MB filesystem,
12that took 2/3rds of the time.
13
14So create a structure for holding the inode position and use it to
15know where the end is. This neatens things up a bit, too, more
16clearly showing when a truncate or extend is occuring. In future
17changes, this will also make it efficient for supporting very large
18files that cannot be fully allocated in memory.
19---
20 genext2fs.c | 147 ++++++++++++++++++++++++++++++++++++++++-------------------
21 1 files changed, 100 insertions(+), 47 deletions(-)
22
23diff --git a/genext2fs.c b/genext2fs.c
24index 46c9605..e45e520 100644
25--- a/genext2fs.c
26+++ b/genext2fs.c
27@@ -436,6 +436,17 @@ swab32(uint32 val)
28 ((val<<8)&0xFF0000) | (val<<24));
29 }
30
31+static inline int
32+is_blk_empty(uint8 *b)
33+{
34+ uint32 i;
35+ uint32 *v = (uint32 *) b;
36+
37+ for(i = 0; i < BLOCKSIZE / 4; i++)
38+ if (*v++)
39+ return 0;
40+ return 1;
41+}
42
43 // on-disk structures
44 // this trick makes me declare things only once
45@@ -1165,7 +1176,6 @@ init_bw(blockwalker *bw)
46 // used after being freed, so once you start
47 // freeing blocks don't stop until the end of
48 // the file. moreover, i_blocks isn't updated.
49-// in fact, don't do that, just use extend_blk
50 // if hole!=0, create a hole in the file
51 static uint32
52 walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
53@@ -1422,52 +1432,80 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
54 return bk;
55 }
56
57-// add blocks to an inode (file/dir/etc...)
58-static void
59-extend_blk(filesystem *fs, uint32 nod, block b, int amount)
60+typedef struct
61 {
62- int create = amount;
63- blockwalker bw, lbw;
64- uint32 bk;
65+ blockwalker bw;
66+ uint32 nod;
67 nod_info *ni;
68 inode *inod;
69+} inode_pos;
70+#define INODE_POS_TRUNCATE 0
71+#define INODE_POS_EXTEND 1
72+
73+// Call this to set up an ipos structure for future use with
74+// extend_inode_blk to append blocks to the given inode. If
75+// op is INODE_POS_TRUNCATE, the inode is truncated to zero size.
76+// If op is INODE_POS_EXTEND, the position is moved to the end
77+// of the inode's data blocks.
78+// Call inode_pos_finish when done with the inode_pos structure.
79+static void
80+inode_pos_init(filesystem *fs, inode_pos *ipos, uint32 nod, int op,
81+ blockwalker *endbw)
82+{
83+ blockwalker lbw;
84
85- inod = get_nod(fs, nod, &ni);
86- init_bw(&bw);
87- if(amount < 0)
88- {
89- uint32 i;
90- for(i = 0; i < inod->i_blocks / INOBLK + amount; i++)
91- walk_bw(fs, nod, &bw, 0, 0);
92- while(walk_bw(fs, nod, &bw, &create, 0) != WALK_END)
93+ init_bw(&ipos->bw);
94+ ipos->nod = nod;
95+ ipos->inod = get_nod(fs, nod, &ipos->ni);
96+ if (op == INODE_POS_TRUNCATE) {
97+ int32 create = -1;
98+ while(walk_bw(fs, nod, &ipos->bw, &create, 0) != WALK_END)
99 /*nop*/;
100- inod->i_blocks += amount * INOBLK;
101+ ipos->inod->i_blocks = 0;
102 }
103- else
104+
105+ if (endbw)
106+ ipos->bw = *endbw;
107+ else {
108+ /* Seek to the end */
109+ init_bw(&ipos->bw);
110+ lbw = ipos->bw;
111+ while(walk_bw(fs, nod, &ipos->bw, 0, 0) != WALK_END)
112+ lbw = ipos->bw;
113+ ipos->bw = lbw;
114+ }
115+}
116+
117+// Clean up the inode_pos structure.
118+static void
119+inode_pos_finish(filesystem *fs, inode_pos *ipos)
120+{
121+ put_nod(ipos->ni);
122+}
123+
124+// add blocks to an inode (file/dir/etc...) at the given position.
125+// This will only work when appending to the end of an inode.
126+static void
127+extend_inode_blk(filesystem *fs, inode_pos *ipos, block b, int amount)
128+{
129+ uint32 bk;
130+ uint32 pos;
131+
132+ if (amount < 0)
133+ error_msg_and_die("extend_inode_blk: Got negative amount");
134+
135+ for (pos = 0; amount; pos += BLOCKSIZE)
136 {
137- lbw = bw;
138- while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
139- lbw = bw;
140- bw = lbw;
141- while(create)
142- {
143- int i, copyb = 0;
144- if(!(fs->sb->s_reserved[200] & OP_HOLES))
145- copyb = 1;
146- else
147- for(i = 0; i < BLOCKSIZE / 4; i++)
148- if(((int32*)(b + BLOCKSIZE * (amount - create)))[i])
149- {
150- copyb = 1;
151- break;
152- }
153- if((bk = walk_bw(fs, nod, &bw, &create, !copyb)) == WALK_END)
154- break;
155- if(copyb) {
156- blk_info *bi;
157- memcpy(get_blk(fs, bk, &bi), b + BLOCKSIZE * (amount - create - 1), BLOCKSIZE);
158- put_blk(bi);
159- }
160+ int hole = ((fs->sb->s_reserved[200] & OP_HOLES) && is_blk_empty(b + pos));
161+
162+ bk = walk_bw(fs, ipos->nod, &ipos->bw, &amount, hole);
163+ if (bk == WALK_END)
164+ error_msg_and_die("extend_inode_blk: extend failed");
165+ if (!hole) {
166+ blk_info *bi;
167+ uint8 *block = get_blk(fs, bk, &bi);
168+ memcpy(block, b + pos, BLOCKSIZE);
169+ put_blk(bi);
170 }
171 }
172 }
173@@ -1484,6 +1522,7 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
174 inode *node;
175 inode *pnode;
176 nod_info *dni, *ni;
177+ inode_pos ipos;
178
179 pnode = get_nod(fs, dnod, &dni);
180 if((pnode->i_mode & FM_IFMT) != FM_IFDIR)
181@@ -1534,7 +1573,11 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
182 node->i_links_count++;
183 put_nod(ni);
184 next_dir(&dw); // Force the data into the buffer
185- extend_blk(fs, dnod, dir_data(&dw), 1);
186+
187+ inode_pos_init(fs, &ipos, dnod, INODE_POS_EXTEND, &lbw);
188+ extend_inode_blk(fs, &ipos, dir_data(&dw), 1);
189+ inode_pos_finish(fs, &ipos);
190+
191 put_dir(&dw);
192 pnode->i_size += BLOCKSIZE;
193 out:
194@@ -1654,8 +1697,9 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint
195 uint32 nod = mknod_fs(fs, parent_nod, name, FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO, uid, gid, 0, 0, ctime, mtime);
196 nod_info *ni;
197 inode *node = get_nod(fs, nod, &ni);
198+ inode_pos ipos;
199
200- extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK);
201+ inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL);
202 node->i_size = size;
203 if(size <= 4 * (EXT2_TIND_BLOCK+1))
204 {
205@@ -1663,7 +1707,8 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint
206 put_nod(ni);
207 return nod;
208 }
209- extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
210+ extend_inode_blk(fs, &ipos, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
211+ inode_pos_finish(fs, &ipos);
212 put_nod(ni);
213 return nod;
214 }
215@@ -1676,8 +1721,9 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size
216 uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime);
217 nod_info *ni;
218 inode *node = get_nod(fs, nod, &ni);
219+ inode_pos ipos;
220
221- extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK);
222+ inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL);
223 node->i_size = size;
224 if (size) {
225 if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1)))
226@@ -1685,9 +1731,11 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size
227 if(f)
228 if (fread(b, size, 1, f) != 1) // FIXME: ugly. use mmap() ...
229 error_msg_and_die("fread failed");
230- extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
231+ extend_inode_blk(fs, &ipos, b,
232+ rndup(size, BLOCKSIZE) / BLOCKSIZE);
233 free(b);
234 }
235+ inode_pos_finish(fs, &ipos);
236 put_nod(ni);
237 return nod;
238 }
239@@ -2210,6 +2258,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
240 inode *itab0;
241 blk_info *bi;
242 nod_info *ni;
243+ inode_pos ipos;
244
245 if(nbresrvd < 0)
246 error_msg_and_die("reserved blocks value is invalid. Note: options have changed, see --help or the man page.");
247@@ -2337,7 +2386,9 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
248 new_dir(fs, EXT2_ROOT_INO, ".", 1, &dw);
249 shrink_dir(&dw, EXT2_ROOT_INO, "..", 2);
250 next_dir(&dw); // Force the data into the buffer
251- extend_blk(fs, EXT2_ROOT_INO, dir_data(&dw), 1);
252+ inode_pos_init(fs, &ipos, EXT2_ROOT_INO, INODE_POS_EXTEND, NULL);
253+ extend_inode_blk(fs, &ipos, dir_data(&dw), 1);
254+ inode_pos_finish(fs, &ipos);
255 put_dir(&dw);
256
257 // make lost+found directory and reserve blocks
258@@ -2355,8 +2406,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
259 */
260 if (fs->sb->s_r_blocks_count > fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS )
261 fs->sb->s_r_blocks_count = fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS;
262+ inode_pos_init(fs, &ipos, nod, INODE_POS_EXTEND, NULL);
263 for(i = 1; i < fs->sb->s_r_blocks_count; i++)
264- extend_blk(fs, nod, b, 1);
265+ extend_inode_blk(fs, &ipos, b, 1);
266+ inode_pos_finish(fs, &ipos);
267 free_workblk(b);
268 node = get_nod(fs, nod, &ni);
269 node->i_size = fs->sb->s_r_blocks_count * BLOCKSIZE;
270--
2711.7.4.1
272
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0007-Move-hdlinks-into-the-filesystem-structure.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0007-Move-hdlinks-into-the-filesystem-structure.patch
new file mode 100644
index 0000000000..52215c8e7a
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0007-Move-hdlinks-into-the-filesystem-structure.patch
@@ -0,0 +1,175 @@
1Upstream-Status: inappropriate
2
3From 1ea2332c6cec1fb979a7cb4502360005bed50da4 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sun, 5 Jun 2011 14:08:02 -0500
6Subject: [PATCH 07/19] Move hdlinks into the filesystem structure.
7
8Since the hard links structures are associated with a filesystem, put
9them in the filesystem structure since it can hold other stuff now.
10---
11 genext2fs.c | 71 +++++++++++++++++++++++++++++++---------------------------
12 1 files changed, 38 insertions(+), 33 deletions(-)
13
14diff --git a/genext2fs.c b/genext2fs.c
15index e45e520..d130362 100644
16--- a/genext2fs.c
17+++ b/genext2fs.c
18@@ -583,6 +583,18 @@ typedef struct
19 uint32 bptind;
20 } blockwalker;
21
22+#define HDLINK_CNT 16
23+struct hdlink_s
24+{
25+ uint32 src_inode;
26+ uint32 dst_nod;
27+};
28+
29+struct hdlinks_s
30+{
31+ int32 count;
32+ struct hdlink_s *hdl;
33+};
34
35 /* Filesystem structure that support groups */
36 #if BLOCKSIZE == 1024
37@@ -592,6 +604,8 @@ typedef struct
38 superblock *sb;
39 groupdescriptor *gd;
40 uint32 nheadblocks;
41+ int32 hdlink_cnt;
42+ struct hdlinks_s hdlinks;
43 } filesystem;
44 #else
45 #error UNHANDLED BLOCKSIZE
46@@ -615,22 +629,6 @@ typedef struct
47 #define udecl32(x) this->x = swab32(this->x);
48 #define utdecl32(x,n) { int i; for(i=0; i<n; i++) this->x[i] = swab32(this->x[i]); }
49
50-#define HDLINK_CNT 16
51-static int32 hdlink_cnt = HDLINK_CNT;
52-struct hdlink_s
53-{
54- uint32 src_inode;
55- uint32 dst_nod;
56-};
57-
58-struct hdlinks_s
59-{
60- int32 count;
61- struct hdlink_s *hdl;
62-};
63-
64-static struct hdlinks_s hdlinks;
65-
66 static void
67 swap_sb(superblock *sb)
68 {
69@@ -787,12 +785,12 @@ xreadlink(const char *path)
70 }
71
72 int
73-is_hardlink(ino_t inode)
74+is_hardlink(filesystem *fs, ino_t inode)
75 {
76 int i;
77
78- for(i = 0; i < hdlinks.count; i++) {
79- if(hdlinks.hdl[i].src_inode == inode)
80+ for(i = 0; i < fs->hdlinks.count; i++) {
81+ if(fs->hdlinks.hdl[i].src_inode == inode)
82 return i;
83 }
84 return -1;
85@@ -1989,9 +1987,9 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per
86 save_nod = 0;
87 /* Check for hardlinks */
88 if (!S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode) && st.st_nlink > 1) {
89- int32 hdlink = is_hardlink(st.st_ino);
90+ int32 hdlink = is_hardlink(fs, st.st_ino);
91 if (hdlink >= 0) {
92- add2dir(fs, this_nod, hdlinks.hdl[hdlink].dst_nod, name);
93+ add2dir(fs, this_nod, fs->hdlinks.hdl[hdlink].dst_nod, name);
94 continue;
95 } else {
96 save_nod = 1;
97@@ -2035,17 +2033,17 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per
98 error_msg("ignoring entry %s", name);
99 }
100 if (save_nod) {
101- if (hdlinks.count == hdlink_cnt) {
102- if ((hdlinks.hdl =
103- realloc (hdlinks.hdl, (hdlink_cnt + HDLINK_CNT) *
104+ if (fs->hdlinks.count == fs->hdlink_cnt) {
105+ if ((fs->hdlinks.hdl =
106+ realloc (fs->hdlinks.hdl, (fs->hdlink_cnt + HDLINK_CNT) *
107 sizeof (struct hdlink_s))) == NULL) {
108 error_msg_and_die("Not enough memory");
109 }
110- hdlink_cnt += HDLINK_CNT;
111+ fs->hdlink_cnt += HDLINK_CNT;
112 }
113- hdlinks.hdl[hdlinks.count].src_inode = st.st_ino;
114- hdlinks.hdl[hdlinks.count].dst_nod = nod;
115- hdlinks.count++;
116+ fs->hdlinks.hdl[fs->hdlinks.count].src_inode = st.st_ino;
117+ fs->hdlinks.hdl[fs->hdlinks.count].dst_nod = nod;
118+ fs->hdlinks.count++;
119 }
120 }
121 }
122@@ -2300,6 +2298,11 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
123 / BLOCKSIZE);
124 if(!(fs->data = calloc(nbblocks, BLOCKSIZE)))
125 error_msg_and_die("not enough memory for filesystem");
126+ fs->hdlink_cnt = HDLINK_CNT;
127+ fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt);
128+ if (!fs->hdlinks.hdl)
129+ error_msg_and_die("Not enough memory");
130+ fs->hdlinks.count = 0 ;
131 fs->sb = (superblock *) (fs->data + BLOCKSIZE);
132 fs->gd = (groupdescriptor *) (fs->sb + 1);
133
134@@ -2442,12 +2445,18 @@ load_fs(FILE * fh, int swapit)
135 fs = malloc(sizeof(*fs));
136 if (!fs)
137 error_msg_and_die("not enough memory for filesystem");
138+ fs->hdlink_cnt = HDLINK_CNT;
139+ fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt);
140+ if (!fs->hdlinks.hdl)
141+ error_msg_and_die("Not enough memory");
142+ fs->hdlinks.count = 0 ;
143 if(!(fs->data = calloc(fssize, BLOCKSIZE)))
144 error_msg_and_die("not enough memory for filesystem");
145 if(fread(fs->data, BLOCKSIZE, fssize, fh) != fssize)
146 perror_msg_and_die("input filesystem image");
147 fs->sb = (superblock *) (fs->data + BLOCKSIZE);
148 fs->gd = (groupdescriptor *) (fs->sb + 1);
149+
150 if(swapit)
151 swap_badfs(fs);
152 if(fs->sb->s_rev_level || (fs->sb->s_magic != EXT2_MAGIC_NUMBER))
153@@ -2461,6 +2470,7 @@ load_fs(FILE * fh, int swapit)
154 static void
155 free_fs(filesystem *fs)
156 {
157+ free(fs->hdlinks.hdl);
158 free(fs->data);
159 free(fs);
160 }
161@@ -2964,11 +2974,6 @@ main(int argc, char **argv)
162 error_msg_and_die("Not enough arguments. Try --help or else see the man page.");
163 fsout = argv[optind];
164
165- hdlinks.hdl = (struct hdlink_s *)malloc(hdlink_cnt * sizeof(struct hdlink_s));
166- if (!hdlinks.hdl)
167- error_msg_and_die("Not enough memory");
168- hdlinks.count = 0 ;
169-
170 if(fsin)
171 {
172 if(strcmp(fsin, "-"))
173--
1741.7.4.1
175
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0008-Separate-out-the-creation-of-the-filesystem-structur.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0008-Separate-out-the-creation-of-the-filesystem-structur.patch
new file mode 100644
index 0000000000..25adeb63c0
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0008-Separate-out-the-creation-of-the-filesystem-structur.patch
@@ -0,0 +1,95 @@
1Upstream-Status: inappropriate
2
3From 797e8548e5857b7a0586b27a9bdcadbea1561d8d Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sun, 5 Jun 2011 14:53:57 -0500
6Subject: [PATCH 08/19] Separate out the creation of the filesystem structure.
7
8Consolidate some processing that occurs when allocating a filesystem
9structure.
10---
11 genext2fs.c | 49 +++++++++++++++++++++++++------------------------
12 1 files changed, 25 insertions(+), 24 deletions(-)
13
14diff --git a/genext2fs.c b/genext2fs.c
15index d130362..497c9af 100644
16--- a/genext2fs.c
17+++ b/genext2fs.c
18@@ -2240,6 +2240,29 @@ swap_badfs(filesystem *fs)
19 }
20 }
21
22+// Allocate a new filesystem structure, allocate internal memory,
23+// and initialize the contents.
24+static filesystem *
25+alloc_fs(uint32 nbblocks)
26+{
27+ filesystem *fs;
28+
29+ fs = malloc(sizeof(*fs));
30+ if (!fs)
31+ error_msg_and_die("not enough memory for filesystem");
32+ memset(fs, 0, sizeof(*fs));
33+ if(!(fs->data = calloc(nbblocks, BLOCKSIZE)))
34+ error_msg_and_die("not enough memory for filesystem");
35+ fs->hdlink_cnt = HDLINK_CNT;
36+ fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt);
37+ if (!fs->hdlinks.hdl)
38+ error_msg_and_die("Not enough memory");
39+ fs->hdlinks.count = 0 ;
40+ fs->sb = (superblock *) (fs->data + BLOCKSIZE);
41+ fs->gd = (groupdescriptor *) (fs->sb + 1);
42+ return fs;
43+}
44+
45 // initialize an empty filesystem
46 static filesystem *
47 init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp)
48@@ -2290,21 +2313,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
49 free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/;
50 free_blocks_per_group = nbblocks_per_group - overhead_per_group;
51
52- fs = malloc(sizeof(*fs));
53- if (!fs)
54- error_msg_and_die("not enough memory for filesystem");
55+ fs = alloc_fs(nbblocks);
56 fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor))
57 + sizeof(superblock) + (BLOCKSIZE - 1))
58 / BLOCKSIZE);
59- if(!(fs->data = calloc(nbblocks, BLOCKSIZE)))
60- error_msg_and_die("not enough memory for filesystem");
61- fs->hdlink_cnt = HDLINK_CNT;
62- fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt);
63- if (!fs->hdlinks.hdl)
64- error_msg_and_die("Not enough memory");
65- fs->hdlinks.count = 0 ;
66- fs->sb = (superblock *) (fs->data + BLOCKSIZE);
67- fs->gd = (groupdescriptor *) (fs->sb + 1);
68
69 // create the superblock for an empty filesystem
70 fs->sb->s_inodes_count = nbinodes_per_group * nbgroups;
71@@ -2442,20 +2454,9 @@ load_fs(FILE * fh, int swapit)
72 fssize = (fssize + BLOCKSIZE - 1) / BLOCKSIZE;
73 if(fssize < 16) // totally arbitrary
74 error_msg_and_die("too small filesystem");
75- fs = malloc(sizeof(*fs));
76- if (!fs)
77- error_msg_and_die("not enough memory for filesystem");
78- fs->hdlink_cnt = HDLINK_CNT;
79- fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt);
80- if (!fs->hdlinks.hdl)
81- error_msg_and_die("Not enough memory");
82- fs->hdlinks.count = 0 ;
83- if(!(fs->data = calloc(fssize, BLOCKSIZE)))
84- error_msg_and_die("not enough memory for filesystem");
85+ fs = alloc_fs(fssize);
86 if(fread(fs->data, BLOCKSIZE, fssize, fh) != fssize)
87 perror_msg_and_die("input filesystem image");
88- fs->sb = (superblock *) (fs->data + BLOCKSIZE);
89- fs->gd = (groupdescriptor *) (fs->sb + 1);
90
91 if(swapit)
92 swap_badfs(fs);
93--
941.7.4.1
95
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
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0010-Convert-over-to-keeping-the-filesystem-on-disk.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0010-Convert-over-to-keeping-the-filesystem-on-disk.patch
new file mode 100644
index 0000000000..79e82c8c73
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0010-Convert-over-to-keeping-the-filesystem-on-disk.patch
@@ -0,0 +1,839 @@
1Upstream-Status: inappropriate
2
3From 29a36b0b91ee009ee4219934c7a70278b1361834 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sun, 5 Jun 2011 15:24:57 -0500
6Subject: [PATCH 10/19] Convert over to keeping the filesystem on disk
7
8This makes the actual filesystem be on disk and not in memory. It
9adds caching of the filesystem data to help keep oft-accessed blocks
10in memory and byteswapped.
11---
12 cache.h | 128 ++++++++++++++++++++
13 genext2fs.c | 377 +++++++++++++++++++++++++++++++++++++++++++++++++----------
14 list.h | 78 ++++++++++++
15 3 files changed, 521 insertions(+), 62 deletions(-)
16 create mode 100644 cache.h
17 create mode 100644 list.h
18
19diff --git a/cache.h b/cache.h
20new file mode 100644
21index 0000000..5275be6
22--- /dev/null
23+++ b/cache.h
24@@ -0,0 +1,128 @@
25+#ifndef __CACHE_H__
26+#define __CACHE_H__
27+
28+#include "list.h"
29+
30+#define CACHE_LISTS 256
31+
32+typedef struct
33+{
34+ list_elem link;
35+ list_elem lru_link;
36+} cache_link;
37+
38+typedef struct
39+{
40+ /* LRU list holds unused items */
41+ unsigned int lru_entries;
42+ list_elem lru_list;
43+ unsigned int max_free_entries;
44+
45+ unsigned int entries;
46+ list_elem lists[CACHE_LISTS];
47+ unsigned int (*elem_val)(cache_link *elem);
48+ void (*freed)(cache_link *elem);
49+} listcache;
50+
51+static inline void
52+cache_add(listcache *c, cache_link *elem)
53+{
54+ unsigned int hash = c->elem_val(elem) % CACHE_LISTS;
55+ int delcount = c->lru_entries - c->max_free_entries;
56+
57+ if (delcount > 0) {
58+ /* Delete some unused items. */
59+ list_elem *lru, *next;
60+ cache_link *l;
61+ list_for_each_elem_safe(&c->lru_list, lru, next) {
62+ l = container_of(lru, cache_link, lru_link);
63+ list_del(lru);
64+ list_del(&l->link);
65+ c->entries--;
66+ c->lru_entries--;
67+ c->freed(l);
68+ delcount--;
69+ if (delcount <= 0)
70+ break;
71+ }
72+ }
73+
74+ c->entries++;
75+ list_item_init(&elem->lru_link); /* Mark it not in the LRU list */
76+ list_add_after(&c->lists[hash], &elem->link);
77+}
78+
79+static inline void
80+cache_item_set_unused(listcache *c, cache_link *elem)
81+{
82+ list_add_before(&c->lru_list, &elem->lru_link);
83+ c->lru_entries++;
84+}
85+
86+static inline cache_link *
87+cache_find(listcache *c, unsigned int val)
88+{
89+ unsigned int hash = val % CACHE_LISTS;
90+ list_elem *elem;
91+
92+ list_for_each_elem(&c->lists[hash], elem) {
93+ cache_link *l = container_of(elem, cache_link, link);
94+ if (c->elem_val(l) == val) {
95+ if (!list_empty(&l->lru_link)) {
96+ /* It's in the unused list, remove it. */
97+ list_del(&l->lru_link);
98+ list_item_init(&l->lru_link);
99+ c->lru_entries--;
100+ }
101+ return l;
102+ }
103+ }
104+ return NULL;
105+}
106+
107+static inline int
108+cache_flush(listcache *c)
109+{
110+ list_elem *elem, *next;
111+ cache_link *l;
112+ int i;
113+
114+ list_for_each_elem_safe(&c->lru_list, elem, next) {
115+ l = container_of(elem, cache_link, lru_link);
116+ list_del(elem);
117+ list_del(&l->link);
118+ c->entries--;
119+ c->lru_entries--;
120+ c->freed(l);
121+ }
122+
123+ for (i = 0; i < CACHE_LISTS; i++) {
124+ list_for_each_elem_safe(&c->lists[i], elem, next) {
125+ l = container_of(elem, cache_link, link);
126+ list_del(&l->link);
127+ c->entries--;
128+ c->freed(l);
129+ }
130+ }
131+
132+ return c->entries || c->lru_entries;
133+}
134+
135+static inline void
136+cache_init(listcache *c, unsigned int max_free_entries,
137+ unsigned int (*elem_val)(cache_link *elem),
138+ void (*freed)(cache_link *elem))
139+{
140+ int i;
141+
142+ c->entries = 0;
143+ c->lru_entries = 0;
144+ c->max_free_entries = max_free_entries;
145+ list_init(&c->lru_list);
146+ for (i = 0; i < CACHE_LISTS; i++)
147+ list_init(&c->lists[i]);
148+ c->elem_val = elem_val;
149+ c->freed = freed;
150+}
151+
152+#endif /* __CACHE_H__ */
153diff --git a/genext2fs.c b/genext2fs.c
154index 51403a2..f79438d 100644
155--- a/genext2fs.c
156+++ b/genext2fs.c
157@@ -142,6 +142,8 @@
158 # include <limits.h>
159 #endif
160
161+#include "cache.h"
162+
163 struct stats {
164 unsigned long nblocks;
165 unsigned long ninodes;
166@@ -600,6 +602,7 @@ struct hdlinks_s
167 #if BLOCKSIZE == 1024
168 typedef struct
169 {
170+ FILE *f;
171 uint8 *data;
172 superblock *sb;
173 groupdescriptor *gd;
174@@ -607,6 +610,10 @@ typedef struct
175 int swapit;
176 int32 hdlink_cnt;
177 struct hdlinks_s hdlinks;
178+
179+ listcache blks;
180+ listcache inodes;
181+ listcache blkmaps;
182 } filesystem;
183 #else
184 #error UNHANDLED BLOCKSIZE
185@@ -848,45 +855,150 @@ allocated(block b, uint32 item)
186 // by the user.
187 typedef struct
188 {
189- int dummy;
190+ cache_link link;
191+
192+ filesystem *fs;
193+ uint32 blk;
194+ uint8 *b;
195+ uint32 usecount;
196 } blk_info;
197
198+#define MAX_FREE_CACHE_BLOCKS 100
199+
200+static uint32
201+blk_elem_val(cache_link *elem)
202+{
203+ blk_info *bi = container_of(elem, blk_info, link);
204+ return bi->blk;
205+}
206+
207+static void
208+blk_freed(cache_link *elem)
209+{
210+ blk_info *bi = container_of(elem, blk_info, link);
211+
212+ if (fseeko(bi->fs->f, ((off_t) bi->blk) * BLOCKSIZE, SEEK_SET))
213+ perror_msg_and_die("fseek");
214+ if (fwrite(bi->b, BLOCKSIZE, 1, bi->fs->f) != 1)
215+ perror_msg_and_die("get_blk: write");
216+ free(bi->b);
217+ free(bi);
218+}
219+
220 // Return a given block from a filesystem. Make sure to call
221 // put_blk when you are done with it.
222 static inline uint8 *
223 get_blk(filesystem *fs, uint32 blk, blk_info **rbi)
224 {
225- return fs->data + blk*BLOCKSIZE;
226+ cache_link *curr;
227+ blk_info *bi;
228+
229+ if (blk < fs->nheadblocks)
230+ error_msg_and_die("Internal error, request for head block");
231+ if (blk >= fs->sb->s_blocks_count)
232+ error_msg_and_die("Internal error, block out of range");
233+
234+ curr = cache_find(&fs->blks, blk);
235+ if (curr) {
236+ bi = container_of(curr, blk_info, link);
237+ bi->usecount++;
238+ goto out;
239+ }
240+
241+ bi = malloc(sizeof(*bi));
242+ if (!bi)
243+ error_msg_and_die("get_blk: out of memory");
244+ bi->fs = fs;
245+ bi->blk = blk;
246+ bi->usecount = 1;
247+ bi->b = malloc(BLOCKSIZE);
248+ if (!bi->b)
249+ error_msg_and_die("get_blk: out of memory");
250+ cache_add(&fs->blks, &bi->link);
251+ if (fseeko(fs->f, ((off_t) blk) * BLOCKSIZE, SEEK_SET))
252+ perror_msg_and_die("fseek");
253+ if (fread(bi->b, BLOCKSIZE, 1, fs->f) != 1) {
254+ if (ferror(fs->f))
255+ perror_msg_and_die("fread");
256+ memset(bi->b, 0, BLOCKSIZE);
257+ }
258+
259+out:
260+ *rbi = bi;
261+ return bi->b;
262 }
263
264 static inline void
265 put_blk(blk_info *bi)
266 {
267+ if (bi->usecount == 0)
268+ error_msg_and_die("Internal error: put_blk usecount zero");
269+ bi->usecount--;
270+ if (bi->usecount == 0)
271+ /* Free happens in the cache code */
272+ cache_item_set_unused(&bi->fs->blks, &bi->link);
273 }
274
275 // Used by get_blkmap/put_blkmap to hold information about an block map
276 // owned by the user.
277 typedef struct
278 {
279+ cache_link link;
280+
281 filesystem *fs;
282+ uint32 blk;
283 uint8 *b;
284 blk_info *bi;
285+ uint32 usecount;
286 } blkmap_info;
287
288+#define MAX_FREE_CACHE_BLOCKMAPS 100
289+
290+static uint32
291+blkmap_elem_val(cache_link *elem)
292+{
293+ blkmap_info *bmi = container_of(elem, blkmap_info, link);
294+ return bmi->blk;
295+}
296+
297+static void
298+blkmap_freed(cache_link *elem)
299+{
300+ blkmap_info *bmi = container_of(elem, blkmap_info, link);
301+
302+ if (bmi->fs->swapit)
303+ swap_block(bmi->b);
304+ put_blk(bmi->bi);
305+ free(bmi);
306+}
307+
308 // Return a given block map from a filesystem. Make sure to call
309 // put_blkmap when you are done with it.
310 static inline uint32 *
311 get_blkmap(filesystem *fs, uint32 blk, blkmap_info **rbmi)
312 {
313 blkmap_info *bmi;
314+ cache_link *curr;
315+
316+ curr = cache_find(&fs->blkmaps, blk);
317+ if (curr) {
318+ bmi = container_of(curr, blkmap_info, link);
319+ bmi->usecount++;
320+ goto out;
321+ }
322
323 bmi = malloc(sizeof(*bmi));
324 if (!bmi)
325 error_msg_and_die("get_blkmap: out of memory");
326 bmi->fs = fs;
327+ bmi->blk = blk;
328 bmi->b = get_blk(fs, blk, &bmi->bi);
329- if (bmi->fs->swapit)
330+ bmi->usecount = 1;
331+ cache_add(&fs->blkmaps, &bmi->link);
332+
333+ if (fs->swapit)
334 swap_block(bmi->b);
335+out:
336 *rbmi = bmi;
337 return (uint32 *) bmi->b;
338 }
339@@ -894,42 +1006,83 @@ get_blkmap(filesystem *fs, uint32 blk, blkmap_info **rbmi)
340 static inline void
341 put_blkmap(blkmap_info *bmi)
342 {
343- if (bmi->fs->swapit)
344- swap_block(bmi->b);
345- put_blk(bmi->bi);
346- free(bmi);
347+ if (bmi->usecount == 0)
348+ error_msg_and_die("Internal error: put_blkmap usecount zero");
349+
350+ bmi->usecount--;
351+ if (bmi->usecount == 0)
352+ /* Free happens in the cache code */
353+ cache_item_set_unused(&bmi->fs->blkmaps, &bmi->link);
354 }
355
356 // Used by get_nod/put_nod to hold information about an inode owned
357 // by the user.
358 typedef struct
359 {
360+ cache_link link;
361+
362 filesystem *fs;
363+ uint32 nod;
364+ uint8 *b;
365 blk_info *bi;
366 inode *itab;
367+ uint32 usecount;
368 } nod_info;
369
370+#define MAX_FREE_CACHE_INODES 100
371+
372+static uint32
373+inode_elem_val(cache_link *elem)
374+{
375+ nod_info *ni = container_of(elem, nod_info, link);
376+ return ni->nod;
377+}
378+
379+static void
380+inode_freed(cache_link *elem)
381+{
382+ nod_info *ni = container_of(elem, nod_info, link);
383+
384+ if (ni->fs->swapit)
385+ swap_nod(ni->itab);
386+ put_blk(ni->bi);
387+ free(ni);
388+}
389+
390 // Return a given inode from a filesystem. Make sure to call put_nod()
391 // when you are done with the inode.
392 static inline inode *
393 get_nod(filesystem *fs, uint32 nod, nod_info **rni)
394 {
395 int grp, offset, boffset;
396+ cache_link *curr;
397 nod_info *ni;
398- uint8 *b;
399
400- offset = GRP_IBM_OFFSET(fs,nod) - 1;
401- boffset = offset / (BLOCKSIZE / sizeof(inode));
402- offset %= BLOCKSIZE / sizeof(inode);
403- grp = GRP_GROUP_OF_INODE(fs,nod);
404+ curr = cache_find(&fs->inodes, nod);
405+ if (curr) {
406+ ni = container_of(curr, nod_info, link);
407+ ni->usecount++;
408+ goto out;
409+ }
410+
411 ni = malloc(sizeof(*ni));
412 if (!ni)
413 error_msg_and_die("get_nod: out of memory");
414 ni->fs = fs;
415- b = get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi);
416- ni->itab = ((inode *) b) + offset;
417+ ni->nod = nod;
418+ ni->usecount = 1;
419+ cache_add(&fs->inodes, &ni->link);
420+
421+ offset = GRP_IBM_OFFSET(fs, nod) - 1;
422+ boffset = offset / (BLOCKSIZE / sizeof(inode));
423+ offset %= BLOCKSIZE / sizeof(inode);
424+ grp = GRP_GROUP_OF_INODE(fs,nod);
425+ ni->b = get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi);
426+ ni->itab = ((inode *) ni->b) + offset;
427 if (fs->swapit)
428 swap_nod(ni->itab);
429+
430+out:
431 *rni = ni;
432 return ni->itab;
433 }
434@@ -937,10 +1090,13 @@ get_nod(filesystem *fs, uint32 nod, nod_info **rni)
435 static inline void
436 put_nod(nod_info *ni)
437 {
438- if (ni->fs->swapit)
439- swap_nod(ni->itab);
440- put_blk(ni->bi);
441- free(ni);
442+ if (ni->usecount == 0)
443+ error_msg_and_die("Internal error: put_nod usecount zero");
444+
445+ ni->usecount--;
446+ if (ni->usecount == 0)
447+ /* Free happens in the cache code */
448+ cache_item_set_unused(&ni->fs->inodes, &ni->link);
449 }
450
451 // Used to hold state information while walking a directory inode.
452@@ -2090,40 +2246,61 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per
453 closedir(dh);
454 }
455
456-// endianness swap of the whole filesystem
457 static void
458-swap_goodfs(filesystem *fs)
459+swap_gds(filesystem *fs)
460 {
461 uint32 i;
462-
463 for(i=0;i<GRP_NBGROUPS(fs);i++)
464 swap_gd(&(fs->gd[i]));
465- swap_sb(fs->sb);
466 }
467
468+// Copy size blocks from src to dst, putting holes in the output
469+// file (if possible) if the input block is all zeros.
470 static void
471-swap_badfs(filesystem *fs)
472+copy_file(filesystem *fs, FILE *dst, FILE *src, size_t size)
473 {
474- uint32 i;
475- swap_sb(fs->sb);
476- for(i=0;i<GRP_NBGROUPS(fs);i++)
477- swap_gd(&(fs->gd[i]));
478+ uint8 *b;
479+
480+ b = malloc(BLOCKSIZE);
481+ if (!b)
482+ error_msg_and_die("copy_file: out of memory");
483+ if (fseek(src, 0, SEEK_SET))
484+ perror_msg_and_die("fseek");
485+ if (ftruncate(fileno(dst), 0))
486+ perror_msg_and_die("copy_file: ftruncate");
487+ while (size > 0) {
488+ if (fread(b, BLOCKSIZE, 1, src) != 1)
489+ perror_msg_and_die("copy failed on read");
490+ if ((dst != stdout) && is_blk_empty(b)) {
491+ /* Empty block, just skip it */
492+ if (fseek(dst, BLOCKSIZE, SEEK_CUR))
493+ perror_msg_and_die("fseek");
494+ } else {
495+ if (fwrite(b, BLOCKSIZE, 1, dst) != 1)
496+ perror_msg_and_die("copy failed on write");
497+ }
498+ size --;
499+ }
500 }
501
502 // Allocate a new filesystem structure, allocate internal memory,
503 // and initialize the contents.
504 static filesystem *
505-alloc_fs(uint32 nbblocks, int swapit)
506+alloc_fs(int swapit, char *fname, uint32 nbblocks, FILE *srcfile)
507 {
508 filesystem *fs;
509+ struct stat srcstat, dststat;
510
511 fs = malloc(sizeof(*fs));
512 if (!fs)
513 error_msg_and_die("not enough memory for filesystem");
514 memset(fs, 0, sizeof(*fs));
515 fs->swapit = swapit;
516- if(!(fs->data = calloc(nbblocks, BLOCKSIZE)))
517- error_msg_and_die("not enough memory for filesystem");
518+ cache_init(&fs->blks, MAX_FREE_CACHE_BLOCKS, blk_elem_val, blk_freed);
519+ cache_init(&fs->blkmaps, MAX_FREE_CACHE_BLOCKMAPS,
520+ blkmap_elem_val, blkmap_freed);
521+ cache_init(&fs->inodes, MAX_FREE_CACHE_INODES,
522+ inode_elem_val, inode_freed);
523 fs->hdlink_cnt = HDLINK_CNT;
524 fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt);
525 if (!fs->hdlinks.hdl)
526@@ -2131,12 +2308,44 @@ alloc_fs(uint32 nbblocks, int swapit)
527 fs->hdlinks.count = 0 ;
528 fs->sb = (superblock *) (fs->data + BLOCKSIZE);
529 fs->gd = (groupdescriptor *) (fs->sb + 1);
530+
531+ if (strcmp(fname, "-") == 0)
532+ fs->f = tmpfile();
533+ else if (srcfile) {
534+ if (fstat(fileno(srcfile), &srcstat))
535+ perror_msg_and_die("fstat srcfile");
536+ if (stat(fname, &dststat))
537+ perror_msg_and_die("stat-ing %s", fname);
538+ if (srcstat.st_ino == dststat.st_ino) {
539+ // source and destination are the same file, don't
540+ // truncate or copy, just use the file.
541+ fs->f = fopen(fname, "r+b");
542+ } else {
543+ fs->f = fopen(fname, "w+b");
544+ if (fs->f)
545+ copy_file(fs, fs->f, srcfile,
546+ nbblocks * BLOCKSIZE);
547+ }
548+ } else
549+ fs->f = fopen(fname, "w+b");
550+ if (!fs->f)
551+ perror_msg_and_die("opening %s", fname);
552 return fs;
553 }
554
555+/* Make sure the output file is the right size */
556+static void
557+set_file_size(filesystem *fs)
558+{
559+ if (ftruncate(fileno(fs->f),
560+ ((off_t) fs->sb->s_blocks_count) * BLOCKSIZE))
561+ perror_msg_and_die("set_file_size: ftruncate");
562+}
563+
564 // initialize an empty filesystem
565 static filesystem *
566-init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp, int swapit)
567+init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes,
568+ uint32 fs_timestamp, int swapit, char *fname)
569 {
570 uint32 i;
571 filesystem *fs;
572@@ -2184,10 +2393,16 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
573 free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/;
574 free_blocks_per_group = nbblocks_per_group - overhead_per_group;
575
576- fs = alloc_fs(nbblocks, swapit);
577+ fs = alloc_fs(swapit, fname, nbblocks, NULL);
578 fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor))
579 + sizeof(superblock) + (BLOCKSIZE - 1))
580 / BLOCKSIZE);
581+ fs->sb = (superblock *) malloc(BLOCKSIZE);
582+ if (!fs->sb)
583+ error_msg_and_die("error allocating header memory");
584+ fs->gd = (groupdescriptor *) calloc(fs->nheadblocks - 1, BLOCKSIZE);
585+ if (!fs->gd)
586+ error_msg_and_die("error allocating header memory");
587
588 // create the superblock for an empty filesystem
589 fs->sb->s_inodes_count = nbinodes_per_group * nbgroups;
590@@ -2205,6 +2420,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
591 fs->sb->s_magic = EXT2_MAGIC_NUMBER;
592 fs->sb->s_lastcheck = fs_timestamp;
593
594+ fs->sb->s_reserved[200] = 0;
595+
596+ set_file_size(fs);
597+
598 // set up groupdescriptors
599 for(i=0, bbmpos=gdsz+2, ibmpos=bbmpos+1, itblpos=ibmpos+1;
600 i<nbgroups;
601@@ -2315,27 +2534,49 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
602
603 // loads a filesystem from disk
604 static filesystem *
605-load_fs(FILE * fh, int swapit)
606+load_fs(FILE * fh, int swapit, char *fname)
607 {
608- size_t fssize;
609+ off_t fssize;
610 filesystem *fs;
611- if((fseek(fh, 0, SEEK_END) < 0) || ((ssize_t)(fssize = ftell(fh)) == -1))
612+
613+ if((fseek(fh, 0, SEEK_END) < 0) || ((fssize = ftello(fh)) == -1))
614 perror_msg_and_die("input filesystem image");
615 rewind(fh);
616- fssize = (fssize + BLOCKSIZE - 1) / BLOCKSIZE;
617+ if ((fssize % BLOCKSIZE) != 0)
618+ error_msg_and_die("Input file not a multiple of block size");
619+ fssize /= BLOCKSIZE;
620 if(fssize < 16) // totally arbitrary
621 error_msg_and_die("too small filesystem");
622- fs = alloc_fs(fssize, swapit);
623- if(fread(fs->data, BLOCKSIZE, fssize, fh) != fssize)
624- perror_msg_and_die("input filesystem image");
625-
626+ fs = alloc_fs(swapit, fname, fssize, fh);
627+
628+ /* Read and check the superblock, then read the superblock
629+ * and all the group descriptors */
630+ fs->sb = malloc(BLOCKSIZE);
631+ if (!fs->sb)
632+ error_msg_and_die("error allocating header memory");
633+ if (fseek(fs->f, BLOCKSIZE, SEEK_SET))
634+ perror_msg_and_die("fseek");
635+ if (fread(fs->sb, BLOCKSIZE, 1, fs->f) != 1)
636+ perror_msg_and_die("fread filesystem image superblock");
637 if(swapit)
638- swap_badfs(fs);
639+ swap_sb(fs->sb);
640 if(fs->sb->s_rev_level || (fs->sb->s_magic != EXT2_MAGIC_NUMBER))
641 error_msg_and_die("not a suitable ext2 filesystem");
642 fs->nheadblocks = (((GRP_NBGROUPS(fs) * sizeof(groupdescriptor))
643 + sizeof(superblock) + (BLOCKSIZE - 1))
644 / BLOCKSIZE);
645+
646+ fs->gd = calloc(fs->nheadblocks - 1, BLOCKSIZE);
647+ if (!fs->gd)
648+ error_msg_and_die("error allocating header memory");
649+ if (fread(fs->gd, BLOCKSIZE, fs->nheadblocks - 1, fs->f)
650+ != (fs->nheadblocks - 1))
651+ perror_msg_and_die("fread filesystem image group descriptors");
652+
653+ if(swapit)
654+ swap_gds(fs);
655+
656+ set_file_size(fs);
657 return fs;
658 }
659
660@@ -2343,7 +2584,9 @@ static void
661 free_fs(filesystem *fs)
662 {
663 free(fs->hdlinks.hdl);
664- free(fs->data);
665+ fclose(fs->f);
666+ free(fs->sb);
667+ free(fs->gd);
668 free(fs);
669 }
670
671@@ -2631,16 +2874,30 @@ print_fs(filesystem *fs)
672 }
673
674 static void
675-dump_fs(filesystem *fs, FILE * fh, int swapit)
676-{
677- uint32 nbblocks = fs->sb->s_blocks_count;
678+finish_fs(filesystem *fs)
679+{
680+ if (cache_flush(&fs->inodes))
681+ error_msg_and_die("entry mismatch on inode cache flush");
682+ if (cache_flush(&fs->blkmaps))
683+ error_msg_and_die("entry mismatch on blockmap cache flush");
684+ if (cache_flush(&fs->blks))
685+ error_msg_and_die("entry mismatch on block cache flush");
686 fs->sb->s_reserved[200] = 0;
687- if(swapit)
688- swap_goodfs(fs);
689- if(fwrite(fs->data, BLOCKSIZE, nbblocks, fh) < nbblocks)
690- perror_msg_and_die("output filesystem image");
691- if(swapit)
692- swap_badfs(fs);
693+ if(fs->swapit) {
694+ swap_sb(fs->sb);
695+ swap_gds(fs);
696+ }
697+ if (fseek(fs->f, BLOCKSIZE, SEEK_SET))
698+ perror_msg_and_die("fseek");
699+ if(fwrite(fs->sb, BLOCKSIZE, 1, fs->f) != 1)
700+ perror_msg_and_die("output filesystem superblock");
701+ if(fwrite(fs->gd, BLOCKSIZE, fs->nheadblocks - 1, fs->f)
702+ != (fs->nheadblocks - 1))
703+ perror_msg_and_die("output filesystem group descriptors");
704+ if(fs->swapit) {
705+ swap_sb(fs->sb);
706+ swap_gds(fs);
707+ }
708 }
709
710 static void
711@@ -2851,11 +3108,11 @@ main(int argc, char **argv)
712 if(strcmp(fsin, "-"))
713 {
714 FILE * fh = xfopen(fsin, "rb");
715- fs = load_fs(fh, bigendian);
716+ fs = load_fs(fh, bigendian, fsout);
717 fclose(fh);
718 }
719 else
720- fs = load_fs(stdin, bigendian);
721+ fs = load_fs(stdin, bigendian, fsout);
722 }
723 else
724 {
725@@ -2886,7 +3143,7 @@ main(int argc, char **argv)
726 if(fs_timestamp == -1)
727 fs_timestamp = time(NULL);
728 fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp,
729- bigendian);
730+ bigendian, fsout);
731 }
732
733 populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL);
734@@ -2925,14 +3182,10 @@ main(int argc, char **argv)
735 flist_blocks(fs, nod, fh);
736 fclose(fh);
737 }
738- if(strcmp(fsout, "-"))
739- {
740- FILE * fh = xfopen(fsout, "wb");
741- dump_fs(fs, fh, bigendian);
742- fclose(fh);
743- }
744- else
745- dump_fs(fs, stdout, bigendian);
746+ finish_fs(fs);
747+ if(strcmp(fsout, "-") == 0)
748+ copy_file(fs, stdout, fs->f, fs->sb->s_blocks_count);
749+
750 free_fs(fs);
751 return 0;
752 }
753diff --git a/list.h b/list.h
754new file mode 100644
755index 0000000..52bb181
756--- /dev/null
757+++ b/list.h
758@@ -0,0 +1,78 @@
759+#ifndef __LIST_H__
760+#define __LIST_H__
761+
762+#if STDC_HEADERS
763+# include <stdlib.h>
764+# include <stddef.h>
765+#else
766+# if HAVE_STDLIB_H
767+# include <stdlib.h>
768+# endif
769+# if HAVE_STDDEF_H
770+# include <stddef.h>
771+# endif
772+#endif
773+
774+#ifndef offsetof
775+#define offsetof(st, m) \
776+ ((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
777+#endif
778+
779+#define container_of(ptr, type, member) ({ \
780+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
781+ (type *)( (char *)__mptr - offsetof(type,member) );})
782+
783+typedef struct list_elem
784+{
785+ struct list_elem *next;
786+ struct list_elem *prev;
787+} list_elem;
788+
789+static inline void list_init(list_elem *list)
790+{
791+ list->next = list;
792+ list->prev = list;
793+}
794+
795+static inline void list_add_after(list_elem *pos, list_elem *elem)
796+{
797+ elem->next = pos->next;
798+ elem->prev = pos;
799+ pos->next->prev = elem;
800+ pos->next = elem;
801+}
802+
803+static inline void list_add_before(list_elem *pos, list_elem *elem)
804+{
805+ elem->prev = pos->prev;
806+ elem->next = pos;
807+ pos->prev->next = elem;
808+ pos->prev = elem;
809+}
810+
811+static inline void list_del(list_elem *elem)
812+{
813+ elem->next->prev = elem->prev;
814+ elem->prev->next = elem->next;
815+}
816+
817+static inline void list_item_init(list_elem *elem)
818+{
819+ elem->next = elem;
820+ elem->prev = elem;
821+}
822+
823+static inline int list_empty(list_elem *elem)
824+{
825+ return elem->next == elem;
826+}
827+
828+#define list_for_each_elem(list, curr) \
829+ for ((curr) = (list)->next; (curr) != (list); (curr) = (curr)->next)
830+
831+#define list_for_each_elem_safe(list, curr, next) \
832+ for ((curr) = (list)->next, (next) = (curr)->next; \
833+ (curr) != (list); \
834+ (curr) = (next), (next) = (curr)->next)
835+
836+#endif /* __LIST_H__ */
837--
8381.7.4.1
839
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0011-Copy-files-into-the-filesystem-a-piece-at-a-time.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0011-Copy-files-into-the-filesystem-a-piece-at-a-time.patch
new file mode 100644
index 0000000000..52dec56d5f
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0011-Copy-files-into-the-filesystem-a-piece-at-a-time.patch
@@ -0,0 +1,103 @@
1Upstream-Status: inappropriate
2
3From 0a7d5b11e62e54f88ce3a49d0c2327d537b3f531 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Sun, 5 Jun 2011 15:42:24 -0500
6Subject: [PATCH 11/19] Copy files into the filesystem a piece at a time
7
8Instead of malloc-ing and entire files-worth of memory, reading it in,
9and writing it to the filesystem, do it a piece at a time. This allows
10very large files to be supported.
11
12Also, use off_t and make it 64-bits so it supports filesystems and files
13larger than 2GB. Full support for >2GB files is not quite here, that
14requires rev 1 filesystem support, which is coming later.
15---
16 genext2fs.c | 35 +++++++++++++++++++++++------------
17 1 files changed, 23 insertions(+), 12 deletions(-)
18
19diff --git a/genext2fs.c b/genext2fs.c
20index f79438d..8a7f589 100644
21--- a/genext2fs.c
22+++ b/genext2fs.c
23@@ -53,6 +53,12 @@
24 // along with -q, -P, -U
25
26
27+/*
28+ * Allow fseeko/off_t to be 64-bit offsets to allow filesystems and
29+ * individual files >2GB.
30+ */
31+#define _FILE_OFFSET_BITS 64
32+
33 #include <config.h>
34 #include <stdio.h>
35
36@@ -603,7 +609,6 @@ struct hdlinks_s
37 typedef struct
38 {
39 FILE *f;
40- uint8 *data;
41 superblock *sb;
42 groupdescriptor *gd;
43 uint32 nheadblocks;
44@@ -1907,30 +1912,38 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint
45 return nod;
46 }
47
48+#define COPY_BLOCKS 16
49+#define CB_SIZE (COPY_BLOCKS * BLOCKSIZE)
50+
51 // make a file from a FILE*
52 static uint32
53-mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size_t size, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime)
54+mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_t size, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime)
55 {
56 uint8 * b;
57 uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime);
58 nod_info *ni;
59 inode *node = get_nod(fs, nod, &ni);
60+ size_t readbytes;
61 inode_pos ipos;
62
63+
64+ b = malloc(CB_SIZE);
65+ if (!b)
66+ error_msg_and_die("mkfile_fs: out of memory");
67 inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL);
68 node->i_size = size;
69- if (size) {
70- if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1)))
71- error_msg_and_die("not enough mem to read file '%s'", name);
72- if(f)
73- if (fread(b, size, 1, f) != 1) // FIXME: ugly. use mmap() ...
74- error_msg_and_die("fread failed");
75+ while (size) {
76+ readbytes = fread(b, 1, CB_SIZE, f);
77+ if ((size < CB_SIZE && readbytes != size)
78+ || (size >= CB_SIZE && readbytes != CB_SIZE))
79+ error_msg_and_die("fread failed");
80 extend_inode_blk(fs, &ipos, b,
81- rndup(size, BLOCKSIZE) / BLOCKSIZE);
82- free(b);
83+ rndup(readbytes, BLOCKSIZE) / BLOCKSIZE);
84+ size -= readbytes;
85 }
86 inode_pos_finish(fs, &ipos);
87 put_nod(ni);
88+ free(b);
89 return nod;
90 }
91
92@@ -2306,8 +2319,6 @@ alloc_fs(int swapit, char *fname, uint32 nbblocks, FILE *srcfile)
93 if (!fs->hdlinks.hdl)
94 error_msg_and_die("Not enough memory");
95 fs->hdlinks.count = 0 ;
96- fs->sb = (superblock *) (fs->data + BLOCKSIZE);
97- fs->gd = (groupdescriptor *) (fs->sb + 1);
98
99 if (strcmp(fname, "-") == 0)
100 fs->f = tmpfile();
101--
1021.7.4.1
103
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0012-Add-rev-1-support-large-file-support-and-rework-hole.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0012-Add-rev-1-support-large-file-support-and-rework-hole.patch
new file mode 100644
index 0000000000..2de6608c0c
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0012-Add-rev-1-support-large-file-support-and-rework-hole.patch
@@ -0,0 +1,211 @@
1Upstream-Status: inappropriate
2
3From fbcbbba3b65402bd43a9e36593d544ff3451620e Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Fri, 3 Jun 2011 21:09:25 -0500
6Subject: [PATCH 12/19] Add rev 1 support, large file support, and rework holes
7
8Add support for individual files larger than 2GB, which requires some
9rev 1 filesystem support.
10
11Also, since we have a non-overly filesystem structure, rework the
12OP_HOLES hack and just put that flag in the filesystem structure.
13This avoid having to mess around with the reserved bytes (which
14changed with rev 1 support).
15---
16 genext2fs.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++-----------
17 1 files changed, 56 insertions(+), 13 deletions(-)
18
19diff --git a/genext2fs.c b/genext2fs.c
20index 8a7f589..e420bba 100644
21--- a/genext2fs.c
22+++ b/genext2fs.c
23@@ -233,10 +233,6 @@ struct stats {
24 #define FM_IWOTH 0000002 // write
25 #define FM_IXOTH 0000001 // execute
26
27-// options
28-
29-#define OP_HOLES 0x01 // make files with holes
30-
31 /* Defines for accessing group details */
32
33 // Number of groups in the filesystem
34@@ -485,7 +481,22 @@ is_blk_empty(uint8 *b)
35 udecl32(s_creator_os) /* Indicator of which OS created the filesystem */ \
36 udecl32(s_rev_level) /* The revision level of the filesystem */ \
37 udecl16(s_def_resuid) /* The default uid for reserved blocks */ \
38- udecl16(s_def_resgid) /* The default gid for reserved blocks */
39+ udecl16(s_def_resgid) /* The default gid for reserved blocks */ \
40+ /* rev 1 version fields start here */ \
41+ udecl32(s_first_ino) /* First non-reserved inode */ \
42+ udecl16(s_inode_size) /* size of inode structure */ \
43+ udecl16(s_block_group_nr) /* block group # of this superblock */ \
44+ udecl32(s_feature_compat) /* compatible feature set */ \
45+ udecl32(s_feature_incompat) /* incompatible feature set */ \
46+ udecl32(s_feature_ro_compat) /* readonly-compatible feature set */ \
47+ utdecl8(s_uuid,16) /* 128-bit uuid for volume */ \
48+ utdecl8(s_volume_name,16) /* volume name */ \
49+ utdecl8(s_last_mounted,64) /* directory where last mounted */ \
50+ udecl32(s_algorithm_usage_bitmap) /* For compression */
51+
52+#define EXT2_GOOD_OLD_FIRST_INO 11
53+#define EXT2_GOOD_OLD_INODE_SIZE 128
54+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
55
56 #define groupdescriptor_decl \
57 udecl32(bg_block_bitmap) /* Block number of the block bitmap */ \
58@@ -525,6 +536,7 @@ is_blk_empty(uint8 *b)
59
60 #define decl8(x) int8 x;
61 #define udecl8(x) uint8 x;
62+#define utdecl8(x,n) uint8 x[n];
63 #define decl16(x) int16 x;
64 #define udecl16(x) uint16 x;
65 #define decl32(x) int32 x;
66@@ -534,7 +546,7 @@ is_blk_empty(uint8 *b)
67 typedef struct
68 {
69 superblock_decl
70- uint32 s_reserved[235]; // Reserved
71+ uint32 s_reserved[205]; // Reserved
72 } superblock;
73
74 typedef struct
75@@ -616,6 +628,8 @@ typedef struct
76 int32 hdlink_cnt;
77 struct hdlinks_s hdlinks;
78
79+ int holes;
80+
81 listcache blks;
82 listcache inodes;
83 listcache blkmaps;
84@@ -628,6 +642,7 @@ typedef struct
85
86 #undef decl8
87 #undef udecl8
88+#undef utdecl8
89 #undef decl16
90 #undef udecl16
91 #undef decl32
92@@ -636,6 +651,7 @@ typedef struct
93
94 #define decl8(x)
95 #define udecl8(x)
96+#define utdecl8(x,n)
97 #define decl16(x) this->x = swab16(this->x);
98 #define udecl16(x) this->x = swab16(this->x);
99 #define decl32(x) this->x = swab32(this->x);
100@@ -700,6 +716,7 @@ swap_block(block b)
101
102 #undef decl8
103 #undef udecl8
104+#undef utdecl8
105 #undef decl16
106 #undef udecl16
107 #undef decl32
108@@ -1695,7 +1712,7 @@ extend_inode_blk(filesystem *fs, inode_pos *ipos, block b, int amount)
109
110 for (pos = 0; amount; pos += BLOCKSIZE)
111 {
112- int hole = ((fs->sb->s_reserved[200] & OP_HOLES) && is_blk_empty(b + pos));
113+ int hole = (fs->holes && is_blk_empty(b + pos));
114
115 bk = walk_bw(fs, ipos->nod, &ipos->bw, &amount, hole);
116 if (bk == WALK_END)
117@@ -1912,6 +1929,14 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint
118 return nod;
119 }
120
121+static void
122+fs_upgrade_rev1_largefile(filesystem *fs)
123+{
124+ fs->sb->s_rev_level = 1;
125+ fs->sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
126+ fs->sb->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
127+}
128+
129 #define COPY_BLOCKS 16
130 #define CB_SIZE (COPY_BLOCKS * BLOCKSIZE)
131
132@@ -1926,11 +1951,16 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_
133 size_t readbytes;
134 inode_pos ipos;
135
136-
137 b = malloc(CB_SIZE);
138 if (!b)
139 error_msg_and_die("mkfile_fs: out of memory");
140 inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL);
141+ if (size > 0x7fffffff) {
142+ if (fs->sb->s_rev_level < 1)
143+ fs_upgrade_rev1_largefile(fs);
144+ fs->sb->s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
145+ }
146+ node->i_dir_acl = size >> 32;
147 node->i_size = size;
148 while (size) {
149 readbytes = fread(b, 1, CB_SIZE, f);
150@@ -2269,6 +2299,8 @@ swap_gds(filesystem *fs)
151
152 // Copy size blocks from src to dst, putting holes in the output
153 // file (if possible) if the input block is all zeros.
154+// Copy size blocks from src to dst, putting holes in the output
155+// file (if possible) if the input block is all zeros.
156 static void
157 copy_file(filesystem *fs, FILE *dst, FILE *src, size_t size)
158 {
159@@ -2284,7 +2316,7 @@ copy_file(filesystem *fs, FILE *dst, FILE *src, size_t size)
160 while (size > 0) {
161 if (fread(b, BLOCKSIZE, 1, src) != 1)
162 perror_msg_and_die("copy failed on read");
163- if ((dst != stdout) && is_blk_empty(b)) {
164+ if ((dst != stdout) && fs->holes && is_blk_empty(b)) {
165 /* Empty block, just skip it */
166 if (fseek(dst, BLOCKSIZE, SEEK_CUR))
167 perror_msg_and_die("fseek");
168@@ -2537,8 +2569,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes,
169 fs->sb->s_max_mnt_count = 20;
170
171 // options for me
172- if(holes)
173- fs->sb->s_reserved[200] |= OP_HOLES;
174+ fs->holes = holes;
175
176 return fs;
177 }
178@@ -2571,8 +2602,21 @@ load_fs(FILE * fh, int swapit, char *fname)
179 perror_msg_and_die("fread filesystem image superblock");
180 if(swapit)
181 swap_sb(fs->sb);
182- if(fs->sb->s_rev_level || (fs->sb->s_magic != EXT2_MAGIC_NUMBER))
183+ if((fs->sb->s_rev_level > 1) || (fs->sb->s_magic != EXT2_MAGIC_NUMBER))
184 error_msg_and_die("not a suitable ext2 filesystem");
185+ if (fs->sb->s_rev_level > 0) {
186+ if (fs->sb->s_first_ino != EXT2_GOOD_OLD_FIRST_INO)
187+ error_msg_and_die("First inode incompatible");
188+ if (fs->sb->s_inode_size != EXT2_GOOD_OLD_INODE_SIZE)
189+ error_msg_and_die("inode size incompatible");
190+ if (fs->sb->s_feature_compat)
191+ error_msg_and_die("Unsupported compat features");
192+ if (fs->sb->s_feature_incompat)
193+ error_msg_and_die("Unsupported incompat features");
194+ if (fs->sb->s_feature_ro_compat
195+ & ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
196+ error_msg_and_die("Unsupported ro compat features");
197+ }
198 fs->nheadblocks = (((GRP_NBGROUPS(fs) * sizeof(groupdescriptor))
199 + sizeof(superblock) + (BLOCKSIZE - 1))
200 / BLOCKSIZE);
201@@ -2893,7 +2937,6 @@ finish_fs(filesystem *fs)
202 error_msg_and_die("entry mismatch on blockmap cache flush");
203 if (cache_flush(&fs->blks))
204 error_msg_and_die("entry mismatch on block cache flush");
205- fs->sb->s_reserved[200] = 0;
206 if(fs->swapit) {
207 swap_sb(fs->sb);
208 swap_gds(fs);
209--
2101.7.4.1
211
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0013-Add-volume-id-support.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0013-Add-volume-id-support.patch
new file mode 100644
index 0000000000..1777dd6b0f
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0013-Add-volume-id-support.patch
@@ -0,0 +1,86 @@
1Upstream-Status: inappropriate
2
3From 3b9edc3e7c809f64dc164d73b64ab4a606ccfea1 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Fri, 3 Jun 2011 21:24:49 -0500
6Subject: [PATCH 13/19] Add volume id support.
7
8Add support for setting the volume id of the filesystem. This is
9functionally the same as the patch from OpenEmbedded, but is built
10on previous changes in this patch set.
11---
12 genext2fs.8 | 3 +++
13 genext2fs.c | 12 ++++++++++--
14 2 files changed, 13 insertions(+), 2 deletions(-)
15
16diff --git a/genext2fs.8 b/genext2fs.8
17index 0f77e7c..8b8db25 100644
18--- a/genext2fs.8
19+++ b/genext2fs.8
20@@ -61,6 +61,9 @@ Size of the image in blocks.
21 .BI "\-N, \-\-number\-of\-inodes inodes"
22 Maximum number of inodes.
23 .TP
24+.BI "\-L, \-\-volume\-id name"
25+Set the volume id (volume name) for the filesystem.
26+.TP
27 .BI "\-i, \-\-bytes\-per\-inode ratio"
28 Used to calculate the maximum number of inodes from the available blocks.
29 .TP
30diff --git a/genext2fs.c b/genext2fs.c
31index e420bba..4d01bc4 100644
32--- a/genext2fs.c
33+++ b/genext2fs.c
34@@ -3058,6 +3058,7 @@ main(int argc, char **argv)
35 int squash_perms = 0;
36 uint16 endian = 1;
37 int bigendian = !*(char*)&endian;
38+ char *volumelabel = NULL;
39 filesystem *fs;
40 int i;
41 int c;
42@@ -3071,6 +3072,7 @@ main(int argc, char **argv)
43 { "size-in-blocks", required_argument, NULL, 'b' },
44 { "bytes-per-inode", required_argument, NULL, 'i' },
45 { "number-of-inodes", required_argument, NULL, 'N' },
46+ { "volume-label", required_argument, NULL, 'L' },
47 { "reserved-percentage", required_argument, NULL, 'm' },
48 { "block-map", required_argument, NULL, 'g' },
49 { "fill-value", required_argument, NULL, 'e' },
50@@ -3087,11 +3089,11 @@ main(int argc, char **argv)
51
52 app_name = argv[0];
53
54- while((c = getopt_long(argc, argv, "x:d:D:b:i:N:m:g:e:zfqUPhVv", longopts, NULL)) != EOF) {
55+ while((c = getopt_long(argc, argv, "x:d:D:b:i:N:L:m:g:e:zfqUPhVv", longopts, NULL)) != EOF) {
56 #else
57 app_name = argv[0];
58
59- while((c = getopt(argc, argv, "x:d:D:b:i:N:m:g:e:zfqUPhVv")) != EOF) {
60+ while((c = getopt(argc, argv, "x:d:D:b:i:N:L:m:g:e:zfqUPhVv")) != EOF) {
61 #endif /* HAVE_GETOPT_LONG */
62 switch(c)
63 {
64@@ -3111,6 +3113,9 @@ main(int argc, char **argv)
65 case 'N':
66 nbinodes = SI_atof(optarg);
67 break;
68+ case 'L':
69+ volumelabel = optarg;
70+ break;
71 case 'm':
72 reserved_frac = SI_atof(optarg) / 100;
73 break;
74@@ -3199,6 +3204,9 @@ main(int argc, char **argv)
75 fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp,
76 bigendian, fsout);
77 }
78+ if (volumelabel != NULL)
79+ strncpy((char *)fs->sb->s_volume_name, volumelabel,
80+ sizeof(fs->sb->s_volume_name));
81
82 populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL);
83
84--
851.7.4.1
86
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0014-Remove-unneeded-setting-of-s_reserved.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0014-Remove-unneeded-setting-of-s_reserved.patch
new file mode 100644
index 0000000000..de196b0716
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0014-Remove-unneeded-setting-of-s_reserved.patch
@@ -0,0 +1,28 @@
1Upstream-Status: inappropriate
2
3From d20116479700bdc8a3b63b0025562671292728d6 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Mon, 6 Jun 2011 13:39:50 -0500
6Subject: [PATCH 14/19] Remove unneeded setting of s_reserved.
7
8This was missed in the previous patch to remove OP_HOLES.
9---
10 genext2fs.c | 2 --
11 1 files changed, 0 insertions(+), 2 deletions(-)
12
13diff --git a/genext2fs.c b/genext2fs.c
14index 4d01bc4..b466a6d 100644
15--- a/genext2fs.c
16+++ b/genext2fs.c
17@@ -2463,8 +2463,6 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes,
18 fs->sb->s_magic = EXT2_MAGIC_NUMBER;
19 fs->sb->s_lastcheck = fs_timestamp;
20
21- fs->sb->s_reserved[200] = 0;
22-
23 set_file_size(fs);
24
25 // set up groupdescriptors
26--
271.7.4.1
28
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0015-Rework-creating-the-lost-found-directory.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0015-Rework-creating-the-lost-found-directory.patch
new file mode 100644
index 0000000000..fbde366854
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0015-Rework-creating-the-lost-found-directory.patch
@@ -0,0 +1,57 @@
1Upstream-Status: inappropriate
2
3From 34a2d139e3cbc9fec1b07171fd13684d4239aa6b Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Mon, 6 Jun 2011 13:51:50 -0500
6Subject: [PATCH 15/19] Rework creating the lost+found directory
7
8For some reason the lost+found directory was being created with
9the size of the number of reserved blocks. I can't find any rationale
10for that, mke2fs creates it with 16 blocks. So just create it with
1116 blocks, too.
12---
13 genext2fs.c | 15 ++++++---------
14 1 files changed, 6 insertions(+), 9 deletions(-)
15
16diff --git a/genext2fs.c b/genext2fs.c
17index b466a6d..fc7fe5f 100644
18--- a/genext2fs.c
19+++ b/genext2fs.c
20@@ -2537,28 +2537,25 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes,
21 inode_pos_finish(fs, &ipos);
22 put_dir(&dw);
23
24- // make lost+found directory and reserve blocks
25+ // make lost+found directory
26 if(fs->sb->s_r_blocks_count)
27 {
28 inode *node;
29 uint8 *b;
30
31- nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU, 0, 0, fs_timestamp, fs_timestamp);
32+ nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU,
33+ 0, 0, fs_timestamp, fs_timestamp);
34 b = get_workblk();
35 memset(b, 0, BLOCKSIZE);
36 ((directory*)b)->d_rec_len = BLOCKSIZE;
37- /* We run into problems with e2fsck if directory lost+found grows
38- * bigger than this. Need to find out why this happens - sundar
39- */
40- if (fs->sb->s_r_blocks_count > fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS )
41- fs->sb->s_r_blocks_count = fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS;
42 inode_pos_init(fs, &ipos, nod, INODE_POS_EXTEND, NULL);
43- for(i = 1; i < fs->sb->s_r_blocks_count; i++)
44+ // It is always 16 blocks to start out with
45+ for(i = 0; i < 16; i++)
46 extend_inode_blk(fs, &ipos, b, 1);
47 inode_pos_finish(fs, &ipos);
48 free_workblk(b);
49 node = get_nod(fs, nod, &ni);
50- node->i_size = fs->sb->s_r_blocks_count * BLOCKSIZE;
51+ node->i_size = 16 * BLOCKSIZE;
52 put_nod(ni);
53 }
54
55--
561.7.4.1
57
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0016-Fix-the-documentation-for-the-new-L-option.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0016-Fix-the-documentation-for-the-new-L-option.patch
new file mode 100644
index 0000000000..8c24db107e
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0016-Fix-the-documentation-for-the-new-L-option.patch
@@ -0,0 +1,29 @@
1Upstream-Status: inappropriate
2
3From 1b5007ee27b9dbf5e84341dceadb83b96e6530d5 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Mon, 6 Jun 2011 13:58:57 -0500
6Subject: [PATCH 16/19] Fix the documentation for the new -L option
7
8---
9 genext2fs.8 | 4 ++--
10 1 files changed, 2 insertions(+), 2 deletions(-)
11
12diff --git a/genext2fs.8 b/genext2fs.8
13index 8b8db25..35e1588 100644
14--- a/genext2fs.8
15+++ b/genext2fs.8
16@@ -61,8 +61,8 @@ Size of the image in blocks.
17 .BI "\-N, \-\-number\-of\-inodes inodes"
18 Maximum number of inodes.
19 .TP
20-.BI "\-L, \-\-volume\-id name"
21-Set the volume id (volume name) for the filesystem.
22+.BI "\-L, \-\-volume\-label name"
23+Set the volume label for the filesystem.
24 .TP
25 .BI "\-i, \-\-bytes\-per\-inode ratio"
26 Used to calculate the maximum number of inodes from the available blocks.
27--
281.7.4.1
29
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0017-Fix-file-same-comparison.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0017-Fix-file-same-comparison.patch
new file mode 100644
index 0000000000..40a7807b0d
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0017-Fix-file-same-comparison.patch
@@ -0,0 +1,30 @@
1Upstream-Status: inappropriate
2
3From 33c92a0b663d16d2260b391d39aa745acd4b360e Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Tue, 7 Jun 2011 07:23:23 -0500
6Subject: [PATCH 17/19] Fix "file same" comparison
7
8It's not enough to check the inode, you also have to check the device
9to make sure a file is the same.
10---
11 genext2fs.c | 3 ++-
12 1 files changed, 2 insertions(+), 1 deletions(-)
13
14diff --git a/genext2fs.c b/genext2fs.c
15index fc7fe5f..485393c 100644
16--- a/genext2fs.c
17+++ b/genext2fs.c
18@@ -2359,7 +2359,8 @@ alloc_fs(int swapit, char *fname, uint32 nbblocks, FILE *srcfile)
19 perror_msg_and_die("fstat srcfile");
20 if (stat(fname, &dststat))
21 perror_msg_and_die("stat-ing %s", fname);
22- if (srcstat.st_ino == dststat.st_ino) {
23+ if (srcstat.st_ino == dststat.st_ino
24+ && srcstat.st_dev == dststat.st_dev) {
25 // source and destination are the same file, don't
26 // truncate or copy, just use the file.
27 fs->f = fopen(fname, "r+b");
28--
291.7.4.1
30
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0018-Handle-files-changing-while-we-are-working.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0018-Handle-files-changing-while-we-are-working.patch
new file mode 100644
index 0000000000..3ea877c4d4
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0018-Handle-files-changing-while-we-are-working.patch
@@ -0,0 +1,89 @@
1Upstream-Status: inappropriate
2
3From fd1f52c435099eab199f2b06eb411aab337d7f47 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Tue, 7 Jun 2011 07:29:53 -0500
6Subject: [PATCH 18/19] Handle files changing while we are working
7
8Files may change or be deleted between the lstat and the actual
9operation to read them and put them into the target filesystem.
10Handle this more gracefully. Warn on file deletions, and handle
11whatever size is read, not whatever size happens to be in the
12inode when we stat-ed it.
13
14Also clear the data to the end of an file's last block, to keep
15things clean.
16---
17 genext2fs.c | 30 ++++++++++++++++++------------
18 1 files changed, 18 insertions(+), 12 deletions(-)
19
20diff --git a/genext2fs.c b/genext2fs.c
21index 485393c..28ba94f 100644
22--- a/genext2fs.c
23+++ b/genext2fs.c
24@@ -1942,19 +1942,30 @@ fs_upgrade_rev1_largefile(filesystem *fs)
25
26 // make a file from a FILE*
27 static uint32
28-mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_t size, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime)
29+mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime)
30 {
31 uint8 * b;
32 uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime);
33 nod_info *ni;
34 inode *node = get_nod(fs, nod, &ni);
35+ off_t size = 0;
36 size_t readbytes;
37 inode_pos ipos;
38+ int fullsize;
39
40 b = malloc(CB_SIZE);
41 if (!b)
42 error_msg_and_die("mkfile_fs: out of memory");
43 inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL);
44+ readbytes = fread(b, 1, CB_SIZE, f);
45+ while (readbytes) {
46+ fullsize = rndup(readbytes, BLOCKSIZE);
47+ // Fill to end of block with zeros.
48+ memset(b + readbytes, 0, fullsize - readbytes);
49+ extend_inode_blk(fs, &ipos, b, fullsize / BLOCKSIZE);
50+ size += readbytes;
51+ readbytes = fread(b, 1, CB_SIZE, f);
52+ }
53 if (size > 0x7fffffff) {
54 if (fs->sb->s_rev_level < 1)
55 fs_upgrade_rev1_largefile(fs);
56@@ -1962,15 +1973,6 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_
57 }
58 node->i_dir_acl = size >> 32;
59 node->i_size = size;
60- while (size) {
61- readbytes = fread(b, 1, CB_SIZE, f);
62- if ((size < CB_SIZE && readbytes != size)
63- || (size >= CB_SIZE && readbytes != CB_SIZE))
64- error_msg_and_die("fread failed");
65- extend_inode_blk(fs, &ipos, b,
66- rndup(readbytes, BLOCKSIZE) / BLOCKSIZE);
67- size -= readbytes;
68- }
69 inode_pos_finish(fs, &ipos);
70 put_nod(ni);
71 free(b);
72@@ -2256,8 +2258,12 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per
73 free(lnk);
74 break;
75 case S_IFREG:
76- fh = xfopen(dent->d_name, "rb");
77- nod = mkfile_fs(fs, this_nod, name, mode, st.st_size, fh, uid, gid, ctime, mtime);
78+ fh = fopen(dent->d_name, "rb");
79+ if (!fh) {
80+ error_msg("Unable to open file %s", dent->d_name);
81+ break;
82+ }
83+ nod = mkfile_fs(fs, this_nod, name, mode, fh, uid, gid, ctime, mtime);
84 fclose(fh);
85 break;
86 case S_IFDIR:
87--
881.7.4.1
89
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0019-Make-sure-superblock-is-clear-on-allocation.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0019-Make-sure-superblock-is-clear-on-allocation.patch
new file mode 100644
index 0000000000..a75a8128cc
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0019-Make-sure-superblock-is-clear-on-allocation.patch
@@ -0,0 +1,42 @@
1Upstream-Status: inappropriate
2
3From a263cdabad01ba99581b26d1753cd459f2669413 Mon Sep 17 00:00:00 2001
4From: Corey Minyard <cminyard@mvista.com>
5Date: Tue, 7 Jun 2011 09:14:19 -0500
6Subject: [PATCH 19/19] Make sure superblock is clear on allocation
7
8Use calloc, not malloc, so the allocated superblock is zero-ed. Also,
9get rid of some unnecessary casts.
10---
11 genext2fs.c | 6 +++---
12 1 files changed, 3 insertions(+), 3 deletions(-)
13
14diff --git a/genext2fs.c b/genext2fs.c
15index 28ba94f..fab90be 100644
16--- a/genext2fs.c
17+++ b/genext2fs.c
18@@ -2447,10 +2447,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes,
19 fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor))
20 + sizeof(superblock) + (BLOCKSIZE - 1))
21 / BLOCKSIZE);
22- fs->sb = (superblock *) malloc(BLOCKSIZE);
23+ fs->sb = calloc(1, BLOCKSIZE);
24 if (!fs->sb)
25 error_msg_and_die("error allocating header memory");
26- fs->gd = (groupdescriptor *) calloc(fs->nheadblocks - 1, BLOCKSIZE);
27+ fs->gd = calloc(fs->nheadblocks - 1, BLOCKSIZE);
28 if (!fs->gd)
29 error_msg_and_die("error allocating header memory");
30
31@@ -2595,7 +2595,7 @@ load_fs(FILE * fh, int swapit, char *fname)
32
33 /* Read and check the superblock, then read the superblock
34 * and all the group descriptors */
35- fs->sb = malloc(BLOCKSIZE);
36+ fs->sb = calloc(1, BLOCKSIZE);
37 if (!fs->sb)
38 error_msg_and_die("error allocating header memory");
39 if (fseek(fs->f, BLOCKSIZE, SEEK_SET))
40--
411.7.4.1
42
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/fix-nbblocks-cast.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/fix-nbblocks-cast.patch
index 3fd15e058b..05b095edf0 100644
--- a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/fix-nbblocks-cast.patch
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/fix-nbblocks-cast.patch
@@ -11,11 +11,13 @@ int tmp_nbinodes = nbblocks * BLOCKSIZE / bytes_per_inode;
11Upstream-Status: Submitted 11Upstream-Status: Submitted
12Signed-off-by: Saul Wold <sgw@linux.intel.com> 12Signed-off-by: Saul Wold <sgw@linux.intel.com>
13 13
14Rebased by Dexuan Cui <dexuan.cui@intel.com>
15
14Index: genext2fs-1.4.1/genext2fs.c 16Index: genext2fs-1.4.1/genext2fs.c
15=================================================================== 17===================================================================
16--- genext2fs-1.4.1.orig/genext2fs.c 18--- a/genext2fs.c 2012-03-29 00:07:20.308856017 +0800
17+++ genext2fs-1.4.1/genext2fs.c 19+++ b/genext2fs.c 2012-03-29 00:09:06.848856005 +0800
18@@ -2447,7 +2447,7 @@ extern int optind, opterr, optopt; 20@@ -3041,7 +3041,7 @@
19 int 21 int
20 main(int argc, char **argv) 22 main(int argc, char **argv)
21 { 23 {
@@ -24,12 +26,12 @@ Index: genext2fs-1.4.1/genext2fs.c
24 int nbinodes = -1; 26 int nbinodes = -1;
25 int nbresrvd = -1; 27 int nbresrvd = -1;
26 float bytes_per_inode = -1; 28 float bytes_per_inode = -1;
27@@ -2609,7 +2609,7 @@ main(int argc, char **argv) 29@@ -3203,7 +3203,7 @@
28 } 30 }
29 if(fs_timestamp == -1) 31 if(fs_timestamp == -1)
30 fs_timestamp = time(NULL); 32 fs_timestamp = time(NULL);
31- fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp); 33- fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp,
32+ fs = init_fs((int)nbblocks, nbinodes, nbresrvd, holes, fs_timestamp); 34+ fs = init_fs((int)nbblocks, nbinodes, nbresrvd, holes, fs_timestamp,
35 bigendian, fsout);
33 } 36 }
34 37 if (volumelabel != NULL)
35 populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL);
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/update_to_1.95.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/update_to_1.95.patch
new file mode 100644
index 0000000000..ea2b16ccf9
--- /dev/null
+++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/update_to_1.95.patch
@@ -0,0 +1,119 @@
1See http://genext2fs.cvs.sourceforge.net/viewvc/genext2fs/genext2fs/genext2fs.c?view=log
2
3The latest version of genext2fs.c is the v1.95 in the cvs repo:
4http://genext2fs.cvs.sourceforge.net/viewvc/genext2fs/genext2fs/genext2fs.c?revision=1.95
5
6First let's upgrade to the version.
7
8Upstream-Status: inappropriate
9
10Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
11
12--- a/genext2fs.c 2007-03-26 22:19:59.000000000 +0800
13+++ b/genext2fs.c 2012-03-28 22:15:03.678856820 +0800
14@@ -286,7 +286,9 @@
15 // older solaris. Note that this is still not very portable, in that
16 // the return value cannot be trusted.
17
18-#if SCANF_CAN_MALLOC
19+#if 0 // SCANF_CAN_MALLOC
20+// C99 define "a" for floating point, so you can have runtime surprise
21+// according the library versions
22 # define SCANF_PREFIX "a"
23 # define SCANF_STRING(s) (&s)
24 #else
25@@ -778,7 +780,7 @@
26 if(hdlinks.hdl[i].src_inode == inode)
27 return i;
28 }
29- return -1;
30+ return -1;
31 }
32
33 // printf helper macro
34@@ -1356,20 +1358,23 @@
35 return nod;
36 }
37
38+// chmod an inode
39+void
40+chmod_fs(filesystem *fs, uint32 nod, uint16 mode, uint16 uid, uint16 gid)
41+{
42+ inode *node;
43+ node = get_nod(fs, nod);
44+ node->i_mode = (node->i_mode & ~FM_IMASK) | (mode & FM_IMASK);
45+ node->i_uid = uid;
46+ node->i_gid = gid;
47+}
48+
49 // create a simple inode
50 static uint32
51 mknod_fs(filesystem *fs, uint32 parent_nod, const char *name, uint16 mode, uint16 uid, uint16 gid, uint8 major, uint8 minor, uint32 ctime, uint32 mtime)
52 {
53 uint32 nod;
54 inode *node;
55- if((nod = find_dir(fs, parent_nod, name)))
56- {
57- node = get_nod(fs, nod);
58- if((node->i_mode & FM_IFMT) != (mode & FM_IFMT))
59- error_msg_and_die("node '%s' already exists and isn't of the same type", name);
60- node->i_mode = mode;
61- }
62- else
63 {
64 nod = alloc_nod(fs);
65 node = get_nod(fs, nod);
66@@ -1591,13 +1596,24 @@
67 dname = malloc(len + 1);
68 for(i = start; i < count; i++)
69 {
70+ uint32 oldnod;
71 SNPRINTF(dname, len, "%s%lu", name, i);
72- mknod_fs(fs, nod, dname, mode, uid, gid, major, minor + (i * increment - start), ctime, mtime);
73+ oldnod = find_dir(fs, nod, dname);
74+ if(oldnod)
75+ chmod_fs(fs, oldnod, mode, uid, gid);
76+ else
77+ mknod_fs(fs, nod, dname, mode, uid, gid, major, minor + (i * increment - start), ctime, mtime);
78 }
79 free(dname);
80 }
81 else
82- mknod_fs(fs, nod, name, mode, uid, gid, major, minor, ctime, mtime);
83+ {
84+ uint32 oldnod = find_dir(fs, nod, name);
85+ if(oldnod)
86+ chmod_fs(fs, oldnod, mode, uid, gid);
87+ else
88+ mknod_fs(fs, nod, name, mode, uid, gid, major, minor, ctime, mtime);
89+ }
90 }
91 }
92 if (line)
93@@ -1664,6 +1680,17 @@
94 }
95 else
96 {
97+ if((nod = find_dir(fs, this_nod, name)))
98+ {
99+ error_msg("ignoring duplicate entry %s", name);
100+ if(S_ISDIR(st.st_mode)) {
101+ if(chdir(dent->d_name) < 0)
102+ perror_msg_and_die(name);
103+ add2fs_from_dir(fs, nod, squash_uids, squash_perms, fs_timestamp, stats);
104+ chdir("..");
105+ }
106+ continue;
107+ }
108 save_nod = 0;
109 /* Check for hardlinks */
110 if (!S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode) && st.st_nlink > 1) {
111@@ -1994,7 +2021,7 @@
112 //system blocks
113 for(j = 1; j <= overhead_per_group; j++)
114 allocate(bbm, j);
115-
116+
117 /* Inode bitmap */
118 ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap);
119 //non-filesystem inodes
diff --git a/meta/recipes-devtools/genext2fs/genext2fs_1.4.1.bb b/meta/recipes-devtools/genext2fs/genext2fs_1.4.1.bb
index 012ec6c4fb..702245ff75 100644
--- a/meta/recipes-devtools/genext2fs/genext2fs_1.4.1.bb
+++ b/meta/recipes-devtools/genext2fs/genext2fs_1.4.1.bb
@@ -1,8 +1,28 @@
1require genext2fs.inc 1require genext2fs.inc
2 2
3PR = "r1" 3PR = "r2"
4 4
5SRC_URI += "file://fix-nbblocks-cast.patch" 5SRC_URI += "file://update_to_1.95.patch \
6 file://0001-Fix-warnings-remove-some-unused-macros.patch \
7 file://0002-Add-put_blk-and-put_nod-routines.patch \
8 file://0003-Add-get_blkmap-and-put_blkmap.patch \
9 file://0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch \
10 file://0005-Make-filesystem-struct-not-an-overloay.patch \
11 file://0006-Improve-the-efficiency-of-extend_blk.patch \
12 file://0007-Move-hdlinks-into-the-filesystem-structure.patch \
13 file://0008-Separate-out-the-creation-of-the-filesystem-structur.patch \
14 file://0009-Move-byte-swapping-into-the-get-put-routines.patch \
15 file://0010-Convert-over-to-keeping-the-filesystem-on-disk.patch \
16 file://0011-Copy-files-into-the-filesystem-a-piece-at-a-time.patch \
17 file://0012-Add-rev-1-support-large-file-support-and-rework-hole.patch \
18 file://0013-Add-volume-id-support.patch \
19 file://0014-Remove-unneeded-setting-of-s_reserved.patch \
20 file://0015-Rework-creating-the-lost-found-directory.patch \
21 file://0016-Fix-the-documentation-for-the-new-L-option.patch \
22 file://0017-Fix-file-same-comparison.patch \
23 file://0018-Handle-files-changing-while-we-are-working.patch \
24 file://0019-Make-sure-superblock-is-clear-on-allocation.patch \
25 file://fix-nbblocks-cast.patch"
6 26
7SRC_URI[md5sum] = "b7b6361bcce2cedff1ae437fadafe53b" 27SRC_URI[md5sum] = "b7b6361bcce2cedff1ae437fadafe53b"
8SRC_URI[sha256sum] = "404dbbfa7a86a6c3de8225c8da254d026b17fd288e05cec4df2cc7e1f4feecfc" 28SRC_URI[sha256sum] = "404dbbfa7a86a6c3de8225c8da254d026b17fd288e05cec4df2cc7e1f4feecfc"