summaryrefslogtreecommitdiffstats
path: root/meta/packages/genext2fs/genext2fs-1.3/autosize.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/genext2fs/genext2fs-1.3/autosize.patch')
-rw-r--r--meta/packages/genext2fs/genext2fs-1.3/autosize.patch339
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)