xref: /openbmc/qemu/block/vvfat.c (revision 27e08bab)
1 /* vim:set shiftwidth=4 ts=4: */
2 /*
3  * QEMU Block driver for virtual VFAT (shadows a local directory)
4  *
5  * Copyright (c) 2004,2005 Johannes E. Schindelin
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 
26 #include "qemu/osdep.h"
27 #include <dirent.h>
28 #include "qapi/error.h"
29 #include "block/block_int.h"
30 #include "block/qdict.h"
31 #include "qemu/module.h"
32 #include "qemu/option.h"
33 #include "qemu/bswap.h"
34 #include "migration/blocker.h"
35 #include "qapi/qmp/qdict.h"
36 #include "qapi/qmp/qstring.h"
37 #include "qemu/ctype.h"
38 #include "qemu/cutils.h"
39 #include "qemu/error-report.h"
40 
41 #ifndef S_IWGRP
42 #define S_IWGRP 0
43 #endif
44 #ifndef S_IWOTH
45 #define S_IWOTH 0
46 #endif
47 
48 /* TODO: add ":bootsector=blabla.img:" */
49 /* LATER TODO: add automatic boot sector generation from
50     BOOTEASY.ASM and Ranish Partition Manager
51     Note that DOS assumes the system files to be the first files in the
52     file system (test if the boot sector still relies on that fact)! */
53 /* MAYBE TODO: write block-visofs.c */
54 /* TODO: call try_commit() only after a timeout */
55 
56 /* #define DEBUG */
57 
58 #ifdef DEBUG
59 
60 #define DLOG(a) a
61 
62 static void checkpoint(void);
63 
64 #else
65 
66 #define DLOG(a)
67 
68 #endif
69 
70 /* bootsector OEM name. see related compatibility problems at:
71  * https://jdebp.eu/FGA/volume-boot-block-oem-name-field.html
72  * http://seasip.info/Misc/oemid.html
73  */
74 #define BOOTSECTOR_OEM_NAME "MSWIN4.1"
75 
76 #define DIR_DELETED 0xe5
77 #define DIR_KANJI DIR_DELETED
78 #define DIR_KANJI_FAKE 0x05
79 #define DIR_FREE 0x00
80 
81 /* dynamic array functions */
82 typedef struct array_t {
83     char* pointer;
84     unsigned int size,next,item_size;
85 } array_t;
86 
87 static inline void array_init(array_t* array,unsigned int item_size)
88 {
89     array->pointer = NULL;
90     array->size=0;
91     array->next=0;
92     array->item_size=item_size;
93 }
94 
95 static inline void array_free(array_t* array)
96 {
97     g_free(array->pointer);
98     array->size=array->next=0;
99 }
100 
101 /* does not automatically grow */
102 static inline void* array_get(array_t* array,unsigned int index) {
103     assert(index < array->next);
104     assert(array->pointer);
105     return array->pointer + index * array->item_size;
106 }
107 
108 static inline void array_ensure_allocated(array_t *array, int index)
109 {
110     if((index + 1) * array->item_size > array->size) {
111         int new_size = (index + 32) * array->item_size;
112         array->pointer = g_realloc(array->pointer, new_size);
113         assert(array->pointer);
114         memset(array->pointer + array->size, 0, new_size - array->size);
115         array->size = new_size;
116         array->next = index + 1;
117     }
118 }
119 
120 static inline void* array_get_next(array_t* array) {
121     unsigned int next = array->next;
122 
123     array_ensure_allocated(array, next);
124     array->next = next + 1;
125     return array_get(array, next);
126 }
127 
128 static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
129     if((array->next+count)*array->item_size>array->size) {
130         int increment=count*array->item_size;
131         array->pointer=g_realloc(array->pointer,array->size+increment);
132         if(!array->pointer)
133             return NULL;
134         array->size+=increment;
135     }
136     memmove(array->pointer+(index+count)*array->item_size,
137                 array->pointer+index*array->item_size,
138                 (array->next-index)*array->item_size);
139     array->next+=count;
140     return array->pointer+index*array->item_size;
141 }
142 
143 static inline int array_remove_slice(array_t* array,int index, int count)
144 {
145     assert(index >=0);
146     assert(count > 0);
147     assert(index + count <= array->next);
148 
149     memmove(array->pointer + index * array->item_size,
150             array->pointer + (index + count) * array->item_size,
151             (array->next - index - count) * array->item_size);
152 
153     array->next -= count;
154     return 0;
155 }
156 
157 static int array_remove(array_t* array,int index)
158 {
159     return array_remove_slice(array, index, 1);
160 }
161 
162 /* return the index for a given member */
163 static int array_index(array_t* array, void* pointer)
164 {
165     size_t offset = (char*)pointer - array->pointer;
166     assert((offset % array->item_size) == 0);
167     assert(offset/array->item_size < array->next);
168     return offset/array->item_size;
169 }
170 
171 /* These structures are used to fake a disk and the VFAT filesystem.
172  * For this reason we need to use QEMU_PACKED. */
173 
174 typedef struct bootsector_t {
175     uint8_t jump[3];
176     uint8_t name[8];
177     uint16_t sector_size;
178     uint8_t sectors_per_cluster;
179     uint16_t reserved_sectors;
180     uint8_t number_of_fats;
181     uint16_t root_entries;
182     uint16_t total_sectors16;
183     uint8_t media_type;
184     uint16_t sectors_per_fat;
185     uint16_t sectors_per_track;
186     uint16_t number_of_heads;
187     uint32_t hidden_sectors;
188     uint32_t total_sectors;
189     union {
190         struct {
191             uint8_t drive_number;
192             uint8_t reserved1;
193             uint8_t signature;
194             uint32_t id;
195             uint8_t volume_label[11];
196             uint8_t fat_type[8];
197             uint8_t ignored[0x1c0];
198         } QEMU_PACKED fat16;
199         struct {
200             uint32_t sectors_per_fat;
201             uint16_t flags;
202             uint8_t major,minor;
203             uint32_t first_cluster_of_root_dir;
204             uint16_t info_sector;
205             uint16_t backup_boot_sector;
206             uint8_t reserved[12];
207             uint8_t drive_number;
208             uint8_t reserved1;
209             uint8_t signature;
210             uint32_t id;
211             uint8_t volume_label[11];
212             uint8_t fat_type[8];
213             uint8_t ignored[0x1a4];
214         } QEMU_PACKED fat32;
215     } u;
216     uint8_t magic[2];
217 } QEMU_PACKED bootsector_t;
218 
219 typedef struct {
220     uint8_t head;
221     uint8_t sector;
222     uint8_t cylinder;
223 } mbr_chs_t;
224 
225 typedef struct partition_t {
226     uint8_t attributes; /* 0x80 = bootable */
227     mbr_chs_t start_CHS;
228     uint8_t   fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xe = FAT16_LBA, 0xb = FAT32, 0xc = FAT32_LBA */
229     mbr_chs_t end_CHS;
230     uint32_t start_sector_long;
231     uint32_t length_sector_long;
232 } QEMU_PACKED partition_t;
233 
234 typedef struct mbr_t {
235     uint8_t ignored[0x1b8];
236     uint32_t nt_id;
237     uint8_t ignored2[2];
238     partition_t partition[4];
239     uint8_t magic[2];
240 } QEMU_PACKED mbr_t;
241 
242 typedef struct direntry_t {
243     uint8_t name[8 + 3];
244     uint8_t attributes;
245     uint8_t reserved[2];
246     uint16_t ctime;
247     uint16_t cdate;
248     uint16_t adate;
249     uint16_t begin_hi;
250     uint16_t mtime;
251     uint16_t mdate;
252     uint16_t begin;
253     uint32_t size;
254 } QEMU_PACKED direntry_t;
255 
256 /* this structure are used to transparently access the files */
257 
258 typedef struct mapping_t {
259     /* begin is the first cluster, end is the last+1 */
260     uint32_t begin,end;
261     /* as s->directory is growable, no pointer may be used here */
262     unsigned int dir_index;
263     /* the clusters of a file may be in any order; this points to the first */
264     int first_mapping_index;
265     union {
266         /* offset is
267          * - the offset in the file (in clusters) for a file, or
268          * - the next cluster of the directory for a directory
269          */
270         struct {
271             uint32_t offset;
272         } file;
273         struct {
274             int parent_mapping_index;
275             int first_dir_index;
276         } dir;
277     } info;
278     /* path contains the full path, i.e. it always starts with s->path */
279     char* path;
280 
281     enum {
282         MODE_UNDEFINED = 0,
283         MODE_NORMAL = 1,
284         MODE_MODIFIED = 2,
285         MODE_DIRECTORY = 4,
286         MODE_DELETED = 8,
287     } mode;
288     int read_only;
289 } mapping_t;
290 
291 #ifdef DEBUG
292 static void print_direntry(const struct direntry_t*);
293 static void print_mapping(const struct mapping_t* mapping);
294 #endif
295 
296 /* here begins the real VVFAT driver */
297 
298 typedef struct BDRVVVFATState {
299     CoMutex lock;
300     BlockDriverState* bs; /* pointer to parent */
301     unsigned char first_sectors[0x40*0x200];
302 
303     int fat_type; /* 16 or 32 */
304     array_t fat,directory,mapping;
305     char volume_label[11];
306 
307     uint32_t offset_to_bootsector; /* 0 for floppy, 0x3f for disk */
308 
309     unsigned int cluster_size;
310     unsigned int sectors_per_cluster;
311     unsigned int sectors_per_fat;
312     uint32_t last_cluster_of_root_directory;
313     /* how many entries are available in root directory (0 for FAT32) */
314     uint16_t root_entries;
315     uint32_t sector_count; /* total number of sectors of the partition */
316     uint32_t cluster_count; /* total number of clusters of this partition */
317     uint32_t max_fat_value;
318     uint32_t offset_to_fat;
319     uint32_t offset_to_root_dir;
320 
321     int current_fd;
322     mapping_t* current_mapping;
323     unsigned char* cluster; /* points to current cluster */
324     unsigned char* cluster_buffer; /* points to a buffer to hold temp data */
325     unsigned int current_cluster;
326 
327     /* write support */
328     char* qcow_filename;
329     BdrvChild* qcow;
330     void* fat2;
331     char* used_clusters;
332     array_t commits;
333     const char* path;
334     int downcase_short_names;
335 
336     Error *migration_blocker;
337 } BDRVVVFATState;
338 
339 /* take the sector position spos and convert it to Cylinder/Head/Sector position
340  * if the position is outside the specified geometry, fill maximum value for CHS
341  * and return 1 to signal overflow.
342  */
343 static int sector2CHS(mbr_chs_t *chs, int spos, int cyls, int heads, int secs)
344 {
345     int head,sector;
346     sector   = spos % secs;  spos /= secs;
347     head     = spos % heads; spos /= heads;
348     if (spos >= cyls) {
349         /* Overflow,
350         it happens if 32bit sector positions are used, while CHS is only 24bit.
351         Windows/Dos is said to take 1023/255/63 as nonrepresentable CHS */
352         chs->head     = 0xFF;
353         chs->sector   = 0xFF;
354         chs->cylinder = 0xFF;
355         return 1;
356     }
357     chs->head     = (uint8_t)head;
358     chs->sector   = (uint8_t)( (sector+1) | ((spos>>8)<<6) );
359     chs->cylinder = (uint8_t)spos;
360     return 0;
361 }
362 
363 static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
364 {
365     /* TODO: if the files mbr.img and bootsect.img exist, use them */
366     mbr_t* real_mbr=(mbr_t*)s->first_sectors;
367     partition_t* partition = &(real_mbr->partition[0]);
368     int lba;
369 
370     memset(s->first_sectors,0,512);
371 
372     /* Win NT Disk Signature */
373     real_mbr->nt_id= cpu_to_le32(0xbe1afdfa);
374 
375     partition->attributes=0x80; /* bootable */
376 
377     /* LBA is used when partition is outside the CHS geometry */
378     lba  = sector2CHS(&partition->start_CHS, s->offset_to_bootsector,
379                      cyls, heads, secs);
380     lba |= sector2CHS(&partition->end_CHS,   s->bs->total_sectors - 1,
381                      cyls, heads, secs);
382 
383     /*LBA partitions are identified only by start/length_sector_long not by CHS*/
384     partition->start_sector_long  = cpu_to_le32(s->offset_to_bootsector);
385     partition->length_sector_long = cpu_to_le32(s->bs->total_sectors
386                                                 - s->offset_to_bootsector);
387 
388     /* FAT12/FAT16/FAT32 */
389     /* DOS uses different types when partition is LBA,
390        probably to prevent older versions from using CHS on them */
391     partition->fs_type = s->fat_type == 12 ? 0x1 :
392                          s->fat_type == 16 ? (lba ? 0xe : 0x06) :
393                        /*s->fat_type == 32*/ (lba ? 0xc : 0x0b);
394 
395     real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
396 }
397 
398 /* direntry functions */
399 
400 static direntry_t *create_long_filename(BDRVVVFATState *s, const char *filename)
401 {
402     int number_of_entries, i;
403     glong length;
404     direntry_t *entry;
405 
406     gunichar2 *longname = g_utf8_to_utf16(filename, -1, NULL, &length, NULL);
407     if (!longname) {
408         fprintf(stderr, "vvfat: invalid UTF-8 name: %s\n", filename);
409         return NULL;
410     }
411 
412     number_of_entries = DIV_ROUND_UP(length * 2, 26);
413 
414     for(i=0;i<number_of_entries;i++) {
415         entry=array_get_next(&(s->directory));
416         entry->attributes=0xf;
417         entry->reserved[0]=0;
418         entry->begin=0;
419         entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
420     }
421     for(i=0;i<26*number_of_entries;i++) {
422         int offset=(i%26);
423         if(offset<10) offset=1+offset;
424         else if(offset<22) offset=14+offset-10;
425         else offset=28+offset-22;
426         entry=array_get(&(s->directory),s->directory.next-1-(i/26));
427         if (i >= 2 * length + 2) {
428             entry->name[offset] = 0xff;
429         } else if (i % 2 == 0) {
430             entry->name[offset] = longname[i / 2] & 0xff;
431         } else {
432             entry->name[offset] = longname[i / 2] >> 8;
433         }
434     }
435     g_free(longname);
436     return array_get(&(s->directory),s->directory.next-number_of_entries);
437 }
438 
439 static char is_free(const direntry_t* direntry)
440 {
441     return direntry->name[0] == DIR_DELETED || direntry->name[0] == DIR_FREE;
442 }
443 
444 static char is_volume_label(const direntry_t* direntry)
445 {
446     return direntry->attributes == 0x28;
447 }
448 
449 static char is_long_name(const direntry_t* direntry)
450 {
451     return direntry->attributes == 0xf;
452 }
453 
454 static char is_short_name(const direntry_t* direntry)
455 {
456     return !is_volume_label(direntry) && !is_long_name(direntry)
457         && !is_free(direntry);
458 }
459 
460 static char is_directory(const direntry_t* direntry)
461 {
462     return direntry->attributes & 0x10 && direntry->name[0] != DIR_DELETED;
463 }
464 
465 static inline char is_dot(const direntry_t* direntry)
466 {
467     return is_short_name(direntry) && direntry->name[0] == '.';
468 }
469 
470 static char is_file(const direntry_t* direntry)
471 {
472     return is_short_name(direntry) && !is_directory(direntry);
473 }
474 
475 static inline uint32_t begin_of_direntry(const direntry_t* direntry)
476 {
477     return le16_to_cpu(direntry->begin)|(le16_to_cpu(direntry->begin_hi)<<16);
478 }
479 
480 static inline uint32_t filesize_of_direntry(const direntry_t* direntry)
481 {
482     return le32_to_cpu(direntry->size);
483 }
484 
485 static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
486 {
487     direntry->begin = cpu_to_le16(begin & 0xffff);
488     direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
489 }
490 
491 static bool valid_filename(const unsigned char *name)
492 {
493     unsigned char c;
494     if (!strcmp((const char*)name, ".") || !strcmp((const char*)name, "..")) {
495         return false;
496     }
497     for (; (c = *name); name++) {
498         if (!((c >= '0' && c <= '9') ||
499               (c >= 'A' && c <= 'Z') ||
500               (c >= 'a' && c <= 'z') ||
501               c > 127 ||
502               strchr("$%'-_@~`!(){}^#&.+,;=[]", c) != NULL))
503         {
504             return false;
505         }
506     }
507     return true;
508 }
509 
510 static uint8_t to_valid_short_char(gunichar c)
511 {
512     c = g_unichar_toupper(c);
513     if ((c >= '0' && c <= '9') ||
514         (c >= 'A' && c <= 'Z') ||
515         strchr("$%'-_@~`!(){}^#&", c) != NULL) {
516         return c;
517     } else {
518         return 0;
519     }
520 }
521 
522 static direntry_t *create_short_filename(BDRVVVFATState *s,
523                                          const char *filename,
524                                          unsigned int directory_start)
525 {
526     int i, j = 0;
527     direntry_t *entry = array_get_next(&(s->directory));
528     const gchar *p, *last_dot = NULL;
529     gunichar c;
530     bool lossy_conversion = false;
531     char tail[8];
532 
533     if (!entry) {
534         return NULL;
535     }
536     memset(entry->name, 0x20, sizeof(entry->name));
537 
538     /* copy filename and search last dot */
539     for (p = filename; ; p = g_utf8_next_char(p)) {
540         c = g_utf8_get_char(p);
541         if (c == '\0') {
542             break;
543         } else if (c == '.') {
544             if (j == 0) {
545                 /* '.' at start of filename */
546                 lossy_conversion = true;
547             } else {
548                 if (last_dot) {
549                     lossy_conversion = true;
550                 }
551                 last_dot = p;
552             }
553         } else if (!last_dot) {
554             /* first part of the name; copy it */
555             uint8_t v = to_valid_short_char(c);
556             if (j < 8 && v) {
557                 entry->name[j++] = v;
558             } else {
559                 lossy_conversion = true;
560             }
561         }
562     }
563 
564     /* copy extension (if any) */
565     if (last_dot) {
566         j = 0;
567         for (p = g_utf8_next_char(last_dot); ; p = g_utf8_next_char(p)) {
568             c = g_utf8_get_char(p);
569             if (c == '\0') {
570                 break;
571             } else {
572                 /* extension; copy it */
573                 uint8_t v = to_valid_short_char(c);
574                 if (j < 3 && v) {
575                     entry->name[8 + (j++)] = v;
576                 } else {
577                     lossy_conversion = true;
578                 }
579             }
580         }
581     }
582 
583     if (entry->name[0] == DIR_KANJI) {
584         entry->name[0] = DIR_KANJI_FAKE;
585     }
586 
587     /* numeric-tail generation */
588     for (j = 0; j < 8; j++) {
589         if (entry->name[j] == ' ') {
590             break;
591         }
592     }
593     for (i = lossy_conversion ? 1 : 0; i < 999999; i++) {
594         direntry_t *entry1;
595         if (i > 0) {
596             int len = snprintf(tail, sizeof(tail), "~%u", (unsigned)i);
597             assert(len <= 7);
598             memcpy(entry->name + MIN(j, 8 - len), tail, len);
599         }
600         for (entry1 = array_get(&(s->directory), directory_start);
601              entry1 < entry; entry1++) {
602             if (!is_long_name(entry1) &&
603                 !memcmp(entry1->name, entry->name, 11)) {
604                 break; /* found dupe */
605             }
606         }
607         if (entry1 == entry) {
608             /* no dupe found */
609             return entry;
610         }
611     }
612     return NULL;
613 }
614 
615 /* fat functions */
616 
617 static inline uint8_t fat_chksum(const direntry_t* entry)
618 {
619     uint8_t chksum=0;
620     int i;
621 
622     for (i = 0; i < ARRAY_SIZE(entry->name); i++) {
623         chksum = (((chksum & 0xfe) >> 1) |
624                   ((chksum & 0x01) ? 0x80 : 0)) + entry->name[i];
625     }
626 
627     return chksum;
628 }
629 
630 /* if return_time==0, this returns the fat_date, else the fat_time */
631 static uint16_t fat_datetime(time_t time,int return_time) {
632     struct tm* t;
633     struct tm t1;
634     t = &t1;
635     localtime_r(&time,t);
636     if(return_time)
637         return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
638     return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
639 }
640 
641 static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
642 {
643     if(s->fat_type==32) {
644         uint32_t* entry=array_get(&(s->fat),cluster);
645         *entry=cpu_to_le32(value);
646     } else if(s->fat_type==16) {
647         uint16_t* entry=array_get(&(s->fat),cluster);
648         *entry=cpu_to_le16(value&0xffff);
649     } else {
650         int offset = (cluster*3/2);
651         unsigned char* p = array_get(&(s->fat), offset);
652         switch (cluster&1) {
653         case 0:
654                 p[0] = value&0xff;
655                 p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
656                 break;
657         case 1:
658                 p[0] = (p[0]&0xf) | ((value&0xf)<<4);
659                 p[1] = (value>>4);
660                 break;
661         }
662     }
663 }
664 
665 static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster)
666 {
667     if(s->fat_type==32) {
668         uint32_t* entry=array_get(&(s->fat),cluster);
669         return le32_to_cpu(*entry);
670     } else if(s->fat_type==16) {
671         uint16_t* entry=array_get(&(s->fat),cluster);
672         return le16_to_cpu(*entry);
673     } else {
674         const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
675         return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
676     }
677 }
678 
679 static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry)
680 {
681     if(fat_entry>s->max_fat_value-8)
682         return -1;
683     return 0;
684 }
685 
686 static inline void init_fat(BDRVVVFATState* s)
687 {
688     if (s->fat_type == 12) {
689         array_init(&(s->fat),1);
690         array_ensure_allocated(&(s->fat),
691                 s->sectors_per_fat * 0x200 * 3 / 2 - 1);
692     } else {
693         array_init(&(s->fat),(s->fat_type==32?4:2));
694         array_ensure_allocated(&(s->fat),
695                 s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
696     }
697     memset(s->fat.pointer,0,s->fat.size);
698 
699     switch(s->fat_type) {
700         case 12: s->max_fat_value=0xfff; break;
701         case 16: s->max_fat_value=0xffff; break;
702         case 32: s->max_fat_value=0x0fffffff; break;
703         default: s->max_fat_value=0; /* error... */
704     }
705 
706 }
707 
708 static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
709         unsigned int directory_start, const char* filename, int is_dot)
710 {
711     int long_index = s->directory.next;
712     direntry_t* entry = NULL;
713     direntry_t* entry_long = NULL;
714 
715     if(is_dot) {
716         entry=array_get_next(&(s->directory));
717         memset(entry->name, 0x20, sizeof(entry->name));
718         memcpy(entry->name,filename,strlen(filename));
719         return entry;
720     }
721 
722     entry_long=create_long_filename(s,filename);
723     entry = create_short_filename(s, filename, directory_start);
724 
725     /* calculate checksum; propagate to long name */
726     if(entry_long) {
727         uint8_t chksum=fat_chksum(entry);
728 
729         /* calculate anew, because realloc could have taken place */
730         entry_long=array_get(&(s->directory),long_index);
731         while(entry_long<entry && is_long_name(entry_long)) {
732             entry_long->reserved[1]=chksum;
733             entry_long++;
734         }
735     }
736 
737     return entry;
738 }
739 
740 /*
741  * Read a directory. (the index of the corresponding mapping must be passed).
742  */
743 static int read_directory(BDRVVVFATState* s, int mapping_index)
744 {
745     mapping_t* mapping = array_get(&(s->mapping), mapping_index);
746     direntry_t* direntry;
747     const char* dirname = mapping->path;
748     int first_cluster = mapping->begin;
749     int parent_index = mapping->info.dir.parent_mapping_index;
750     mapping_t* parent_mapping = (mapping_t*)
751         (parent_index >= 0 ? array_get(&(s->mapping), parent_index) : NULL);
752     int first_cluster_of_parent = parent_mapping ? parent_mapping->begin : -1;
753 
754     DIR* dir=opendir(dirname);
755     struct dirent* entry;
756     int i;
757 
758     assert(mapping->mode & MODE_DIRECTORY);
759 
760     if(!dir) {
761         mapping->end = mapping->begin;
762         return -1;
763     }
764 
765     i = mapping->info.dir.first_dir_index =
766             first_cluster == 0 ? 0 : s->directory.next;
767 
768     if (first_cluster != 0) {
769         /* create the top entries of a subdirectory */
770         (void)create_short_and_long_name(s, i, ".", 1);
771         (void)create_short_and_long_name(s, i, "..", 1);
772     }
773 
774     /* actually read the directory, and allocate the mappings */
775     while((entry=readdir(dir))) {
776         unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
777         char* buffer;
778         direntry_t* direntry;
779         struct stat st;
780         int is_dot=!strcmp(entry->d_name,".");
781         int is_dotdot=!strcmp(entry->d_name,"..");
782 
783         if (first_cluster == 0 && s->directory.next >= s->root_entries - 1) {
784             fprintf(stderr, "Too many entries in root directory\n");
785             closedir(dir);
786             return -2;
787         }
788 
789         if(first_cluster == 0 && (is_dotdot || is_dot))
790             continue;
791 
792         buffer = g_malloc(length);
793         snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
794 
795         if(stat(buffer,&st)<0) {
796             g_free(buffer);
797             continue;
798         }
799 
800         /* create directory entry for this file */
801         if (!is_dot && !is_dotdot) {
802             direntry = create_short_and_long_name(s, i, entry->d_name, 0);
803         } else {
804             direntry = array_get(&(s->directory), is_dot ? i : i + 1);
805         }
806         direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
807         direntry->reserved[0]=direntry->reserved[1]=0;
808         direntry->ctime=fat_datetime(st.st_ctime,1);
809         direntry->cdate=fat_datetime(st.st_ctime,0);
810         direntry->adate=fat_datetime(st.st_atime,0);
811         direntry->begin_hi=0;
812         direntry->mtime=fat_datetime(st.st_mtime,1);
813         direntry->mdate=fat_datetime(st.st_mtime,0);
814         if(is_dotdot)
815             set_begin_of_direntry(direntry, first_cluster_of_parent);
816         else if(is_dot)
817             set_begin_of_direntry(direntry, first_cluster);
818         else
819             direntry->begin=0; /* do that later */
820         if (st.st_size > 0x7fffffff) {
821             fprintf(stderr, "File %s is larger than 2GB\n", buffer);
822             g_free(buffer);
823             closedir(dir);
824             return -2;
825         }
826         direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
827 
828         /* create mapping for this file */
829         if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
830             s->current_mapping = array_get_next(&(s->mapping));
831             s->current_mapping->begin=0;
832             s->current_mapping->end=st.st_size;
833             /*
834              * we get the direntry of the most recent direntry, which
835              * contains the short name and all the relevant information.
836              */
837             s->current_mapping->dir_index=s->directory.next-1;
838             s->current_mapping->first_mapping_index = -1;
839             if (S_ISDIR(st.st_mode)) {
840                 s->current_mapping->mode = MODE_DIRECTORY;
841                 s->current_mapping->info.dir.parent_mapping_index =
842                     mapping_index;
843             } else {
844                 s->current_mapping->mode = MODE_UNDEFINED;
845                 s->current_mapping->info.file.offset = 0;
846             }
847             s->current_mapping->path=buffer;
848             s->current_mapping->read_only =
849                 (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
850         } else {
851             g_free(buffer);
852         }
853     }
854     closedir(dir);
855 
856     /* fill with zeroes up to the end of the cluster */
857     while(s->directory.next%(0x10*s->sectors_per_cluster)) {
858         direntry_t* direntry=array_get_next(&(s->directory));
859         memset(direntry,0,sizeof(direntry_t));
860     }
861 
862     if (s->fat_type != 32 &&
863         mapping_index == 0 &&
864         s->directory.next < s->root_entries) {
865         /* root directory */
866         int cur = s->directory.next;
867         array_ensure_allocated(&(s->directory), s->root_entries - 1);
868         s->directory.next = s->root_entries;
869         memset(array_get(&(s->directory), cur), 0,
870                 (s->root_entries - cur) * sizeof(direntry_t));
871     }
872 
873     /* re-get the mapping, since s->mapping was possibly realloc()ed */
874     mapping = array_get(&(s->mapping), mapping_index);
875     first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
876         * 0x20 / s->cluster_size;
877     mapping->end = first_cluster;
878 
879     direntry = array_get(&(s->directory), mapping->dir_index);
880     set_begin_of_direntry(direntry, mapping->begin);
881 
882     return 0;
883 }
884 
885 static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
886 {
887     return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster;
888 }
889 
890 static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
891 {
892     return s->offset_to_root_dir + s->sectors_per_cluster * cluster_num;
893 }
894 
895 static int init_directories(BDRVVVFATState* s,
896                             const char *dirname, int heads, int secs,
897                             Error **errp)
898 {
899     bootsector_t* bootsector;
900     mapping_t* mapping;
901     unsigned int i;
902     unsigned int cluster;
903 
904     memset(&(s->first_sectors[0]),0,0x40*0x200);
905 
906     s->cluster_size=s->sectors_per_cluster*0x200;
907     s->cluster_buffer=g_malloc(s->cluster_size);
908 
909     /*
910      * The formula: sc = spf+1+spf*spc*(512*8/fat_type),
911      * where sc is sector_count,
912      * spf is sectors_per_fat,
913      * spc is sectors_per_clusters, and
914      * fat_type = 12, 16 or 32.
915      */
916     i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
917     s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
918 
919     s->offset_to_fat = s->offset_to_bootsector + 1;
920     s->offset_to_root_dir = s->offset_to_fat + s->sectors_per_fat * 2;
921 
922     array_init(&(s->mapping),sizeof(mapping_t));
923     array_init(&(s->directory),sizeof(direntry_t));
924 
925     /* add volume label */
926     {
927         direntry_t* entry=array_get_next(&(s->directory));
928         entry->attributes=0x28; /* archive | volume label */
929         memcpy(entry->name, s->volume_label, sizeof(entry->name));
930     }
931 
932     /* Now build FAT, and write back information into directory */
933     init_fat(s);
934 
935     /* TODO: if there are more entries, bootsector has to be adjusted! */
936     s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster;
937     s->cluster_count=sector2cluster(s, s->sector_count);
938 
939     mapping = array_get_next(&(s->mapping));
940     mapping->begin = 0;
941     mapping->dir_index = 0;
942     mapping->info.dir.parent_mapping_index = -1;
943     mapping->first_mapping_index = -1;
944     mapping->path = g_strdup(dirname);
945     i = strlen(mapping->path);
946     if (i > 0 && mapping->path[i - 1] == '/')
947         mapping->path[i - 1] = '\0';
948     mapping->mode = MODE_DIRECTORY;
949     mapping->read_only = 0;
950     s->path = mapping->path;
951 
952     for (i = 0, cluster = 0; i < s->mapping.next; i++) {
953         /* MS-DOS expects the FAT to be 0 for the root directory
954          * (except for the media byte). */
955         /* LATER TODO: still true for FAT32? */
956         int fix_fat = (i != 0);
957         mapping = array_get(&(s->mapping), i);
958 
959         if (mapping->mode & MODE_DIRECTORY) {
960             char *path = mapping->path;
961             mapping->begin = cluster;
962             if(read_directory(s, i)) {
963                 error_setg(errp, "Could not read directory %s", path);
964                 return -1;
965             }
966             mapping = array_get(&(s->mapping), i);
967         } else {
968             assert(mapping->mode == MODE_UNDEFINED);
969             mapping->mode=MODE_NORMAL;
970             mapping->begin = cluster;
971             if (mapping->end > 0) {
972                 direntry_t* direntry = array_get(&(s->directory),
973                         mapping->dir_index);
974 
975                 mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
976                 set_begin_of_direntry(direntry, mapping->begin);
977             } else {
978                 mapping->end = cluster + 1;
979                 fix_fat = 0;
980             }
981         }
982 
983         assert(mapping->begin < mapping->end);
984 
985         /* next free cluster */
986         cluster = mapping->end;
987 
988         if(cluster > s->cluster_count) {
989             error_setg(errp,
990                        "Directory does not fit in FAT%d (capacity %.2f MB)",
991                        s->fat_type, s->sector_count / 2000.0);
992             return -1;
993         }
994 
995         /* fix fat for entry */
996         if (fix_fat) {
997             int j;
998             for(j = mapping->begin; j < mapping->end - 1; j++)
999                 fat_set(s, j, j+1);
1000             fat_set(s, mapping->end - 1, s->max_fat_value);
1001         }
1002     }
1003 
1004     mapping = array_get(&(s->mapping), 0);
1005     s->last_cluster_of_root_directory = mapping->end;
1006 
1007     /* the FAT signature */
1008     fat_set(s,0,s->max_fat_value);
1009     fat_set(s,1,s->max_fat_value);
1010 
1011     s->current_mapping = NULL;
1012 
1013     bootsector = (bootsector_t *)(s->first_sectors
1014                                   + s->offset_to_bootsector * 0x200);
1015     bootsector->jump[0]=0xeb;
1016     bootsector->jump[1]=0x3e;
1017     bootsector->jump[2]=0x90;
1018     memcpy(bootsector->name, BOOTSECTOR_OEM_NAME, 8);
1019     bootsector->sector_size=cpu_to_le16(0x200);
1020     bootsector->sectors_per_cluster=s->sectors_per_cluster;
1021     bootsector->reserved_sectors=cpu_to_le16(1);
1022     bootsector->number_of_fats=0x2; /* number of FATs */
1023     bootsector->root_entries = cpu_to_le16(s->root_entries);
1024     bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
1025     /* media descriptor: hard disk=0xf8, floppy=0xf0 */
1026     bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0);
1027     s->fat.pointer[0] = bootsector->media_type;
1028     bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
1029     bootsector->sectors_per_track = cpu_to_le16(secs);
1030     bootsector->number_of_heads = cpu_to_le16(heads);
1031     bootsector->hidden_sectors = cpu_to_le32(s->offset_to_bootsector);
1032     bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
1033 
1034     /* LATER TODO: if FAT32, this is wrong */
1035     /* drive_number: fda=0, hda=0x80 */
1036     bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80;
1037     bootsector->u.fat16.signature=0x29;
1038     bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
1039 
1040     memcpy(bootsector->u.fat16.volume_label, s->volume_label,
1041            sizeof(bootsector->u.fat16.volume_label));
1042     memcpy(bootsector->u.fat16.fat_type,
1043            s->fat_type == 12 ? "FAT12   " : "FAT16   ", 8);
1044     bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
1045 
1046     return 0;
1047 }
1048 
1049 #ifdef DEBUG
1050 static BDRVVVFATState *vvv = NULL;
1051 #endif
1052 
1053 static int enable_write_target(BlockDriverState *bs, Error **errp);
1054 static int is_consistent(BDRVVVFATState *s);
1055 
1056 static QemuOptsList runtime_opts = {
1057     .name = "vvfat",
1058     .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
1059     .desc = {
1060         {
1061             .name = "dir",
1062             .type = QEMU_OPT_STRING,
1063             .help = "Host directory to map to the vvfat device",
1064         },
1065         {
1066             .name = "fat-type",
1067             .type = QEMU_OPT_NUMBER,
1068             .help = "FAT type (12, 16 or 32)",
1069         },
1070         {
1071             .name = "floppy",
1072             .type = QEMU_OPT_BOOL,
1073             .help = "Create a floppy rather than a hard disk image",
1074         },
1075         {
1076             .name = "label",
1077             .type = QEMU_OPT_STRING,
1078             .help = "Use a volume label other than QEMU VVFAT",
1079         },
1080         {
1081             .name = "rw",
1082             .type = QEMU_OPT_BOOL,
1083             .help = "Make the image writable",
1084         },
1085         { /* end of list */ }
1086     },
1087 };
1088 
1089 static void vvfat_parse_filename(const char *filename, QDict *options,
1090                                  Error **errp)
1091 {
1092     int fat_type = 0;
1093     bool floppy = false;
1094     bool rw = false;
1095     int i;
1096 
1097     if (!strstart(filename, "fat:", NULL)) {
1098         error_setg(errp, "File name string must start with 'fat:'");
1099         return;
1100     }
1101 
1102     /* Parse options */
1103     if (strstr(filename, ":32:")) {
1104         fat_type = 32;
1105     } else if (strstr(filename, ":16:")) {
1106         fat_type = 16;
1107     } else if (strstr(filename, ":12:")) {
1108         fat_type = 12;
1109     }
1110 
1111     if (strstr(filename, ":floppy:")) {
1112         floppy = true;
1113     }
1114 
1115     if (strstr(filename, ":rw:")) {
1116         rw = true;
1117     }
1118 
1119     /* Get the directory name without options */
1120     i = strrchr(filename, ':') - filename;
1121     assert(i >= 3);
1122     if (filename[i - 2] == ':' && qemu_isalpha(filename[i - 1])) {
1123         /* workaround for DOS drive names */
1124         filename += i - 1;
1125     } else {
1126         filename += i + 1;
1127     }
1128 
1129     /* Fill in the options QDict */
1130     qdict_put_str(options, "dir", filename);
1131     qdict_put_int(options, "fat-type", fat_type);
1132     qdict_put_bool(options, "floppy", floppy);
1133     qdict_put_bool(options, "rw", rw);
1134 }
1135 
1136 static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
1137                       Error **errp)
1138 {
1139     BDRVVVFATState *s = bs->opaque;
1140     int cyls, heads, secs;
1141     bool floppy;
1142     const char *dirname, *label;
1143     QemuOpts *opts;
1144     Error *local_err = NULL;
1145     int ret;
1146 
1147 #ifdef DEBUG
1148     vvv = s;
1149 #endif
1150 
1151     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
1152     qemu_opts_absorb_qdict(opts, options, &local_err);
1153     if (local_err) {
1154         error_propagate(errp, local_err);
1155         ret = -EINVAL;
1156         goto fail;
1157     }
1158 
1159     dirname = qemu_opt_get(opts, "dir");
1160     if (!dirname) {
1161         error_setg(errp, "vvfat block driver requires a 'dir' option");
1162         ret = -EINVAL;
1163         goto fail;
1164     }
1165 
1166     s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);
1167     floppy = qemu_opt_get_bool(opts, "floppy", false);
1168 
1169     memset(s->volume_label, ' ', sizeof(s->volume_label));
1170     label = qemu_opt_get(opts, "label");
1171     if (label) {
1172         size_t label_length = strlen(label);
1173         if (label_length > 11) {
1174             error_setg(errp, "vvfat label cannot be longer than 11 bytes");
1175             ret = -EINVAL;
1176             goto fail;
1177         }
1178         memcpy(s->volume_label, label, label_length);
1179     } else {
1180         memcpy(s->volume_label, "QEMU VVFAT", 10);
1181     }
1182 
1183     if (floppy) {
1184         /* 1.44MB or 2.88MB floppy.  2.88MB can be FAT12 (default) or FAT16. */
1185         if (!s->fat_type) {
1186             s->fat_type = 12;
1187             secs = 36;
1188             s->sectors_per_cluster = 2;
1189         } else {
1190             secs = s->fat_type == 12 ? 18 : 36;
1191             s->sectors_per_cluster = 1;
1192         }
1193         cyls = 80;
1194         heads = 2;
1195     } else {
1196         /* 32MB or 504MB disk*/
1197         if (!s->fat_type) {
1198             s->fat_type = 16;
1199         }
1200         s->offset_to_bootsector = 0x3f;
1201         cyls = s->fat_type == 12 ? 64 : 1024;
1202         heads = 16;
1203         secs = 63;
1204     }
1205 
1206     switch (s->fat_type) {
1207     case 32:
1208         warn_report("FAT32 has not been tested. You are welcome to do so!");
1209         break;
1210     case 16:
1211     case 12:
1212         break;
1213     default:
1214         error_setg(errp, "Valid FAT types are only 12, 16 and 32");
1215         ret = -EINVAL;
1216         goto fail;
1217     }
1218 
1219 
1220     s->bs = bs;
1221 
1222     /* LATER TODO: if FAT32, adjust */
1223     s->sectors_per_cluster=0x10;
1224 
1225     s->current_cluster=0xffffffff;
1226 
1227     s->qcow = NULL;
1228     s->qcow_filename = NULL;
1229     s->fat2 = NULL;
1230     s->downcase_short_names = 1;
1231 
1232     DLOG(fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
1233                  dirname, cyls, heads, secs));
1234 
1235     s->sector_count = cyls * heads * secs - s->offset_to_bootsector;
1236 
1237     if (qemu_opt_get_bool(opts, "rw", false)) {
1238         if (!bdrv_is_read_only(bs)) {
1239             ret = enable_write_target(bs, errp);
1240             if (ret < 0) {
1241                 goto fail;
1242             }
1243         } else {
1244             ret = -EPERM;
1245             error_setg(errp,
1246                        "Unable to set VVFAT to 'rw' when drive is read-only");
1247             goto fail;
1248         }
1249     } else {
1250         ret = bdrv_apply_auto_read_only(bs, NULL, errp);
1251         if (ret < 0) {
1252             goto fail;
1253         }
1254     }
1255 
1256     bs->total_sectors = cyls * heads * secs;
1257 
1258     if (init_directories(s, dirname, heads, secs, errp)) {
1259         ret = -EIO;
1260         goto fail;
1261     }
1262 
1263     s->sector_count = s->offset_to_root_dir
1264                     + s->sectors_per_cluster * s->cluster_count;
1265 
1266     /* Disable migration when vvfat is used rw */
1267     if (s->qcow) {
1268         error_setg(&s->migration_blocker,
1269                    "The vvfat (rw) format used by node '%s' "
1270                    "does not support live migration",
1271                    bdrv_get_device_or_node_name(bs));
1272         ret = migrate_add_blocker(s->migration_blocker, &local_err);
1273         if (local_err) {
1274             error_propagate(errp, local_err);
1275             error_free(s->migration_blocker);
1276             goto fail;
1277         }
1278     }
1279 
1280     if (s->offset_to_bootsector > 0) {
1281         init_mbr(s, cyls, heads, secs);
1282     }
1283 
1284     qemu_co_mutex_init(&s->lock);
1285 
1286     ret = 0;
1287 fail:
1288     qemu_opts_del(opts);
1289     return ret;
1290 }
1291 
1292 static void vvfat_refresh_limits(BlockDriverState *bs, Error **errp)
1293 {
1294     bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
1295 }
1296 
1297 static inline void vvfat_close_current_file(BDRVVVFATState *s)
1298 {
1299     if(s->current_mapping) {
1300         s->current_mapping = NULL;
1301         if (s->current_fd) {
1302                 qemu_close(s->current_fd);
1303                 s->current_fd = 0;
1304         }
1305     }
1306     s->current_cluster = -1;
1307 }
1308 
1309 /* mappings between index1 and index2-1 are supposed to be ordered
1310  * return value is the index of the last mapping for which end>cluster_num
1311  */
1312 static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
1313 {
1314     while(1) {
1315         int index3;
1316         mapping_t* mapping;
1317         index3=(index1+index2)/2;
1318         mapping=array_get(&(s->mapping),index3);
1319         assert(mapping->begin < mapping->end);
1320         if(mapping->begin>=cluster_num) {
1321             assert(index2!=index3 || index2==0);
1322             if(index2==index3)
1323                 return index1;
1324             index2=index3;
1325         } else {
1326             if(index1==index3)
1327                 return mapping->end<=cluster_num ? index2 : index1;
1328             index1=index3;
1329         }
1330         assert(index1<=index2);
1331         DLOG(mapping=array_get(&(s->mapping),index1);
1332         assert(mapping->begin<=cluster_num);
1333         assert(index2 >= s->mapping.next ||
1334                 ((mapping = array_get(&(s->mapping),index2)) &&
1335                 mapping->end>cluster_num)));
1336     }
1337 }
1338 
1339 static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
1340 {
1341     int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
1342     mapping_t* mapping;
1343     if(index>=s->mapping.next)
1344         return NULL;
1345     mapping=array_get(&(s->mapping),index);
1346     if(mapping->begin>cluster_num)
1347         return NULL;
1348     assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
1349     return mapping;
1350 }
1351 
1352 static int open_file(BDRVVVFATState* s,mapping_t* mapping)
1353 {
1354     if(!mapping)
1355         return -1;
1356     if(!s->current_mapping ||
1357             strcmp(s->current_mapping->path,mapping->path)) {
1358         /* open file */
1359         int fd = qemu_open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
1360         if(fd<0)
1361             return -1;
1362         vvfat_close_current_file(s);
1363         s->current_fd = fd;
1364         s->current_mapping = mapping;
1365     }
1366     return 0;
1367 }
1368 
1369 static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
1370 {
1371     if(s->current_cluster != cluster_num) {
1372         int result=0;
1373         off_t offset;
1374         assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
1375         if(!s->current_mapping
1376                 || s->current_mapping->begin>cluster_num
1377                 || s->current_mapping->end<=cluster_num) {
1378             /* binary search of mappings for file */
1379             mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
1380 
1381             assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
1382 
1383             if (mapping && mapping->mode & MODE_DIRECTORY) {
1384                 vvfat_close_current_file(s);
1385                 s->current_mapping = mapping;
1386 read_cluster_directory:
1387                 offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
1388                 s->cluster = (unsigned char*)s->directory.pointer+offset
1389                         + 0x20*s->current_mapping->info.dir.first_dir_index;
1390                 assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
1391                 assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
1392                 s->current_cluster = cluster_num;
1393                 return 0;
1394             }
1395 
1396             if(open_file(s,mapping))
1397                 return -2;
1398         } else if (s->current_mapping->mode & MODE_DIRECTORY)
1399             goto read_cluster_directory;
1400 
1401         assert(s->current_fd);
1402 
1403         offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
1404         if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
1405             return -3;
1406         s->cluster=s->cluster_buffer;
1407         result=read(s->current_fd,s->cluster,s->cluster_size);
1408         if(result<0) {
1409             s->current_cluster = -1;
1410             return -1;
1411         }
1412         s->current_cluster = cluster_num;
1413     }
1414     return 0;
1415 }
1416 
1417 #ifdef DEBUG
1418 static void print_direntry(const direntry_t* direntry)
1419 {
1420     int j = 0;
1421     char buffer[1024];
1422 
1423     fprintf(stderr, "direntry %p: ", direntry);
1424     if(!direntry)
1425         return;
1426     if(is_long_name(direntry)) {
1427         unsigned char* c=(unsigned char*)direntry;
1428         int i;
1429         for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
1430 #define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
1431             ADD_CHAR(c[i]);
1432         for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
1433             ADD_CHAR(c[i]);
1434         for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
1435             ADD_CHAR(c[i]);
1436         buffer[j] = 0;
1437         fprintf(stderr, "%s\n", buffer);
1438     } else {
1439         int i;
1440         for(i=0;i<11;i++)
1441             ADD_CHAR(direntry->name[i]);
1442         buffer[j] = 0;
1443         fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
1444                 buffer,
1445                 direntry->attributes,
1446                 begin_of_direntry(direntry),le32_to_cpu(direntry->size));
1447     }
1448 }
1449 
1450 static void print_mapping(const mapping_t* mapping)
1451 {
1452     fprintf(stderr, "mapping (%p): begin, end = %d, %d, dir_index = %d, "
1453         "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
1454         mapping, mapping->begin, mapping->end, mapping->dir_index,
1455         mapping->first_mapping_index, mapping->path, mapping->mode);
1456 
1457     if (mapping->mode & MODE_DIRECTORY)
1458         fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
1459     else
1460         fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
1461 }
1462 #endif
1463 
1464 static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
1465                     uint8_t *buf, int nb_sectors)
1466 {
1467     BDRVVVFATState *s = bs->opaque;
1468     int i;
1469 
1470     for(i=0;i<nb_sectors;i++,sector_num++) {
1471         if (sector_num >= bs->total_sectors)
1472            return -1;
1473         if (s->qcow) {
1474             int64_t n;
1475             int ret;
1476             ret = bdrv_is_allocated(s->qcow->bs, sector_num * BDRV_SECTOR_SIZE,
1477                                     (nb_sectors - i) * BDRV_SECTOR_SIZE, &n);
1478             if (ret < 0) {
1479                 return ret;
1480             }
1481             if (ret) {
1482                 DLOG(fprintf(stderr, "sectors %" PRId64 "+%" PRId64
1483                              " allocated\n", sector_num,
1484                              n >> BDRV_SECTOR_BITS));
1485                 if (bdrv_pread(s->qcow, sector_num * BDRV_SECTOR_SIZE,
1486                                buf + i * 0x200, n) < 0) {
1487                     return -1;
1488                 }
1489                 i += (n >> BDRV_SECTOR_BITS) - 1;
1490                 sector_num += (n >> BDRV_SECTOR_BITS) - 1;
1491                 continue;
1492             }
1493             DLOG(fprintf(stderr, "sector %" PRId64 " not allocated\n",
1494                          sector_num));
1495         }
1496         if (sector_num < s->offset_to_root_dir) {
1497             if (sector_num < s->offset_to_fat) {
1498                 memcpy(buf + i * 0x200,
1499                        &(s->first_sectors[sector_num * 0x200]),
1500                        0x200);
1501             } else if (sector_num < s->offset_to_fat + s->sectors_per_fat) {
1502                 memcpy(buf + i * 0x200,
1503                        &(s->fat.pointer[(sector_num
1504                                        - s->offset_to_fat) * 0x200]),
1505                        0x200);
1506             } else if (sector_num < s->offset_to_root_dir) {
1507                 memcpy(buf + i * 0x200,
1508                        &(s->fat.pointer[(sector_num - s->offset_to_fat
1509                                        - s->sectors_per_fat) * 0x200]),
1510                        0x200);
1511             }
1512         } else {
1513             uint32_t sector = sector_num - s->offset_to_root_dir,
1514             sector_offset_in_cluster=(sector%s->sectors_per_cluster),
1515             cluster_num=sector/s->sectors_per_cluster;
1516             if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
1517                 /* LATER TODO: strict: return -1; */
1518                 memset(buf+i*0x200,0,0x200);
1519                 continue;
1520             }
1521             memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
1522         }
1523     }
1524     return 0;
1525 }
1526 
1527 static int coroutine_fn
1528 vvfat_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
1529                 QEMUIOVector *qiov, int flags)
1530 {
1531     int ret;
1532     BDRVVVFATState *s = bs->opaque;
1533     uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
1534     int nb_sectors = bytes >> BDRV_SECTOR_BITS;
1535     void *buf;
1536 
1537     assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
1538     assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
1539 
1540     buf = g_try_malloc(bytes);
1541     if (bytes && buf == NULL) {
1542         return -ENOMEM;
1543     }
1544 
1545     qemu_co_mutex_lock(&s->lock);
1546     ret = vvfat_read(bs, sector_num, buf, nb_sectors);
1547     qemu_co_mutex_unlock(&s->lock);
1548 
1549     qemu_iovec_from_buf(qiov, 0, buf, bytes);
1550     g_free(buf);
1551 
1552     return ret;
1553 }
1554 
1555 /* LATER TODO: statify all functions */
1556 
1557 /*
1558  * Idea of the write support (use snapshot):
1559  *
1560  * 1. check if all data is consistent, recording renames, modifications,
1561  *    new files and directories (in s->commits).
1562  *
1563  * 2. if the data is not consistent, stop committing
1564  *
1565  * 3. handle renames, and create new files and directories (do not yet
1566  *    write their contents)
1567  *
1568  * 4. walk the directories, fixing the mapping and direntries, and marking
1569  *    the handled mappings as not deleted
1570  *
1571  * 5. commit the contents of the files
1572  *
1573  * 6. handle deleted files and directories
1574  *
1575  */
1576 
1577 typedef struct commit_t {
1578     char* path;
1579     union {
1580         struct { uint32_t cluster; } rename;
1581         struct { int dir_index; uint32_t modified_offset; } writeout;
1582         struct { uint32_t first_cluster; } new_file;
1583         struct { uint32_t cluster; } mkdir;
1584     } param;
1585     /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
1586     enum {
1587         ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
1588     } action;
1589 } commit_t;
1590 
1591 static void clear_commits(BDRVVVFATState* s)
1592 {
1593     int i;
1594 DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
1595     for (i = 0; i < s->commits.next; i++) {
1596         commit_t* commit = array_get(&(s->commits), i);
1597         assert(commit->path || commit->action == ACTION_WRITEOUT);
1598         if (commit->action != ACTION_WRITEOUT) {
1599             assert(commit->path);
1600             g_free(commit->path);
1601         } else
1602             assert(commit->path == NULL);
1603     }
1604     s->commits.next = 0;
1605 }
1606 
1607 static void schedule_rename(BDRVVVFATState* s,
1608         uint32_t cluster, char* new_path)
1609 {
1610     commit_t* commit = array_get_next(&(s->commits));
1611     commit->path = new_path;
1612     commit->param.rename.cluster = cluster;
1613     commit->action = ACTION_RENAME;
1614 }
1615 
1616 static void schedule_writeout(BDRVVVFATState* s,
1617         int dir_index, uint32_t modified_offset)
1618 {
1619     commit_t* commit = array_get_next(&(s->commits));
1620     commit->path = NULL;
1621     commit->param.writeout.dir_index = dir_index;
1622     commit->param.writeout.modified_offset = modified_offset;
1623     commit->action = ACTION_WRITEOUT;
1624 }
1625 
1626 static void schedule_new_file(BDRVVVFATState* s,
1627         char* path, uint32_t first_cluster)
1628 {
1629     commit_t* commit = array_get_next(&(s->commits));
1630     commit->path = path;
1631     commit->param.new_file.first_cluster = first_cluster;
1632     commit->action = ACTION_NEW_FILE;
1633 }
1634 
1635 static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
1636 {
1637     commit_t* commit = array_get_next(&(s->commits));
1638     commit->path = path;
1639     commit->param.mkdir.cluster = cluster;
1640     commit->action = ACTION_MKDIR;
1641 }
1642 
1643 typedef struct {
1644     /*
1645      * Since the sequence number is at most 0x3f, and the filename
1646      * length is at most 13 times the sequence number, the maximal
1647      * filename length is 0x3f * 13 bytes.
1648      */
1649     unsigned char name[0x3f * 13 + 1];
1650     gunichar2 name2[0x3f * 13 + 1];
1651     int checksum, len;
1652     int sequence_number;
1653 } long_file_name;
1654 
1655 static void lfn_init(long_file_name* lfn)
1656 {
1657    lfn->sequence_number = lfn->len = 0;
1658    lfn->checksum = 0x100;
1659 }
1660 
1661 /* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
1662 static int parse_long_name(long_file_name* lfn,
1663         const direntry_t* direntry)
1664 {
1665     int i, j, offset;
1666     const unsigned char* pointer = (const unsigned char*)direntry;
1667 
1668     if (!is_long_name(direntry))
1669         return 1;
1670 
1671     if (pointer[0] & 0x40) {
1672         /* first entry; do some initialization */
1673         lfn->sequence_number = pointer[0] & 0x3f;
1674         lfn->checksum = pointer[13];
1675         lfn->name[0] = 0;
1676         lfn->name[lfn->sequence_number * 13] = 0;
1677     } else if ((pointer[0] & 0x3f) != --lfn->sequence_number) {
1678         /* not the expected sequence number */
1679         return -1;
1680     } else if (pointer[13] != lfn->checksum) {
1681         /* not the expected checksum */
1682         return -2;
1683     } else if (pointer[12] || pointer[26] || pointer[27]) {
1684         /* invalid zero fields */
1685         return -3;
1686     }
1687 
1688     offset = 13 * (lfn->sequence_number - 1);
1689     for (i = 0, j = 1; i < 13; i++, j+=2) {
1690         if (j == 11)
1691             j = 14;
1692         else if (j == 26)
1693             j = 28;
1694 
1695         if (pointer[j] == 0 && pointer[j + 1] == 0) {
1696             /* end of long file name */
1697             break;
1698         }
1699         gunichar2 c = (pointer[j + 1] << 8) + pointer[j];
1700         lfn->name2[offset + i] = c;
1701     }
1702 
1703     if (pointer[0] & 0x40) {
1704         /* first entry; set len */
1705         lfn->len = offset + i;
1706     }
1707     if ((pointer[0] & 0x3f) == 0x01) {
1708         /* last entry; finalize entry */
1709         glong olen;
1710         gchar *utf8 = g_utf16_to_utf8(lfn->name2, lfn->len, NULL, &olen, NULL);
1711         if (!utf8) {
1712             return -4;
1713         }
1714         lfn->len = olen;
1715         memcpy(lfn->name, utf8, olen + 1);
1716         g_free(utf8);
1717     }
1718 
1719     return 0;
1720 }
1721 
1722 /* returns 0 if successful, >0 if no short_name, and <0 on error */
1723 static int parse_short_name(BDRVVVFATState* s,
1724         long_file_name* lfn, direntry_t* direntry)
1725 {
1726     int i, j;
1727 
1728     if (!is_short_name(direntry))
1729         return 1;
1730 
1731     for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
1732     for (i = 0; i <= j; i++) {
1733         uint8_t c = direntry->name[i];
1734         if (c != to_valid_short_char(c)) {
1735             return -1;
1736         } else if (s->downcase_short_names) {
1737             lfn->name[i] = qemu_tolower(direntry->name[i]);
1738         } else {
1739             lfn->name[i] = direntry->name[i];
1740         }
1741     }
1742 
1743     for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) {
1744     }
1745     if (j >= 0) {
1746         lfn->name[i++] = '.';
1747         lfn->name[i + j + 1] = '\0';
1748         for (;j >= 0; j--) {
1749             uint8_t c = direntry->name[8 + j];
1750             if (c != to_valid_short_char(c)) {
1751                 return -2;
1752             } else if (s->downcase_short_names) {
1753                 lfn->name[i + j] = qemu_tolower(c);
1754             } else {
1755                 lfn->name[i + j] = c;
1756             }
1757         }
1758     } else
1759         lfn->name[i + j + 1] = '\0';
1760 
1761     if (lfn->name[0] == DIR_KANJI_FAKE) {
1762         lfn->name[0] = DIR_KANJI;
1763     }
1764     lfn->len = strlen((char*)lfn->name);
1765 
1766     return 0;
1767 }
1768 
1769 static inline uint32_t modified_fat_get(BDRVVVFATState* s,
1770         unsigned int cluster)
1771 {
1772     if (cluster < s->last_cluster_of_root_directory) {
1773         if (cluster + 1 == s->last_cluster_of_root_directory)
1774             return s->max_fat_value;
1775         else
1776             return cluster + 1;
1777     }
1778 
1779     if (s->fat_type==32) {
1780         uint32_t* entry=((uint32_t*)s->fat2)+cluster;
1781         return le32_to_cpu(*entry);
1782     } else if (s->fat_type==16) {
1783         uint16_t* entry=((uint16_t*)s->fat2)+cluster;
1784         return le16_to_cpu(*entry);
1785     } else {
1786         const uint8_t* x=s->fat2+cluster*3/2;
1787         return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
1788     }
1789 }
1790 
1791 static inline bool cluster_was_modified(BDRVVVFATState *s,
1792                                         uint32_t cluster_num)
1793 {
1794     int was_modified = 0;
1795     int i;
1796 
1797     if (s->qcow == NULL) {
1798         return 0;
1799     }
1800 
1801     for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) {
1802         was_modified = bdrv_is_allocated(s->qcow->bs,
1803                                          (cluster2sector(s, cluster_num) +
1804                                           i) * BDRV_SECTOR_SIZE,
1805                                          BDRV_SECTOR_SIZE, NULL);
1806     }
1807 
1808     /*
1809      * Note that this treats failures to learn allocation status the
1810      * same as if an allocation has occurred.  It's as safe as
1811      * anything else, given that a failure to learn allocation status
1812      * will probably result in more failures.
1813      */
1814     return !!was_modified;
1815 }
1816 
1817 static const char* get_basename(const char* path)
1818 {
1819     char* basename = strrchr(path, '/');
1820     if (basename == NULL)
1821         return path;
1822     else
1823         return basename + 1; /* strip '/' */
1824 }
1825 
1826 /*
1827  * The array s->used_clusters holds the states of the clusters. If it is
1828  * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
1829  * was modified, bit 3 is set.
1830  * If any cluster is allocated, but not part of a file or directory, this
1831  * driver refuses to commit.
1832  */
1833 typedef enum {
1834      USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
1835 } used_t;
1836 
1837 /*
1838  * get_cluster_count_for_direntry() not only determines how many clusters
1839  * are occupied by direntry, but also if it was renamed or modified.
1840  *
1841  * A file is thought to be renamed *only* if there already was a file with
1842  * exactly the same first cluster, but a different name.
1843  *
1844  * Further, the files/directories handled by this function are
1845  * assumed to be *not* deleted (and *only* those).
1846  */
1847 static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
1848         direntry_t* direntry, const char* path)
1849 {
1850     /*
1851      * This is a little bit tricky:
1852      * IF the guest OS just inserts a cluster into the file chain,
1853      * and leaves the rest alone, (i.e. the original file had clusters
1854      * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
1855      *
1856      * - do_commit will write the cluster into the file at the given
1857      *   offset, but
1858      *
1859      * - the cluster which is overwritten should be moved to a later
1860      *   position in the file.
1861      *
1862      * I am not aware that any OS does something as braindead, but this
1863      * situation could happen anyway when not committing for a long time.
1864      * Just to be sure that this does not bite us, detect it, and copy the
1865      * contents of the clusters to-be-overwritten into the qcow.
1866      */
1867     int copy_it = 0;
1868     int was_modified = 0;
1869     int32_t ret = 0;
1870 
1871     uint32_t cluster_num = begin_of_direntry(direntry);
1872     uint32_t offset = 0;
1873     int first_mapping_index = -1;
1874     mapping_t* mapping = NULL;
1875     const char* basename2 = NULL;
1876 
1877     vvfat_close_current_file(s);
1878 
1879     /* the root directory */
1880     if (cluster_num == 0)
1881         return 0;
1882 
1883     /* write support */
1884     if (s->qcow) {
1885         basename2 = get_basename(path);
1886 
1887         mapping = find_mapping_for_cluster(s, cluster_num);
1888 
1889         if (mapping) {
1890             const char* basename;
1891 
1892             assert(mapping->mode & MODE_DELETED);
1893             mapping->mode &= ~MODE_DELETED;
1894 
1895             basename = get_basename(mapping->path);
1896 
1897             assert(mapping->mode & MODE_NORMAL);
1898 
1899             /* rename */
1900             if (strcmp(basename, basename2))
1901                 schedule_rename(s, cluster_num, g_strdup(path));
1902         } else if (is_file(direntry))
1903             /* new file */
1904             schedule_new_file(s, g_strdup(path), cluster_num);
1905         else {
1906             abort();
1907             return 0;
1908         }
1909     }
1910 
1911     while(1) {
1912         if (s->qcow) {
1913             if (!copy_it && cluster_was_modified(s, cluster_num)) {
1914                 if (mapping == NULL ||
1915                         mapping->begin > cluster_num ||
1916                         mapping->end <= cluster_num)
1917                 mapping = find_mapping_for_cluster(s, cluster_num);
1918 
1919 
1920                 if (mapping &&
1921                         (mapping->mode & MODE_DIRECTORY) == 0) {
1922 
1923                     /* was modified in qcow */
1924                     if (offset != mapping->info.file.offset + s->cluster_size
1925                             * (cluster_num - mapping->begin)) {
1926                         /* offset of this cluster in file chain has changed */
1927                         abort();
1928                         copy_it = 1;
1929                     } else if (offset == 0) {
1930                         const char* basename = get_basename(mapping->path);
1931 
1932                         if (strcmp(basename, basename2))
1933                             copy_it = 1;
1934                         first_mapping_index = array_index(&(s->mapping), mapping);
1935                     }
1936 
1937                     if (mapping->first_mapping_index != first_mapping_index
1938                             && mapping->info.file.offset > 0) {
1939                         abort();
1940                         copy_it = 1;
1941                     }
1942 
1943                     /* need to write out? */
1944                     if (!was_modified && is_file(direntry)) {
1945                         was_modified = 1;
1946                         schedule_writeout(s, mapping->dir_index, offset);
1947                     }
1948                 }
1949             }
1950 
1951             if (copy_it) {
1952                 int i;
1953                 /*
1954                  * This is horribly inefficient, but that is okay, since
1955                  * it is rarely executed, if at all.
1956                  */
1957                 int64_t offset = cluster2sector(s, cluster_num);
1958 
1959                 vvfat_close_current_file(s);
1960                 for (i = 0; i < s->sectors_per_cluster; i++) {
1961                     int res;
1962 
1963                     res = bdrv_is_allocated(s->qcow->bs,
1964                                             (offset + i) * BDRV_SECTOR_SIZE,
1965                                             BDRV_SECTOR_SIZE, NULL);
1966                     if (res < 0) {
1967                         return -1;
1968                     }
1969                     if (!res) {
1970                         res = vvfat_read(s->bs, offset, s->cluster_buffer, 1);
1971                         if (res) {
1972                             return -1;
1973                         }
1974                         res = bdrv_pwrite(s->qcow, offset * BDRV_SECTOR_SIZE,
1975                                           s->cluster_buffer, BDRV_SECTOR_SIZE);
1976                         if (res < 0) {
1977                             return -2;
1978                         }
1979                     }
1980                 }
1981             }
1982         }
1983 
1984         ret++;
1985         if (s->used_clusters[cluster_num] & USED_ANY)
1986             return 0;
1987         s->used_clusters[cluster_num] = USED_FILE;
1988 
1989         cluster_num = modified_fat_get(s, cluster_num);
1990 
1991         if (fat_eof(s, cluster_num))
1992             return ret;
1993         else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
1994             return -1;
1995 
1996         offset += s->cluster_size;
1997     }
1998 }
1999 
2000 /*
2001  * This function looks at the modified data (qcow).
2002  * It returns 0 upon inconsistency or error, and the number of clusters
2003  * used by the directory, its subdirectories and their files.
2004  */
2005 static int check_directory_consistency(BDRVVVFATState *s,
2006         int cluster_num, const char* path)
2007 {
2008     int ret = 0;
2009     unsigned char* cluster = g_malloc(s->cluster_size);
2010     direntry_t* direntries = (direntry_t*)cluster;
2011     mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
2012 
2013     long_file_name lfn;
2014     int path_len = strlen(path);
2015     char path2[PATH_MAX + 1];
2016 
2017     assert(path_len < PATH_MAX); /* len was tested before! */
2018     pstrcpy(path2, sizeof(path2), path);
2019     path2[path_len] = '/';
2020     path2[path_len + 1] = '\0';
2021 
2022     if (mapping) {
2023         const char* basename = get_basename(mapping->path);
2024         const char* basename2 = get_basename(path);
2025 
2026         assert(mapping->mode & MODE_DIRECTORY);
2027 
2028         assert(mapping->mode & MODE_DELETED);
2029         mapping->mode &= ~MODE_DELETED;
2030 
2031         if (strcmp(basename, basename2))
2032             schedule_rename(s, cluster_num, g_strdup(path));
2033     } else
2034         /* new directory */
2035         schedule_mkdir(s, cluster_num, g_strdup(path));
2036 
2037     lfn_init(&lfn);
2038     do {
2039         int i;
2040         int subret = 0;
2041 
2042         ret++;
2043 
2044         if (s->used_clusters[cluster_num] & USED_ANY) {
2045             fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
2046             goto fail;
2047         }
2048         s->used_clusters[cluster_num] = USED_DIRECTORY;
2049 
2050 DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
2051         subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
2052                 s->sectors_per_cluster);
2053         if (subret) {
2054             fprintf(stderr, "Error fetching direntries\n");
2055         fail:
2056             g_free(cluster);
2057             return 0;
2058         }
2059 
2060         for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
2061             int cluster_count = 0;
2062 
2063 DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i));
2064             if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
2065                     is_free(direntries + i))
2066                 continue;
2067 
2068             subret = parse_long_name(&lfn, direntries + i);
2069             if (subret < 0) {
2070                 fprintf(stderr, "Error in long name\n");
2071                 goto fail;
2072             }
2073             if (subret == 0 || is_free(direntries + i))
2074                 continue;
2075 
2076             if (fat_chksum(direntries+i) != lfn.checksum) {
2077                 subret = parse_short_name(s, &lfn, direntries + i);
2078                 if (subret < 0) {
2079                     fprintf(stderr, "Error in short name (%d)\n", subret);
2080                     goto fail;
2081                 }
2082                 if (subret > 0 || !strcmp((char*)lfn.name, ".")
2083                         || !strcmp((char*)lfn.name, ".."))
2084                     continue;
2085             }
2086             lfn.checksum = 0x100; /* cannot use long name twice */
2087 
2088             if (!valid_filename(lfn.name)) {
2089                 fprintf(stderr, "Invalid file name\n");
2090                 goto fail;
2091             }
2092             if (path_len + 1 + lfn.len >= PATH_MAX) {
2093                 fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
2094                 goto fail;
2095             }
2096             pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
2097                     (char*)lfn.name);
2098 
2099             if (is_directory(direntries + i)) {
2100                 if (begin_of_direntry(direntries + i) == 0) {
2101                     DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
2102                     goto fail;
2103                 }
2104                 cluster_count = check_directory_consistency(s,
2105                         begin_of_direntry(direntries + i), path2);
2106                 if (cluster_count == 0) {
2107                     DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
2108                     goto fail;
2109                 }
2110             } else if (is_file(direntries + i)) {
2111                 /* check file size with FAT */
2112                 cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
2113                 if (cluster_count !=
2114             DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) {
2115                     DLOG(fprintf(stderr, "Cluster count mismatch\n"));
2116                     goto fail;
2117                 }
2118             } else
2119                 abort(); /* cluster_count = 0; */
2120 
2121             ret += cluster_count;
2122         }
2123 
2124         cluster_num = modified_fat_get(s, cluster_num);
2125     } while(!fat_eof(s, cluster_num));
2126 
2127     g_free(cluster);
2128     return ret;
2129 }
2130 
2131 /* returns 1 on success */
2132 static int is_consistent(BDRVVVFATState* s)
2133 {
2134     int i, check;
2135     int used_clusters_count = 0;
2136 
2137 DLOG(checkpoint());
2138     /*
2139      * - get modified FAT
2140      * - compare the two FATs (TODO)
2141      * - get buffer for marking used clusters
2142      * - recurse direntries from root (using bs->bdrv_pread to make
2143      *    sure to get the new data)
2144      *   - check that the FAT agrees with the size
2145      *   - count the number of clusters occupied by this directory and
2146      *     its files
2147      * - check that the cumulative used cluster count agrees with the
2148      *   FAT
2149      * - if all is fine, return number of used clusters
2150      */
2151     if (s->fat2 == NULL) {
2152         int size = 0x200 * s->sectors_per_fat;
2153         s->fat2 = g_malloc(size);
2154         memcpy(s->fat2, s->fat.pointer, size);
2155     }
2156     check = vvfat_read(s->bs,
2157             s->offset_to_fat, s->fat2, s->sectors_per_fat);
2158     if (check) {
2159         fprintf(stderr, "Could not copy fat\n");
2160         return 0;
2161     }
2162     assert (s->used_clusters);
2163     for (i = 0; i < sector2cluster(s, s->sector_count); i++)
2164         s->used_clusters[i] &= ~USED_ANY;
2165 
2166     clear_commits(s);
2167 
2168     /* mark every mapped file/directory as deleted.
2169      * (check_directory_consistency() will unmark those still present). */
2170     if (s->qcow)
2171         for (i = 0; i < s->mapping.next; i++) {
2172             mapping_t* mapping = array_get(&(s->mapping), i);
2173             if (mapping->first_mapping_index < 0)
2174                 mapping->mode |= MODE_DELETED;
2175         }
2176 
2177     used_clusters_count = check_directory_consistency(s, 0, s->path);
2178     if (used_clusters_count <= 0) {
2179         DLOG(fprintf(stderr, "problem in directory\n"));
2180         return 0;
2181     }
2182 
2183     check = s->last_cluster_of_root_directory;
2184     for (i = check; i < sector2cluster(s, s->sector_count); i++) {
2185         if (modified_fat_get(s, i)) {
2186             if(!s->used_clusters[i]) {
2187                 DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
2188                 return 0;
2189             }
2190             check++;
2191         }
2192 
2193         if (s->used_clusters[i] == USED_ALLOCATED) {
2194             /* allocated, but not used... */
2195             DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
2196             return 0;
2197         }
2198     }
2199 
2200     if (check != used_clusters_count)
2201         return 0;
2202 
2203     return used_clusters_count;
2204 }
2205 
2206 static inline void adjust_mapping_indices(BDRVVVFATState* s,
2207         int offset, int adjust)
2208 {
2209     int i;
2210 
2211     for (i = 0; i < s->mapping.next; i++) {
2212         mapping_t* mapping = array_get(&(s->mapping), i);
2213 
2214 #define ADJUST_MAPPING_INDEX(name) \
2215         if (mapping->name >= offset) \
2216             mapping->name += adjust
2217 
2218         ADJUST_MAPPING_INDEX(first_mapping_index);
2219         if (mapping->mode & MODE_DIRECTORY)
2220             ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
2221     }
2222 }
2223 
2224 /* insert or update mapping */
2225 static mapping_t* insert_mapping(BDRVVVFATState* s,
2226         uint32_t begin, uint32_t end)
2227 {
2228     /*
2229      * - find mapping where mapping->begin >= begin,
2230      * - if mapping->begin > begin: insert
2231      *   - adjust all references to mappings!
2232      * - else: adjust
2233      * - replace name
2234      */
2235     int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
2236     mapping_t* mapping = NULL;
2237     mapping_t* first_mapping = array_get(&(s->mapping), 0);
2238 
2239     if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
2240             && mapping->begin < begin) {
2241         mapping->end = begin;
2242         index++;
2243         mapping = array_get(&(s->mapping), index);
2244     }
2245     if (index >= s->mapping.next || mapping->begin > begin) {
2246         mapping = array_insert(&(s->mapping), index, 1);
2247         mapping->path = NULL;
2248         adjust_mapping_indices(s, index, +1);
2249     }
2250 
2251     mapping->begin = begin;
2252     mapping->end = end;
2253 
2254 DLOG(mapping_t* next_mapping;
2255 assert(index + 1 >= s->mapping.next ||
2256 ((next_mapping = array_get(&(s->mapping), index + 1)) &&
2257  next_mapping->begin >= end)));
2258 
2259     if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
2260         s->current_mapping = array_get(&(s->mapping),
2261                 s->current_mapping - first_mapping);
2262 
2263     return mapping;
2264 }
2265 
2266 static int remove_mapping(BDRVVVFATState* s, int mapping_index)
2267 {
2268     mapping_t* mapping = array_get(&(s->mapping), mapping_index);
2269     mapping_t* first_mapping = array_get(&(s->mapping), 0);
2270 
2271     /* free mapping */
2272     if (mapping->first_mapping_index < 0) {
2273         g_free(mapping->path);
2274     }
2275 
2276     /* remove from s->mapping */
2277     array_remove(&(s->mapping), mapping_index);
2278 
2279     /* adjust all references to mappings */
2280     adjust_mapping_indices(s, mapping_index, -1);
2281 
2282     if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
2283         s->current_mapping = array_get(&(s->mapping),
2284                 s->current_mapping - first_mapping);
2285 
2286     return 0;
2287 }
2288 
2289 static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
2290 {
2291     int i;
2292     for (i = 0; i < s->mapping.next; i++) {
2293         mapping_t* mapping = array_get(&(s->mapping), i);
2294         if (mapping->dir_index >= offset)
2295             mapping->dir_index += adjust;
2296         if ((mapping->mode & MODE_DIRECTORY) &&
2297                 mapping->info.dir.first_dir_index >= offset)
2298             mapping->info.dir.first_dir_index += adjust;
2299     }
2300 }
2301 
2302 static direntry_t* insert_direntries(BDRVVVFATState* s,
2303         int dir_index, int count)
2304 {
2305     /*
2306      * make room in s->directory,
2307      * adjust_dirindices
2308      */
2309     direntry_t* result = array_insert(&(s->directory), dir_index, count);
2310     if (result == NULL)
2311         return NULL;
2312     adjust_dirindices(s, dir_index, count);
2313     return result;
2314 }
2315 
2316 static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
2317 {
2318     int ret = array_remove_slice(&(s->directory), dir_index, count);
2319     if (ret)
2320         return ret;
2321     adjust_dirindices(s, dir_index, -count);
2322     return 0;
2323 }
2324 
2325 /*
2326  * Adapt the mappings of the cluster chain starting at first cluster
2327  * (i.e. if a file starts at first_cluster, the chain is followed according
2328  * to the modified fat, and the corresponding entries in s->mapping are
2329  * adjusted)
2330  */
2331 static int commit_mappings(BDRVVVFATState* s,
2332         uint32_t first_cluster, int dir_index)
2333 {
2334     mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
2335     direntry_t* direntry = array_get(&(s->directory), dir_index);
2336     uint32_t cluster = first_cluster;
2337 
2338     vvfat_close_current_file(s);
2339 
2340     assert(mapping);
2341     assert(mapping->begin == first_cluster);
2342     mapping->first_mapping_index = -1;
2343     mapping->dir_index = dir_index;
2344     mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
2345         MODE_DIRECTORY : MODE_NORMAL;
2346 
2347     while (!fat_eof(s, cluster)) {
2348         uint32_t c, c1;
2349 
2350         for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
2351                 c = c1, c1 = modified_fat_get(s, c1));
2352 
2353         c++;
2354         if (c > mapping->end) {
2355             int index = array_index(&(s->mapping), mapping);
2356             int i, max_i = s->mapping.next - index;
2357             for (i = 1; i < max_i && mapping[i].begin < c; i++);
2358             while (--i > 0)
2359                 remove_mapping(s, index + 1);
2360         }
2361         assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
2362                 || mapping[1].begin >= c);
2363         mapping->end = c;
2364 
2365         if (!fat_eof(s, c1)) {
2366             int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
2367             mapping_t* next_mapping = i >= s->mapping.next ? NULL :
2368                 array_get(&(s->mapping), i);
2369 
2370             if (next_mapping == NULL || next_mapping->begin > c1) {
2371                 int i1 = array_index(&(s->mapping), mapping);
2372 
2373                 next_mapping = insert_mapping(s, c1, c1+1);
2374 
2375                 if (c1 < c)
2376                     i1++;
2377                 mapping = array_get(&(s->mapping), i1);
2378             }
2379 
2380             next_mapping->dir_index = mapping->dir_index;
2381             next_mapping->first_mapping_index =
2382                 mapping->first_mapping_index < 0 ?
2383                 array_index(&(s->mapping), mapping) :
2384                 mapping->first_mapping_index;
2385             next_mapping->path = mapping->path;
2386             next_mapping->mode = mapping->mode;
2387             next_mapping->read_only = mapping->read_only;
2388             if (mapping->mode & MODE_DIRECTORY) {
2389                 next_mapping->info.dir.parent_mapping_index =
2390                         mapping->info.dir.parent_mapping_index;
2391                 next_mapping->info.dir.first_dir_index =
2392                         mapping->info.dir.first_dir_index +
2393                         0x10 * s->sectors_per_cluster *
2394                         (mapping->end - mapping->begin);
2395             } else
2396                 next_mapping->info.file.offset = mapping->info.file.offset +
2397                         mapping->end - mapping->begin;
2398 
2399             mapping = next_mapping;
2400         }
2401 
2402         cluster = c1;
2403     }
2404 
2405     return 0;
2406 }
2407 
2408 static int commit_direntries(BDRVVVFATState* s,
2409         int dir_index, int parent_mapping_index)
2410 {
2411     direntry_t* direntry = array_get(&(s->directory), dir_index);
2412     uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
2413     mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
2414     int factor = 0x10 * s->sectors_per_cluster;
2415     int old_cluster_count, new_cluster_count;
2416     int current_dir_index;
2417     int first_dir_index;
2418     int ret, i;
2419     uint32_t c;
2420 
2421     assert(direntry);
2422     assert(mapping);
2423     assert(mapping->begin == first_cluster);
2424     assert(mapping->info.dir.first_dir_index < s->directory.next);
2425     assert(mapping->mode & MODE_DIRECTORY);
2426     assert(dir_index == 0 || is_directory(direntry));
2427 
2428     DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n",
2429                  mapping->path, parent_mapping_index));
2430 
2431     current_dir_index = mapping->info.dir.first_dir_index;
2432     first_dir_index = current_dir_index;
2433     mapping->info.dir.parent_mapping_index = parent_mapping_index;
2434 
2435     if (first_cluster == 0) {
2436         old_cluster_count = new_cluster_count =
2437             s->last_cluster_of_root_directory;
2438     } else {
2439         for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2440                 c = fat_get(s, c))
2441             old_cluster_count++;
2442 
2443         for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2444                 c = modified_fat_get(s, c))
2445             new_cluster_count++;
2446     }
2447 
2448     if (new_cluster_count > old_cluster_count) {
2449         if (insert_direntries(s,
2450                 current_dir_index + factor * old_cluster_count,
2451                 factor * (new_cluster_count - old_cluster_count)) == NULL)
2452             return -1;
2453     } else if (new_cluster_count < old_cluster_count)
2454         remove_direntries(s,
2455                 current_dir_index + factor * new_cluster_count,
2456                 factor * (old_cluster_count - new_cluster_count));
2457 
2458     for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
2459         direntry_t *first_direntry;
2460         void* direntry = array_get(&(s->directory), current_dir_index);
2461         int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
2462                 s->sectors_per_cluster);
2463         if (ret)
2464             return ret;
2465 
2466         /* The first directory entry on the filesystem is the volume name */
2467         first_direntry = (direntry_t*) s->directory.pointer;
2468         assert(!memcmp(first_direntry->name, s->volume_label, 11));
2469 
2470         current_dir_index += factor;
2471     }
2472 
2473     ret = commit_mappings(s, first_cluster, dir_index);
2474     if (ret)
2475         return ret;
2476 
2477     /* recurse */
2478     for (i = 0; i < factor * new_cluster_count; i++) {
2479         direntry = array_get(&(s->directory), first_dir_index + i);
2480         if (is_directory(direntry) && !is_dot(direntry)) {
2481             mapping = find_mapping_for_cluster(s, first_cluster);
2482             if (mapping == NULL) {
2483                 return -1;
2484             }
2485             assert(mapping->mode & MODE_DIRECTORY);
2486             ret = commit_direntries(s, first_dir_index + i,
2487                 array_index(&(s->mapping), mapping));
2488             if (ret)
2489                 return ret;
2490         }
2491     }
2492 
2493     return 0;
2494 }
2495 
2496 /* commit one file (adjust contents, adjust mapping),
2497    return first_mapping_index */
2498 static int commit_one_file(BDRVVVFATState* s,
2499         int dir_index, uint32_t offset)
2500 {
2501     direntry_t* direntry = array_get(&(s->directory), dir_index);
2502     uint32_t c = begin_of_direntry(direntry);
2503     uint32_t first_cluster = c;
2504     mapping_t* mapping = find_mapping_for_cluster(s, c);
2505     uint32_t size = filesize_of_direntry(direntry);
2506     char *cluster;
2507     uint32_t i;
2508     int fd = 0;
2509 
2510     assert(offset < size);
2511     assert((offset % s->cluster_size) == 0);
2512 
2513     if (mapping == NULL) {
2514         return -1;
2515     }
2516 
2517     for (i = s->cluster_size; i < offset; i += s->cluster_size)
2518         c = modified_fat_get(s, c);
2519 
2520     fd = qemu_open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
2521     if (fd < 0) {
2522         fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
2523                 strerror(errno), errno);
2524         return fd;
2525     }
2526     if (offset > 0) {
2527         if (lseek(fd, offset, SEEK_SET) != offset) {
2528             qemu_close(fd);
2529             return -3;
2530         }
2531     }
2532 
2533     cluster = g_malloc(s->cluster_size);
2534 
2535     while (offset < size) {
2536         uint32_t c1;
2537         int rest_size = (size - offset > s->cluster_size ?
2538                 s->cluster_size : size - offset);
2539         int ret;
2540 
2541         c1 = modified_fat_get(s, c);
2542 
2543         assert((size - offset == 0 && fat_eof(s, c)) ||
2544                 (size > offset && c >=2 && !fat_eof(s, c)));
2545 
2546         ret = vvfat_read(s->bs, cluster2sector(s, c),
2547             (uint8_t*)cluster, DIV_ROUND_UP(rest_size, 0x200));
2548 
2549         if (ret < 0) {
2550             qemu_close(fd);
2551             g_free(cluster);
2552             return ret;
2553         }
2554 
2555         if (write(fd, cluster, rest_size) < 0) {
2556             qemu_close(fd);
2557             g_free(cluster);
2558             return -2;
2559         }
2560 
2561         offset += rest_size;
2562         c = c1;
2563     }
2564 
2565     if (ftruncate(fd, size)) {
2566         perror("ftruncate()");
2567         qemu_close(fd);
2568         g_free(cluster);
2569         return -4;
2570     }
2571     qemu_close(fd);
2572     g_free(cluster);
2573 
2574     return commit_mappings(s, first_cluster, dir_index);
2575 }
2576 
2577 #ifdef DEBUG
2578 /* test, if all mappings point to valid direntries */
2579 static void check1(BDRVVVFATState* s)
2580 {
2581     int i;
2582     for (i = 0; i < s->mapping.next; i++) {
2583         mapping_t* mapping = array_get(&(s->mapping), i);
2584         if (mapping->mode & MODE_DELETED) {
2585             fprintf(stderr, "deleted\n");
2586             continue;
2587         }
2588         assert(mapping->dir_index < s->directory.next);
2589         direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
2590         assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
2591         if (mapping->mode & MODE_DIRECTORY) {
2592             assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
2593             assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
2594         }
2595     }
2596 }
2597 
2598 /* test, if all direntries have mappings */
2599 static void check2(BDRVVVFATState* s)
2600 {
2601     int i;
2602     int first_mapping = -1;
2603 
2604     for (i = 0; i < s->directory.next; i++) {
2605         direntry_t* direntry = array_get(&(s->directory), i);
2606 
2607         if (is_short_name(direntry) && begin_of_direntry(direntry)) {
2608             mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
2609             assert(mapping);
2610             assert(mapping->dir_index == i || is_dot(direntry));
2611             assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
2612         }
2613 
2614         if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
2615             /* cluster start */
2616             int j, count = 0;
2617 
2618             for (j = 0; j < s->mapping.next; j++) {
2619                 mapping_t* mapping = array_get(&(s->mapping), j);
2620                 if (mapping->mode & MODE_DELETED)
2621                     continue;
2622                 if (mapping->mode & MODE_DIRECTORY) {
2623                     if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
2624                         assert(++count == 1);
2625                         if (mapping->first_mapping_index == -1)
2626                             first_mapping = array_index(&(s->mapping), mapping);
2627                         else
2628                             assert(first_mapping == mapping->first_mapping_index);
2629                         if (mapping->info.dir.parent_mapping_index < 0)
2630                             assert(j == 0);
2631                         else {
2632                             mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
2633                             assert(parent->mode & MODE_DIRECTORY);
2634                             assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
2635                         }
2636                     }
2637                 }
2638             }
2639             if (count == 0)
2640                 first_mapping = -1;
2641         }
2642     }
2643 }
2644 #endif
2645 
2646 static int handle_renames_and_mkdirs(BDRVVVFATState* s)
2647 {
2648     int i;
2649 
2650 #ifdef DEBUG
2651     fprintf(stderr, "handle_renames\n");
2652     for (i = 0; i < s->commits.next; i++) {
2653         commit_t* commit = array_get(&(s->commits), i);
2654         fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
2655     }
2656 #endif
2657 
2658     for (i = 0; i < s->commits.next;) {
2659         commit_t* commit = array_get(&(s->commits), i);
2660         if (commit->action == ACTION_RENAME) {
2661             mapping_t* mapping = find_mapping_for_cluster(s,
2662                     commit->param.rename.cluster);
2663             char *old_path;
2664 
2665             if (mapping == NULL) {
2666                 return -1;
2667             }
2668             old_path = mapping->path;
2669             assert(commit->path);
2670             mapping->path = commit->path;
2671             if (rename(old_path, mapping->path))
2672                 return -2;
2673 
2674             if (mapping->mode & MODE_DIRECTORY) {
2675                 int l1 = strlen(mapping->path);
2676                 int l2 = strlen(old_path);
2677                 int diff = l1 - l2;
2678                 direntry_t* direntry = array_get(&(s->directory),
2679                         mapping->info.dir.first_dir_index);
2680                 uint32_t c = mapping->begin;
2681                 int i = 0;
2682 
2683                 /* recurse */
2684                 while (!fat_eof(s, c)) {
2685                     do {
2686                         direntry_t* d = direntry + i;
2687 
2688                         if (is_file(d) || (is_directory(d) && !is_dot(d))) {
2689                             int l;
2690                             char *new_path;
2691                             mapping_t* m = find_mapping_for_cluster(s,
2692                                     begin_of_direntry(d));
2693                             if (m == NULL) {
2694                                 return -1;
2695                             }
2696                             l = strlen(m->path);
2697                             new_path = g_malloc(l + diff + 1);
2698 
2699                             assert(!strncmp(m->path, mapping->path, l2));
2700 
2701                             pstrcpy(new_path, l + diff + 1, mapping->path);
2702                             pstrcpy(new_path + l1, l + diff + 1 - l1,
2703                                     m->path + l2);
2704 
2705                             schedule_rename(s, m->begin, new_path);
2706                         }
2707                         i++;
2708                     } while((i % (0x10 * s->sectors_per_cluster)) != 0);
2709                     c = fat_get(s, c);
2710                 }
2711             }
2712 
2713             g_free(old_path);
2714             array_remove(&(s->commits), i);
2715             continue;
2716         } else if (commit->action == ACTION_MKDIR) {
2717             mapping_t* mapping;
2718             int j, parent_path_len;
2719 
2720 #ifdef __MINGW32__
2721             if (mkdir(commit->path))
2722                 return -5;
2723 #else
2724             if (mkdir(commit->path, 0755))
2725                 return -5;
2726 #endif
2727 
2728             mapping = insert_mapping(s, commit->param.mkdir.cluster,
2729                     commit->param.mkdir.cluster + 1);
2730             if (mapping == NULL)
2731                 return -6;
2732 
2733             mapping->mode = MODE_DIRECTORY;
2734             mapping->read_only = 0;
2735             mapping->path = commit->path;
2736             j = s->directory.next;
2737             assert(j);
2738             insert_direntries(s, s->directory.next,
2739                     0x10 * s->sectors_per_cluster);
2740             mapping->info.dir.first_dir_index = j;
2741 
2742             parent_path_len = strlen(commit->path)
2743                 - strlen(get_basename(commit->path)) - 1;
2744             for (j = 0; j < s->mapping.next; j++) {
2745                 mapping_t* m = array_get(&(s->mapping), j);
2746                 if (m->first_mapping_index < 0 && m != mapping &&
2747                         !strncmp(m->path, mapping->path, parent_path_len) &&
2748                         strlen(m->path) == parent_path_len)
2749                     break;
2750             }
2751             assert(j < s->mapping.next);
2752             mapping->info.dir.parent_mapping_index = j;
2753 
2754             array_remove(&(s->commits), i);
2755             continue;
2756         }
2757 
2758         i++;
2759     }
2760     return 0;
2761 }
2762 
2763 /*
2764  * TODO: make sure that the short name is not matching *another* file
2765  */
2766 static int handle_commits(BDRVVVFATState* s)
2767 {
2768     int i, fail = 0;
2769 
2770     vvfat_close_current_file(s);
2771 
2772     for (i = 0; !fail && i < s->commits.next; i++) {
2773         commit_t* commit = array_get(&(s->commits), i);
2774         switch(commit->action) {
2775         case ACTION_RENAME: case ACTION_MKDIR:
2776             abort();
2777             fail = -2;
2778             break;
2779         case ACTION_WRITEOUT: {
2780 #ifndef NDEBUG
2781             /* these variables are only used by assert() below */
2782             direntry_t* entry = array_get(&(s->directory),
2783                     commit->param.writeout.dir_index);
2784             uint32_t begin = begin_of_direntry(entry);
2785             mapping_t* mapping = find_mapping_for_cluster(s, begin);
2786 #endif
2787 
2788             assert(mapping);
2789             assert(mapping->begin == begin);
2790             assert(commit->path == NULL);
2791 
2792             if (commit_one_file(s, commit->param.writeout.dir_index,
2793                         commit->param.writeout.modified_offset))
2794                 fail = -3;
2795 
2796             break;
2797         }
2798         case ACTION_NEW_FILE: {
2799             int begin = commit->param.new_file.first_cluster;
2800             mapping_t* mapping = find_mapping_for_cluster(s, begin);
2801             direntry_t* entry;
2802             int i;
2803 
2804             /* find direntry */
2805             for (i = 0; i < s->directory.next; i++) {
2806                 entry = array_get(&(s->directory), i);
2807                 if (is_file(entry) && begin_of_direntry(entry) == begin)
2808                     break;
2809             }
2810 
2811             if (i >= s->directory.next) {
2812                 fail = -6;
2813                 continue;
2814             }
2815 
2816             /* make sure there exists an initial mapping */
2817             if (mapping && mapping->begin != begin) {
2818                 mapping->end = begin;
2819                 mapping = NULL;
2820             }
2821             if (mapping == NULL) {
2822                 mapping = insert_mapping(s, begin, begin+1);
2823             }
2824             /* most members will be fixed in commit_mappings() */
2825             assert(commit->path);
2826             mapping->path = commit->path;
2827             mapping->read_only = 0;
2828             mapping->mode = MODE_NORMAL;
2829             mapping->info.file.offset = 0;
2830 
2831             if (commit_one_file(s, i, 0))
2832                 fail = -7;
2833 
2834             break;
2835         }
2836         default:
2837             abort();
2838         }
2839     }
2840     if (i > 0 && array_remove_slice(&(s->commits), 0, i))
2841         return -1;
2842     return fail;
2843 }
2844 
2845 static int handle_deletes(BDRVVVFATState* s)
2846 {
2847     int i, deferred = 1, deleted = 1;
2848 
2849     /* delete files corresponding to mappings marked as deleted */
2850     /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
2851     while (deferred && deleted) {
2852         deferred = 0;
2853         deleted = 0;
2854 
2855         for (i = 1; i < s->mapping.next; i++) {
2856             mapping_t* mapping = array_get(&(s->mapping), i);
2857             if (mapping->mode & MODE_DELETED) {
2858                 direntry_t* entry = array_get(&(s->directory),
2859                         mapping->dir_index);
2860 
2861                 if (is_free(entry)) {
2862                     /* remove file/directory */
2863                     if (mapping->mode & MODE_DIRECTORY) {
2864                         int j, next_dir_index = s->directory.next,
2865                         first_dir_index = mapping->info.dir.first_dir_index;
2866 
2867                         if (rmdir(mapping->path) < 0) {
2868                             if (errno == ENOTEMPTY) {
2869                                 deferred++;
2870                                 continue;
2871                             } else
2872                                 return -5;
2873                         }
2874 
2875                         for (j = 1; j < s->mapping.next; j++) {
2876                             mapping_t* m = array_get(&(s->mapping), j);
2877                             if (m->mode & MODE_DIRECTORY &&
2878                                     m->info.dir.first_dir_index >
2879                                     first_dir_index &&
2880                                     m->info.dir.first_dir_index <
2881                                     next_dir_index)
2882                                 next_dir_index =
2883                                     m->info.dir.first_dir_index;
2884                         }
2885                         remove_direntries(s, first_dir_index,
2886                                 next_dir_index - first_dir_index);
2887 
2888                         deleted++;
2889                     }
2890                 } else {
2891                     if (unlink(mapping->path))
2892                         return -4;
2893                     deleted++;
2894                 }
2895                 DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
2896                 remove_mapping(s, i);
2897             }
2898         }
2899     }
2900 
2901     return 0;
2902 }
2903 
2904 /*
2905  * synchronize mapping with new state:
2906  *
2907  * - copy FAT (with bdrv_pread)
2908  * - mark all filenames corresponding to mappings as deleted
2909  * - recurse direntries from root (using bs->bdrv_pread)
2910  * - delete files corresponding to mappings marked as deleted
2911  */
2912 static int do_commit(BDRVVVFATState* s)
2913 {
2914     int ret = 0;
2915 
2916     /* the real meat are the commits. Nothing to do? Move along! */
2917     if (s->commits.next == 0)
2918         return 0;
2919 
2920     vvfat_close_current_file(s);
2921 
2922     ret = handle_renames_and_mkdirs(s);
2923     if (ret) {
2924         fprintf(stderr, "Error handling renames (%d)\n", ret);
2925         abort();
2926         return ret;
2927     }
2928 
2929     /* copy FAT (with bdrv_pread) */
2930     memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
2931 
2932     /* recurse direntries from root (using bs->bdrv_pread) */
2933     ret = commit_direntries(s, 0, -1);
2934     if (ret) {
2935         fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
2936         abort();
2937         return ret;
2938     }
2939 
2940     ret = handle_commits(s);
2941     if (ret) {
2942         fprintf(stderr, "Error handling commits (%d)\n", ret);
2943         abort();
2944         return ret;
2945     }
2946 
2947     ret = handle_deletes(s);
2948     if (ret) {
2949         fprintf(stderr, "Error deleting\n");
2950         abort();
2951         return ret;
2952     }
2953 
2954     bdrv_make_empty(s->qcow, NULL);
2955 
2956     memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
2957 
2958 DLOG(checkpoint());
2959     return 0;
2960 }
2961 
2962 static int try_commit(BDRVVVFATState* s)
2963 {
2964     vvfat_close_current_file(s);
2965 DLOG(checkpoint());
2966     if(!is_consistent(s))
2967         return -1;
2968     return do_commit(s);
2969 }
2970 
2971 static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
2972                     const uint8_t *buf, int nb_sectors)
2973 {
2974     BDRVVVFATState *s = bs->opaque;
2975     int i, ret;
2976 
2977 DLOG(checkpoint());
2978 
2979     /* Check if we're operating in read-only mode */
2980     if (s->qcow == NULL) {
2981         return -EACCES;
2982     }
2983 
2984     vvfat_close_current_file(s);
2985 
2986     /*
2987      * Some sanity checks:
2988      * - do not allow writing to the boot sector
2989      */
2990 
2991     if (sector_num < s->offset_to_fat)
2992         return -1;
2993 
2994     for (i = sector2cluster(s, sector_num);
2995             i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
2996         mapping_t* mapping = find_mapping_for_cluster(s, i);
2997         if (mapping) {
2998             if (mapping->read_only) {
2999                 fprintf(stderr, "Tried to write to write-protected file %s\n",
3000                         mapping->path);
3001                 return -1;
3002             }
3003 
3004             if (mapping->mode & MODE_DIRECTORY) {
3005                 int begin = cluster2sector(s, i);
3006                 int end = begin + s->sectors_per_cluster, k;
3007                 int dir_index;
3008                 const direntry_t* direntries;
3009                 long_file_name lfn;
3010 
3011                 lfn_init(&lfn);
3012 
3013                 if (begin < sector_num)
3014                     begin = sector_num;
3015                 if (end > sector_num + nb_sectors)
3016                     end = sector_num + nb_sectors;
3017                 dir_index  = mapping->dir_index +
3018                     0x10 * (begin - mapping->begin * s->sectors_per_cluster);
3019                 direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
3020 
3021                 for (k = 0; k < (end - begin) * 0x10; k++) {
3022                     /* no access to the direntry of a read-only file */
3023                     if (is_short_name(direntries + k) &&
3024                             (direntries[k].attributes & 1)) {
3025                         if (memcmp(direntries + k,
3026                                     array_get(&(s->directory), dir_index + k),
3027                                     sizeof(direntry_t))) {
3028                             warn_report("tried to write to write-protected "
3029                                         "file");
3030                             return -1;
3031                         }
3032                     }
3033                 }
3034             }
3035             i = mapping->end;
3036         } else
3037             i++;
3038     }
3039 
3040     /*
3041      * Use qcow backend. Commit later.
3042      */
3043 DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
3044     ret = bdrv_pwrite(s->qcow, sector_num * BDRV_SECTOR_SIZE, buf,
3045                       nb_sectors * BDRV_SECTOR_SIZE);
3046     if (ret < 0) {
3047         fprintf(stderr, "Error writing to qcow backend\n");
3048         return ret;
3049     }
3050 
3051     for (i = sector2cluster(s, sector_num);
3052             i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
3053         if (i >= 0)
3054             s->used_clusters[i] |= USED_ALLOCATED;
3055 
3056 DLOG(checkpoint());
3057     /* TODO: add timeout */
3058     try_commit(s);
3059 
3060 DLOG(checkpoint());
3061     return 0;
3062 }
3063 
3064 static int coroutine_fn
3065 vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
3066                  QEMUIOVector *qiov, int flags)
3067 {
3068     int ret;
3069     BDRVVVFATState *s = bs->opaque;
3070     uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
3071     int nb_sectors = bytes >> BDRV_SECTOR_BITS;
3072     void *buf;
3073 
3074     assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
3075     assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
3076 
3077     buf = g_try_malloc(bytes);
3078     if (bytes && buf == NULL) {
3079         return -ENOMEM;
3080     }
3081     qemu_iovec_to_buf(qiov, 0, buf, bytes);
3082 
3083     qemu_co_mutex_lock(&s->lock);
3084     ret = vvfat_write(bs, sector_num, buf, nb_sectors);
3085     qemu_co_mutex_unlock(&s->lock);
3086 
3087     g_free(buf);
3088 
3089     return ret;
3090 }
3091 
3092 static int coroutine_fn vvfat_co_block_status(BlockDriverState *bs,
3093                                               bool want_zero, int64_t offset,
3094                                               int64_t bytes, int64_t *n,
3095                                               int64_t *map,
3096                                               BlockDriverState **file)
3097 {
3098     *n = bytes;
3099     return BDRV_BLOCK_DATA;
3100 }
3101 
3102 static int coroutine_fn
3103 write_target_commit(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
3104                     QEMUIOVector *qiov, int flags)
3105 {
3106     int ret;
3107 
3108     BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
3109     qemu_co_mutex_lock(&s->lock);
3110     ret = try_commit(s);
3111     qemu_co_mutex_unlock(&s->lock);
3112 
3113     return ret;
3114 }
3115 
3116 static BlockDriver vvfat_write_target = {
3117     .format_name        = "vvfat_write_target",
3118     .instance_size      = sizeof(void*),
3119     .bdrv_co_pwritev    = write_target_commit,
3120 };
3121 
3122 static void vvfat_qcow_options(BdrvChildRole role, bool parent_is_format,
3123                                int *child_flags, QDict *child_options,
3124                                int parent_flags, QDict *parent_options)
3125 {
3126     qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
3127     qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
3128     qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
3129 }
3130 
3131 static const BdrvChildClass child_vvfat_qcow = {
3132     .parent_is_bds      = true,
3133     .inherit_options    = vvfat_qcow_options,
3134 };
3135 
3136 static int enable_write_target(BlockDriverState *bs, Error **errp)
3137 {
3138     BDRVVVFATState *s = bs->opaque;
3139     BlockDriver *bdrv_qcow = NULL;
3140     BlockDriverState *backing;
3141     QemuOpts *opts = NULL;
3142     int ret;
3143     int size = sector2cluster(s, s->sector_count);
3144     QDict *options;
3145 
3146     s->used_clusters = calloc(size, 1);
3147 
3148     array_init(&(s->commits), sizeof(commit_t));
3149 
3150     s->qcow_filename = g_malloc(PATH_MAX);
3151     ret = get_tmp_filename(s->qcow_filename, PATH_MAX);
3152     if (ret < 0) {
3153         error_setg_errno(errp, -ret, "can't create temporary file");
3154         goto err;
3155     }
3156 
3157     bdrv_qcow = bdrv_find_format("qcow");
3158     if (!bdrv_qcow) {
3159         error_setg(errp, "Failed to locate qcow driver");
3160         ret = -ENOENT;
3161         goto err;
3162     }
3163 
3164     opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
3165     qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512,
3166                         &error_abort);
3167     qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:", &error_abort);
3168 
3169     ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts, errp);
3170     qemu_opts_del(opts);
3171     if (ret < 0) {
3172         goto err;
3173     }
3174 
3175     options = qdict_new();
3176     qdict_put_str(options, "write-target.driver", "qcow");
3177     s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs,
3178                               &child_vvfat_qcow,
3179                               BDRV_CHILD_DATA | BDRV_CHILD_METADATA,
3180                               false, errp);
3181     qobject_unref(options);
3182     if (!s->qcow) {
3183         ret = -EINVAL;
3184         goto err;
3185     }
3186 
3187 #ifndef _WIN32
3188     unlink(s->qcow_filename);
3189 #endif
3190 
3191     backing = bdrv_new_open_driver(&vvfat_write_target, NULL, BDRV_O_ALLOW_RDWR,
3192                                    &error_abort);
3193     *(void**) backing->opaque = s;
3194 
3195     bdrv_set_backing_hd(s->bs, backing, &error_abort);
3196     bdrv_unref(backing);
3197 
3198     return 0;
3199 
3200 err:
3201     g_free(s->qcow_filename);
3202     s->qcow_filename = NULL;
3203     return ret;
3204 }
3205 
3206 static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
3207                              BdrvChildRole role,
3208                              BlockReopenQueue *reopen_queue,
3209                              uint64_t perm, uint64_t shared,
3210                              uint64_t *nperm, uint64_t *nshared)
3211 {
3212     BDRVVVFATState *s = bs->opaque;
3213 
3214     assert(c == s->qcow || (role & BDRV_CHILD_COW));
3215 
3216     if (c == s->qcow) {
3217         /* This is a private node, nobody should try to attach to it */
3218         *nperm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE;
3219         *nshared = BLK_PERM_WRITE_UNCHANGED;
3220     } else {
3221         /* The backing file is there so 'commit' can use it. vvfat doesn't
3222          * access it in any way. */
3223         *nperm = 0;
3224         *nshared = BLK_PERM_ALL;
3225     }
3226 }
3227 
3228 static void vvfat_close(BlockDriverState *bs)
3229 {
3230     BDRVVVFATState *s = bs->opaque;
3231 
3232     vvfat_close_current_file(s);
3233     array_free(&(s->fat));
3234     array_free(&(s->directory));
3235     array_free(&(s->mapping));
3236     g_free(s->cluster_buffer);
3237 
3238     if (s->qcow) {
3239         migrate_del_blocker(s->migration_blocker);
3240         error_free(s->migration_blocker);
3241     }
3242 }
3243 
3244 static const char *const vvfat_strong_runtime_opts[] = {
3245     "dir",
3246     "fat-type",
3247     "floppy",
3248     "label",
3249     "rw",
3250 
3251     NULL
3252 };
3253 
3254 static BlockDriver bdrv_vvfat = {
3255     .format_name            = "vvfat",
3256     .protocol_name          = "fat",
3257     .instance_size          = sizeof(BDRVVVFATState),
3258 
3259     .bdrv_parse_filename    = vvfat_parse_filename,
3260     .bdrv_file_open         = vvfat_open,
3261     .bdrv_refresh_limits    = vvfat_refresh_limits,
3262     .bdrv_close             = vvfat_close,
3263     .bdrv_child_perm        = vvfat_child_perm,
3264 
3265     .bdrv_co_preadv         = vvfat_co_preadv,
3266     .bdrv_co_pwritev        = vvfat_co_pwritev,
3267     .bdrv_co_block_status   = vvfat_co_block_status,
3268 
3269     .strong_runtime_opts    = vvfat_strong_runtime_opts,
3270 };
3271 
3272 static void bdrv_vvfat_init(void)
3273 {
3274     bdrv_register(&bdrv_vvfat);
3275 }
3276 
3277 block_init(bdrv_vvfat_init);
3278 
3279 #ifdef DEBUG
3280 static void checkpoint(void)
3281 {
3282     assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
3283     check1(vvv);
3284     check2(vvv);
3285     assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
3286 }
3287 #endif
3288