summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/dosfstools/dosfstools/fix_populated_dosfs_creation.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/dosfstools/dosfstools/fix_populated_dosfs_creation.patch')
-rw-r--r--meta/recipes-devtools/dosfstools/dosfstools/fix_populated_dosfs_creation.patch489
1 files changed, 489 insertions, 0 deletions
diff --git a/meta/recipes-devtools/dosfstools/dosfstools/fix_populated_dosfs_creation.patch b/meta/recipes-devtools/dosfstools/dosfstools/fix_populated_dosfs_creation.patch
new file mode 100644
index 0000000000..9d7f7321ac
--- /dev/null
+++ b/meta/recipes-devtools/dosfstools/dosfstools/fix_populated_dosfs_creation.patch
@@ -0,0 +1,489 @@
1Upstream-Status: Inappropriate
2
3This patch fixes populated dosfs image creation with directory
4structures. Earlier it was causing segfault; and only image
5population with no subdirectories was working.
6
7Issues fixed:
81. (dir->count == dir->entries) check was only needed for root
9 directory entries. And this check is wrong for non-root
10 directories.
112. For each dir entry 2 dir->table entries were needed, one for
12 the file/dir and 2nd for long file name support. Earlier long
13 name support was added for filenames but the 2nd entry
14 allocation, initialization & counting was missed.
153. The memory clearing was missed at the code path after dir->table
16 memroy allocation.
174. Add entries for . & .. directories in all non-root directories.
185. The . directory points to the correct entry in fat now.
196. All directoriy entries' size was not zero as required for dosfsck,
20 Now all directory entries' size is zero.
21
22Enhancements:
231. Added support for long names for directory names. This is same
24 as the existing long name support for filenames.
252. Added error messages for previously silent memory allocation and
26 other errors.
273. -d options does not work correctly with fat32, so now throwing
28 an error for that.
294. Use predefined structures from kernel's msdos_fs.h file, rather
30 than defining again here. And accordingly change the names & use
31 of structure variables.
32
33Outstanding Issues:
341. The .. directory entry do not point to the parent of current
35 directory. This issue can be fixed by running dosfsck -a after
36 image creation.
372. For files the filesize is correct, but the clusters size is more
38 than it needs to be, this also can be fixed by running dosfsck -a
39 after image creation.
40
41Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
422011/12/13
43
44
45Index: dosfstools-2.11/mkdosfs/mkdosfs.c
46===================================================================
47--- dosfstools-2.11.orig/mkdosfs/mkdosfs.c
48+++ dosfstools-2.11/mkdosfs/mkdosfs.c
49@@ -21,7 +21,17 @@
50 June 2004 - Jordan Crouse (info.linux@amd.com)
51 Added -d <directory> support to populate the image
52 Copyright (C) 2004, Advanced Micro Devices, All Rights Reserved
53-
54+
55+ 2011-12-13: Nitin A Kamble <nitin.a.kamble@intel.com>
56+ Enhanced the -d <directory> support for population of image while
57+ creation. Earlier subdirectores support was broken, only files in
58+ the rootdir were supported. Now directory hirarchy is supported.
59+ Also added long filename support to directory names.
60+ The -d <directory> option (image population while creation)
61+ is broken with fat32.
62+ Copyright (C) 2011, Intel Corporation, All Rights Reserved
63+
64+
65 Fixes/additions May 1998 by Roman Hodek
66 <Roman.Hodek@informatik.uni-erlangen.de>:
67 - Atari format support
68@@ -86,23 +96,23 @@
69 # undef __KERNEL__
70 #endif
71
72-#if __BYTE_ORDER == __BIG_ENDIAN
73-
74+#ifndef __ASM_STUB_BYTEORDER_H__
75 #include <asm/byteorder.h>
76-#ifdef __le16_to_cpu
77-/* ++roman: 2.1 kernel headers define these function, they're probably more
78- * efficient then coding the swaps machine-independently. */
79-#define CF_LE_W __le16_to_cpu
80-#define CF_LE_L __le32_to_cpu
81-#define CT_LE_W __cpu_to_le16
82-#define CT_LE_L __cpu_to_le32
83-#else
84-#define CF_LE_W(v) ((((v) & 0xff) << 8) | (((v) >> 8) & 0xff))
85-#define CF_LE_L(v) (((unsigned)(v)>>24) | (((unsigned)(v)>>8)&0xff00) | \
86- (((unsigned)(v)<<8)&0xff0000) | ((unsigned)(v)<<24))
87+#endif
88+
89+#include <linux/msdos_fs.h>
90+
91+#undef CF_LE_W
92+#undef CF_LE_L
93+#undef CT_LE_W
94+#undef CT_LE_L
95+
96+#if __BYTE_ORDER == __BIG_ENDIAN
97+#include <byteswap.h>
98+#define CF_LE_W(v) bswap_16(v)
99+#define CF_LE_L(v) bswap_32(v)
100 #define CT_LE_W(v) CF_LE_W(v)
101 #define CT_LE_L(v) CF_LE_L(v)
102-#endif /* defined(__le16_to_cpu) */
103
104 #else
105
106@@ -253,33 +263,6 @@ struct fat32_fsinfo {
107 __u32 reserved2[4];
108 };
109
110-/* This stores up to 13 chars of the name */
111-
112-struct msdos_dir_slot {
113- __u8 id; /* sequence number for slot */
114- __u8 name0_4[10]; /* first 5 characters in name */
115- __u8 attr; /* attribute byte */
116- __u8 reserved; /* always 0 */
117- __u8 alias_checksum; /* checksum for 8.3 alias */
118- __u8 name5_10[12]; /* 6 more characters in name */
119- __u16 start; /* starting cluster number, 0 in long slots */
120- __u8 name11_12[4]; /* last 2 characters in name */
121-};
122-
123-struct msdos_dir_entry
124- {
125- char name[8], ext[3]; /* name and extension */
126- __u8 attr; /* attribute bits */
127- __u8 lcase; /* Case for base and extension */
128- __u8 ctime_ms; /* Creation time, milliseconds */
129- __u16 ctime; /* Creation time */
130- __u16 cdate; /* Creation date */
131- __u16 adate; /* Last access date */
132- __u16 starthi; /* high 16 bits of first cl. (FAT32) */
133- __u16 time, date, start; /* time, date and first cluster */
134- __u32 size; /* file size (in bytes) */
135- } __attribute__ ((packed));
136-
137 /* The "boot code" we put into the filesystem... it writes a message and
138 tells the user to try again */
139
140@@ -356,7 +339,6 @@ static struct msdos_dir_entry *root_dir;
141 static int size_root_dir; /* Size of the root directory in bytes */
142 static int sectors_per_cluster = 0; /* Number of sectors per disk cluster */
143 static int root_dir_entries = 0; /* Number of root directory entries */
144-static int root_dir_num_entries = 0;
145 static int last_cluster_written = 0;
146
147 static char *blank_sector; /* Blank sector - all zeros */
148@@ -1315,7 +1297,7 @@ setup_tables (void)
149 de->date = CT_LE_W((unsigned short)(ctime->tm_mday +
150 ((ctime->tm_mon+1) << 5) +
151 ((ctime->tm_year-80) << 9)));
152- de->ctime_ms = 0;
153+ de->ctime_cs = 0;
154 de->ctime = de->time;
155 de->cdate = de->date;
156 de->adate = de->date;
157@@ -1451,16 +1433,23 @@ write_tables (void)
158
159 /* Add a file to the specified directory entry, and also write it into the image */
160
161-static void copy_filename(char *filename, char *base, char *ext) {
162+static void copy_filename(char *filename, char *dos_name) {
163
164 char *ch = filename;
165 int i, len;
166
167- memset(base, 0x20, 8);
168- memset(ext, 0x20, 3);
169+ if (!strcmp(filename, ".")) {
170+ strncpy(dos_name, MSDOS_DOT, MSDOS_NAME);
171+ return;
172+ }
173+ if (!strcmp(filename, "..")) {
174+ strncpy(dos_name, MSDOS_DOTDOT, MSDOS_NAME);
175+ return;
176+ }
177+ memset(dos_name, 0x20, MSDOS_NAME);
178
179 for(len = 0 ; *ch && *ch != '.'; ch++) {
180- base[len++] = toupper(*ch);
181+ dos_name[len++] = toupper(*ch);
182 if (len == 8) break;
183 }
184
185@@ -1468,7 +1457,7 @@ static void copy_filename(char *filename
186 if (*ch) ch++;
187
188 for(len = 0 ; *ch; ch++) {
189- ext[len++] = toupper(*ch);
190+ dos_name[8 + len++] = toupper(*ch);
191 if (len == 3) break;
192 }
193 }
194@@ -1551,7 +1540,7 @@ static int add_file(char *filename, stru
195 int start;
196 int usedsec, totalsec;
197
198- char name83[8], ext83[3];
199+ char dos_name[MSDOS_NAME+1];
200
201 struct msdos_dir_slot *slot;
202 int i;
203@@ -1562,23 +1551,22 @@ static int add_file(char *filename, stru
204 if (dir->root) {
205 if (dir->count == dir->entries) {
206 printf("Error - too many directory entries\n");
207+ return;
208 }
209 }
210 else {
211- if (dir->count == dir->entries) {
212- if (!dir->table)
213- dir->table =
214- (struct msdos_dir_entry *) malloc(sizeof(struct msdos_dir_entry));
215- else {
216- dir->table =
217- (struct msdos_dir_entry *) realloc(dir->table, (dir->entries + 1) *
218- sizeof(struct msdos_dir_entry));
219-
220- memset(&dir->table[dir->entries], 0, sizeof(struct msdos_dir_entry));
221- }
222-
223- dir->entries++;
224- }
225+ /* 2 entries, one extra for long filename */
226+ if (!dir->table)
227+ dir->table =
228+ (struct msdos_dir_entry *) malloc(2 * sizeof(struct msdos_dir_entry));
229+ else
230+ dir->table =
231+ (struct msdos_dir_entry *) realloc(dir->table, 2 * (dir->entries + 1) *
232+ sizeof(struct msdos_dir_entry));
233+ if (!dir->table)
234+ printf("Error - realloc failed\n");
235+ memset(&dir->table[dir->entries], 0, 2 * sizeof(struct msdos_dir_entry));
236+ dir->entries += 2;
237 }
238
239 infile = open(filename, O_RDONLY, 0);
240@@ -1611,13 +1599,13 @@ static int add_file(char *filename, stru
241 return -1;
242 }
243
244- printf("ADD %s\n", filename);
245+ printf("ADD FILE %s\n", filename);
246
247 /* Grab the basename of the file */
248 base = basename(filename);
249
250- /* Extract out the 8.3 name */
251- copy_filename(base, name83, ext83);
252+ /* convert for dos fat structure */
253+ copy_filename(base, dos_name);
254
255 /* Make an extended name slot */
256
257@@ -1629,12 +1617,9 @@ static int add_file(char *filename, stru
258
259 slot->alias_checksum = 0;
260
261- for(i = 0; i < 8; i++)
262- slot->alias_checksum = (((slot->alias_checksum&1)<<7)|((slot->alias_checksum&0xfe)>>1)) + name83[i];
263+ for(i = 0; i < MSDOS_NAME; i++)
264+ slot->alias_checksum = (((slot->alias_checksum&1)<<7)|((slot->alias_checksum&0xfe)>>1)) + dos_name[i];
265
266- for(i = 0; i < 3; i++)
267- slot->alias_checksum = (((slot->alias_checksum&1)<<7)|((slot->alias_checksum&0xfe)>>1)) + ext83[i];
268-
269 p = base;
270
271 copy_name(slot->name0_4, 10, &p);
272@@ -1645,8 +1630,7 @@ static int add_file(char *filename, stru
273 /* Get the entry from the root filesytem */
274 entry = &dir->table[dir->count++];
275
276- strncpy(entry->name, name83, 8);
277- strncpy(entry->ext, ext83, 3);
278+ strncpy(entry->name, dos_name, MSDOS_NAME);
279
280
281 /* If the user has it read only, then add read only to the incoming
282@@ -1665,7 +1649,7 @@ static int add_file(char *filename, stru
283 ((ctime->tm_mon+1) << 5) +
284 ((ctime->tm_year-80) << 9)));
285
286- entry->ctime_ms = 0;
287+ entry->ctime_cs = 0;
288 entry->ctime = entry->time;
289 entry->cdate = entry->date;
290 entry->adate = entry->date;
291@@ -1711,6 +1695,7 @@ static int add_file(char *filename, stru
292
293 exit_add:
294 if (infile) close(infile);
295+ return 0;
296 }
297
298 /* Add a new directory to the specified directory entry, and in turn populate
299@@ -1727,10 +1712,18 @@ static void add_directory(char *filename
300 struct dirent *dentry = 0;
301 int remain;
302 char *data;
303+ char *base;
304+ char dos_name[MSDOS_NAME+1];
305+ struct msdos_dir_slot *slot;
306+ int i;
307+ char *p;
308
309 /* If the directory doesn't exist */
310- if (!rddir) return;
311-
312+ if (!rddir) {
313+ printf("Error - dir does not exist: %s\n", filename);
314+ return;
315+ }
316+
317 if (dir->root) {
318 if (dir->count == dir->entries) {
319 printf("Error - too many directory entries\n");
320@@ -1738,28 +1731,58 @@ static void add_directory(char *filename
321 }
322 }
323 else {
324- if (dir->count == dir->entries) {
325- if (!dir->table)
326- dir->table = (struct msdos_dir_entry *) malloc(sizeof(struct msdos_dir_entry));
327- else {
328- dir->table = (struct msdos_dir_entry *) realloc(dir->table, (dir->entries + 1) *
329- sizeof(struct msdos_dir_entry));
330-
331- /* Zero it out to avoid issues */
332- memset(&dir->table[dir->entries], 0, sizeof(struct msdos_dir_entry));
333- }
334- dir->entries++;
335+ /* 2 entries, one extra for long name of the directory */
336+ if (!dir->table)
337+ dir->table = (struct msdos_dir_entry *) malloc(2 * sizeof(struct msdos_dir_entry));
338+ else
339+ dir->table = (struct msdos_dir_entry *) realloc(dir->table, 2 * (dir->entries + 1) *
340+ sizeof(struct msdos_dir_entry));
341+ if (!dir->table) {
342+ printf("Error - memory allocation failed\n");
343+ goto exit_add_dir;
344 }
345+ /* Zero it out to avoid issues */
346+ memset(&dir->table[dir->entries], 0, 2 * sizeof(struct msdos_dir_entry));
347+ dir->entries += 2;
348 }
349
350+ printf("ADD DIR %s\n", filename);
351 /* Now, create a new directory entry for the new directory */
352 newdir = (struct dir_entry *) calloc(1, sizeof(struct dir_entry));
353- if (!newdir) goto exit_add_dir;
354+ if (!newdir) {
355+ printf("Error - calloc failed\n");
356+ goto exit_add_dir;
357+ }
358+
359+ /* Grab the basename of the file */
360+ base = basename(filename);
361+
362+ /* convert for dos structure */
363+ copy_filename(base, dos_name);
364+
365+ /* Make an extended name slot */
366+ slot = (struct msdos_dir_slot *) &dir->table[dir->count++];
367+ slot->id = 'A';
368+ slot->attr = 0x0F;
369+ slot->reserved = 0;
370+ slot->start = 0;
371+
372+ slot->alias_checksum = 0;
373
374+ for (i = 0; i < MSDOS_NAME; i++)
375+ slot->alias_checksum = (((slot->alias_checksum&1)<<7)|((slot->alias_checksum&0xfe)>>1)) + dos_name[i];
376+
377+ p = base;
378+
379+ copy_name(slot->name0_4, 10, &p);
380+ copy_name(slot->name5_10, 12, &p);
381+ copy_name(slot->name11_12, 4, &p);
382+
383+ /* Get the entry from the root filesytem */
384 entry = &dir->table[dir->count++];
385
386- strncpy(entry->name, basename(filename), sizeof(entry->name));
387-
388+ strncpy(entry->name, dos_name, MSDOS_NAME);
389+
390 entry->attr = ATTR_DIR;
391 ctime = localtime(&create_time);
392
393@@ -1770,25 +1793,32 @@ static void add_directory(char *filename
394 ((ctime->tm_mon+1) << 5) +
395 ((ctime->tm_year-80) << 9)));
396
397- entry->ctime_ms = 0;
398+ entry->ctime_cs = 0;
399 entry->ctime = entry->time;
400 entry->cdate = entry->date;
401 entry->adate = entry->date;
402
403 /* Now, read the directory */
404
405- while((dentry = readdir(rddir))) {
406+
407+ while((base[0] != '.') && (dentry = readdir(rddir))) {
408 struct stat st;
409 char *buffer;
410-
411- if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, ".."))
412- continue;
413
414- /* DOS wouldn't like a typical unix . (dot) file, so we skip those too */
415- if (dentry->d_name[0] == '.') continue;
416+ if (dentry->d_name[0] == '.') {
417+ /* dos also has . & .. directory entries */
418+ if (! ((!strcmp(dentry->d_name, ".")) || (!strcmp(dentry->d_name, "..")))) {
419+ /* ignore other .* files */
420+ printf("Error - File/Dir name is not dos compatible, ignored: %s\n", dentry->d_name);
421+ continue;
422+ }
423+ }
424
425 buffer = malloc(strlen(filename) + strlen(dentry->d_name) + 3);
426- if (!buffer) continue;
427+ if (!buffer) {
428+ printf("Error - malloc failed\n");
429+ goto exit_add_dir;
430+ }
431
432 sprintf(buffer, "%s/%s", filename, dentry->d_name);
433 if (!stat(buffer, &st)) {
434@@ -1806,11 +1836,23 @@ static void add_directory(char *filename
435 /* Now that the entire directory has been written, go ahead and write the directory
436 entry as well */
437
438+ entry->size = 0; /* a directory has zero size */
439+
440+ if (base[0] == '.') { /* . & .. point to parent's cluster */
441+ goto exit_add_dir;
442+ }
443+
444 entry->start = CT_LE_W(last_cluster_written);
445 entry->starthi = CT_LE_W((last_cluster_written & 0xFFFF0000) >> 16);
446- entry->size = newdir->count * sizeof(struct msdos_dir_entry);
447+
448+/* . dir start points to parent */
449+ newdir->table[1].start = entry->start;
450+/* .. dir points to parent of parent*/
451+/* .. dir start is not set yet, would need more changes to the code,
452+ * but dosfsck can fix these .. entry start pointers correctly */
453+
454+ remain = newdir->count * sizeof(struct msdos_dir_entry);
455
456- remain = entry->size;
457 data = (char *) newdir->table;
458
459 while(remain) {
460@@ -1858,6 +1900,7 @@ static void add_root_directory(char *dir
461
462 if (!newdir) {
463 closedir(dir);
464+ printf("Error - calloc failed!\n");
465 return;
466 }
467
468@@ -1877,7 +1920,10 @@ static void add_root_directory(char *dir
469 if (entry->d_name[0] == '.') continue;
470
471 buffer = malloc(strlen(dirname) + strlen(entry->d_name) + 3);
472- if (!buffer) continue;
473+ if (!buffer) {
474+ printf("Error - malloc failed!\n");
475+ continue;
476+ }
477
478 sprintf(buffer, "%s/%s", dirname, entry->d_name);
479 if (!stat(buffer, &st)) {
480@@ -2245,6 +2291,9 @@ main (int argc, char **argv)
481 if (check && listfile) /* Auto and specified bad block handling are mutually */
482 die ("-c and -l are incompatible"); /* exclusive of each other! */
483
484+ if (dirname && (size_fat == 32))
485+ die ("-d is incompatible with FAT32");
486+
487 if (!create) {
488 check_mount (device_name); /* Is the device already mounted? */
489 dev = open (device_name, O_RDWR); /* Is it a suitable device to build the FS on? */