diff options
Diffstat (limited to 'meta/packages/genext2fs/genext2fs-1.3/autosize.patch')
-rw-r--r-- | meta/packages/genext2fs/genext2fs-1.3/autosize.patch | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/meta/packages/genext2fs/genext2fs-1.3/autosize.patch b/meta/packages/genext2fs/genext2fs-1.3/autosize.patch new file mode 100644 index 0000000000..a4318a6eee --- /dev/null +++ b/meta/packages/genext2fs/genext2fs-1.3/autosize.patch | |||
@@ -0,0 +1,339 @@ | |||
1 | |||
2 | # | ||
3 | # Patch managed by http://www.holgerschurig.de/patcher.html | ||
4 | # | ||
5 | |||
6 | --- genext2fs-1.3.orig/genext2fs.c~autosize.patch | ||
7 | +++ genext2fs-1.3.orig/genext2fs.c | ||
8 | @@ -4,6 +4,11 @@ | ||
9 | // ext2 filesystem generator for embedded systems | ||
10 | // Copyright (C) 2000 Xavier Bestel <xavier.bestel@free.fr> | ||
11 | // | ||
12 | +// 'du' portions taken from coreutils/du.c in busybox: | ||
13 | +// Copyright (C) 1999,2000 by Lineo, inc. and John Beppu | ||
14 | +// Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org> | ||
15 | +// Copyright (C) 2002 Edward Betts <edward@debian.org> | ||
16 | +// | ||
17 | // This program is free software; you can redistribute it and/or | ||
18 | // modify it under the terms of the GNU General Public License | ||
19 | // as published by the Free Software Foundation; version | ||
20 | @@ -79,9 +84,93 @@ | ||
21 | #include <ctype.h> | ||
22 | #include <errno.h> | ||
23 | #include <fcntl.h> | ||
24 | +#include <sys/types.h> | ||
25 | +#include <getopt.h> | ||
26 | + | ||
27 | +#define HASH_SIZE 311 /* Should be prime */ | ||
28 | +#define hash_inode(i) ((i) % HASH_SIZE) | ||
29 | + | ||
30 | +typedef struct ino_dev_hash_bucket_struct { | ||
31 | + struct ino_dev_hash_bucket_struct *next; | ||
32 | + ino_t ino; | ||
33 | + dev_t dev; | ||
34 | + char name[1]; | ||
35 | +} ino_dev_hashtable_bucket_t; | ||
36 | + | ||
37 | +static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE]; | ||
38 | + | ||
39 | +struct stats { | ||
40 | + unsigned long nblocks; | ||
41 | + unsigned long ninodes; | ||
42 | +}; | ||
43 | + | ||
44 | +int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name) | ||
45 | +{ | ||
46 | + ino_dev_hashtable_bucket_t *bucket; | ||
47 | + | ||
48 | + bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)]; | ||
49 | + while (bucket != NULL) { | ||
50 | + if ((bucket->ino == statbuf->st_ino) && | ||
51 | + (bucket->dev == statbuf->st_dev)) | ||
52 | + { | ||
53 | + if (name) *name = bucket->name; | ||
54 | + return 1; | ||
55 | + } | ||
56 | + bucket = bucket->next; | ||
57 | + } | ||
58 | + return 0; | ||
59 | +} | ||
60 | + | ||
61 | +/* Add statbuf to statbuf hash table */ | ||
62 | +void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) | ||
63 | +{ | ||
64 | + int i; | ||
65 | + size_t s; | ||
66 | + ino_dev_hashtable_bucket_t *bucket; | ||
67 | + | ||
68 | + i = hash_inode(statbuf->st_ino); | ||
69 | + s = name ? strlen(name) : 0; | ||
70 | + bucket = malloc(sizeof(ino_dev_hashtable_bucket_t) + s); | ||
71 | + bucket->ino = statbuf->st_ino; | ||
72 | + bucket->dev = statbuf->st_dev; | ||
73 | + if (name) | ||
74 | + strcpy(bucket->name, name); | ||
75 | + else | ||
76 | + bucket->name[0] = '\0'; | ||
77 | + bucket->next = ino_dev_hashtable[i]; | ||
78 | + ino_dev_hashtable[i] = bucket; | ||
79 | +} | ||
80 | + | ||
81 | +/* Clear statbuf hash table */ | ||
82 | +void reset_ino_dev_hashtable(void) | ||
83 | +{ | ||
84 | + int i; | ||
85 | + ino_dev_hashtable_bucket_t *bucket; | ||
86 | + | ||
87 | + for (i = 0; i < HASH_SIZE; i++) { | ||
88 | + while (ino_dev_hashtable[i] != NULL) { | ||
89 | + bucket = ino_dev_hashtable[i]->next; | ||
90 | + free(ino_dev_hashtable[i]); | ||
91 | + ino_dev_hashtable[i] = bucket; | ||
92 | + } | ||
93 | + } | ||
94 | +} | ||
95 | |||
96 | +static int count_ino_in_hashtable(void) | ||
97 | +{ | ||
98 | + long count = 0; | ||
99 | + int i; | ||
100 | |||
101 | + for (i = 0; i < HASH_SIZE; i++) { | ||
102 | + ino_dev_hashtable_bucket_t *bucket = ino_dev_hashtable[i]; | ||
103 | + while (bucket != NULL) { | ||
104 | + count++; | ||
105 | + bucket = bucket->next; | ||
106 | + } | ||
107 | + } | ||
108 | |||
109 | + return count; | ||
110 | +} | ||
111 | |||
112 | // block size | ||
113 | |||
114 | @@ -1178,6 +1267,38 @@ | ||
115 | return n; | ||
116 | } | ||
117 | |||
118 | +void stats_from_dir(struct stats *stats) | ||
119 | +{ | ||
120 | + DIR *dh; | ||
121 | + struct dirent *dent; | ||
122 | + struct stat st; | ||
123 | + if(!(dh = opendir("."))) | ||
124 | + perror_msg_and_die("."); | ||
125 | + while((dent = readdir(dh))) | ||
126 | + { | ||
127 | + if((!strcmp(dent->d_name, ".")) || (!strcmp(dent->d_name, ".."))) | ||
128 | + continue; | ||
129 | + lstat(dent->d_name, &st); | ||
130 | + if (S_ISLNK(st.st_mode)) { | ||
131 | + stats->ninodes++; | ||
132 | + } else if (S_ISDIR(st.st_mode)) { | ||
133 | + if(chdir(dent->d_name) < 0) | ||
134 | + perror_msg_and_die(dent->d_name); | ||
135 | + stats->ninodes++; | ||
136 | + stats_from_dir(stats); | ||
137 | + chdir(".."); | ||
138 | + } else { | ||
139 | + if (!is_in_ino_dev_hashtable(&st, NULL)) { | ||
140 | + add_to_ino_dev_hashtable(&st, NULL); | ||
141 | + stats->nblocks += (st.st_blocks >> 1); | ||
142 | + stats->ninodes++; | ||
143 | + } | ||
144 | + } | ||
145 | + } | ||
146 | + closedir(dh); | ||
147 | + reset_ino_dev_hashtable(); | ||
148 | +} | ||
149 | + | ||
150 | // adds a tree of entries to the filesystem from current dir | ||
151 | void add2fs_from_dir(filesystem *fs, uint32 this_nod) | ||
152 | { | ||
153 | @@ -1436,7 +1557,6 @@ | ||
154 | free_blocks_per_group = nbblocks_per_group - overhead_per_group; | ||
155 | } | ||
156 | nbblocks = nbblocks_per_group * nbgroups + 1; | ||
157 | - | ||
158 | |||
159 | if(!(fs = (filesystem*)calloc(nbblocks, BLOCKSIZE))) | ||
160 | error_msg_and_die("not enough memory for filesystem"); | ||
161 | @@ -1891,6 +2011,7 @@ | ||
162 | Regular files must exist in the target root directory. If a char, | ||
163 | block, fifo, or directory does not exist, it will be created. | ||
164 | */ | ||
165 | + | ||
166 | static int interpret_table_entry(filesystem *fs, char *line) | ||
167 | { | ||
168 | char type, *name = NULL, *tmp, *dir, *bname; | ||
169 | @@ -2026,6 +2147,52 @@ | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | +static int stats_from_table_entry(char *line, struct stats *stats) | ||
174 | +{ | ||
175 | + char type, *name = NULL, *tmp, *dir, *bname; | ||
176 | + unsigned long mode = 0755, uid = 0, gid = 0, major = 0, minor = 0; | ||
177 | + unsigned long start = 0, increment = 1, count = 0; | ||
178 | + inode *entry; | ||
179 | + | ||
180 | + if (sscanf (line, "%" SCANF_PREFIX "s %c %lo %lu %lu %lu %lu %lu %lu %lu", | ||
181 | + SCANF_STRING(name), &type, &mode, &uid, &gid, &major, &minor, | ||
182 | + &start, &increment, &count) < 0) | ||
183 | + { | ||
184 | + return 1; | ||
185 | + } | ||
186 | + | ||
187 | + if (!strcmp(name, "/")) { | ||
188 | + error_msg_and_die("Device table entries require absolute paths"); | ||
189 | + } | ||
190 | + | ||
191 | + tmp = xstrdup(name); | ||
192 | + bname = xstrdup(basename(tmp)); | ||
193 | + free(tmp); | ||
194 | + switch (type) { | ||
195 | + case 'd': | ||
196 | + stats->ninodes++; | ||
197 | + break; | ||
198 | + case 'c': | ||
199 | + case 'b': | ||
200 | + if (count > 0) { | ||
201 | + dev_t rdev; | ||
202 | + char *dname; | ||
203 | + unsigned long i; | ||
204 | + for (i = start; i < count; i++) { | ||
205 | + asprintf(&dname, "%s%lu", bname, i); | ||
206 | + stats->ninodes++; | ||
207 | + free(dname); | ||
208 | + } | ||
209 | + } else { | ||
210 | + stats->ninodes++; | ||
211 | + } | ||
212 | + break; | ||
213 | + } | ||
214 | + free(bname); | ||
215 | + free(name); | ||
216 | + return 0; | ||
217 | +} | ||
218 | + | ||
219 | static int parse_device_table(filesystem *root, FILE * file) | ||
220 | { | ||
221 | char *line; | ||
222 | @@ -2070,6 +2237,45 @@ | ||
223 | return status; | ||
224 | } | ||
225 | |||
226 | +static int stats_from_dev_table(FILE *file, struct stats *stats) | ||
227 | +{ | ||
228 | + char *line; | ||
229 | + int status = 0; | ||
230 | + size_t length = 0; | ||
231 | + | ||
232 | + /* Looks ok so far. The general plan now is to read in one | ||
233 | + * line at a time, check for leading comment delimiters ('#'), | ||
234 | + * then try and parse the line as a device table. If we fail | ||
235 | + * to parse things, try and help the poor fool to fix their | ||
236 | + * device table with a useful error msg... */ | ||
237 | + line = NULL; | ||
238 | + while (getline(&line, &length, file) != -1) { | ||
239 | + /* First trim off any whitespace */ | ||
240 | + int len = strlen(line); | ||
241 | + | ||
242 | + /* trim trailing whitespace */ | ||
243 | + while (len > 0 && isspace(line[len - 1])) | ||
244 | + line[--len] = '\0'; | ||
245 | + /* trim leading whitespace */ | ||
246 | + memmove(line, &line[strspn(line, " \n\r\t\v")], len); | ||
247 | + | ||
248 | + /* How long are we after trimming? */ | ||
249 | + len = strlen(line); | ||
250 | + | ||
251 | + /* If this is NOT a comment line, try to interpret it */ | ||
252 | + if (len && *line != '#') { | ||
253 | + if (stats_from_table_entry(line, stats)) | ||
254 | + status = 1; | ||
255 | + } | ||
256 | + | ||
257 | + free(line); | ||
258 | + line = NULL; | ||
259 | + } | ||
260 | + fclose(file); | ||
261 | + | ||
262 | + return status; | ||
263 | +} | ||
264 | + | ||
265 | /* | ||
266 | Local Variables: | ||
267 | c-file-style: "linux" | ||
268 | @@ -2112,6 +2318,8 @@ | ||
269 | int nbblocks = -1; | ||
270 | int nbinodes = -1; | ||
271 | int nbresrvd = -1; | ||
272 | + int tmp_nbblocks = -1; | ||
273 | + int tmp_nbinodes = -1; | ||
274 | char * fsout = "-"; | ||
275 | char * fsin = 0; | ||
276 | char * dopt[MAX_DOPT]; | ||
277 | @@ -2128,6 +2336,7 @@ | ||
278 | int c; | ||
279 | struct stat sb; | ||
280 | FILE *devtable = NULL; | ||
281 | + struct stats stats; | ||
282 | |||
283 | app_name = argv[0]; | ||
284 | while((c = getopt(argc, argv, "x:d:b:i:r:g:e:zvhD:f:qUP")) != EOF) | ||
285 | @@ -2184,6 +2393,7 @@ | ||
286 | default: | ||
287 | exit(1); | ||
288 | } | ||
289 | + | ||
290 | if(optind < (argc - 1)) | ||
291 | error_msg_and_die("too many arguments"); | ||
292 | if(optind == (argc - 1)) | ||
293 | @@ -2201,6 +2411,46 @@ | ||
294 | } | ||
295 | else | ||
296 | { | ||
297 | + stats.ninodes = 0; | ||
298 | + stats.nblocks = 0; | ||
299 | + for(i = 0; i < didx; i++) | ||
300 | + { | ||
301 | + struct stat st; | ||
302 | + char *pdir; | ||
303 | + stat(dopt[i], &st); | ||
304 | + switch(st.st_mode & S_IFMT) | ||
305 | + { | ||
306 | + case S_IFDIR: | ||
307 | + if(!(pdir = getcwd(0, GETCWD_SIZE))) | ||
308 | + perror_msg_and_die(dopt[i]); | ||
309 | + if(chdir(dopt[i]) < 0) | ||
310 | + perror_msg_and_die(dopt[i]); | ||
311 | + stats_from_dir(&stats); | ||
312 | + if(chdir(pdir) < 0) | ||
313 | + perror_msg_and_die(pdir); | ||
314 | + free(pdir); | ||
315 | + break; | ||
316 | + default: | ||
317 | + error_msg_and_die("%s is neither a file nor a directory", dopt[i]); | ||
318 | + } | ||
319 | + } | ||
320 | + | ||
321 | + if(devtable) | ||
322 | + stats_from_dev_table(devtable, &stats); | ||
323 | + | ||
324 | + tmp_nbinodes = stats.ninodes + EXT2_FIRST_INO + 1; | ||
325 | + tmp_nbblocks = stats.nblocks; | ||
326 | + | ||
327 | + if(tmp_nbblocks > nbblocks) | ||
328 | + { | ||
329 | + printf("Number of blocks too low, increasing to %d\n",tmp_nbblocks); | ||
330 | + nbblocks = tmp_nbblocks; | ||
331 | + } | ||
332 | + if(tmp_nbinodes > nbinodes) | ||
333 | + { | ||
334 | + printf("Number of inodes too low, increasing to %d\n",tmp_nbinodes); | ||
335 | + nbinodes = tmp_nbinodes; | ||
336 | + } | ||
337 | if(nbblocks == -1) | ||
338 | error_msg_and_die("filesystem size unspecified"); | ||
339 | if(nbinodes == -1) | ||