xref: /openbmc/qemu/block/vvfat.c (revision 8e3b0cbb)
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 int32_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     int ret;
1145 
1146 #ifdef DEBUG
1147     vvv = s;
1148 #endif
1149 
1150     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
1151     if (!qemu_opts_absorb_qdict(opts, options, errp)) {
1152         ret = -EINVAL;
1153         goto fail;
1154     }
1155 
1156     dirname = qemu_opt_get(opts, "dir");
1157     if (!dirname) {
1158         error_setg(errp, "vvfat block driver requires a 'dir' option");
1159         ret = -EINVAL;
1160         goto fail;
1161     }
1162 
1163     s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);
1164     floppy = qemu_opt_get_bool(opts, "floppy", false);
1165 
1166     memset(s->volume_label, ' ', sizeof(s->volume_label));
1167     label = qemu_opt_get(opts, "label");
1168     if (label) {
1169         size_t label_length = strlen(label);
1170         if (label_length > 11) {
1171             error_setg(errp, "vvfat label cannot be longer than 11 bytes");
1172             ret = -EINVAL;
1173             goto fail;
1174         }
1175         memcpy(s->volume_label, label, label_length);
1176     } else {
1177         memcpy(s->volume_label, "QEMU VVFAT", 10);
1178     }
1179 
1180     if (floppy) {
1181         /* 1.44MB or 2.88MB floppy.  2.88MB can be FAT12 (default) or FAT16. */
1182         if (!s->fat_type) {
1183             s->fat_type = 12;
1184             secs = 36;
1185             s->sectors_per_cluster = 2;
1186         } else {
1187             secs = s->fat_type == 12 ? 18 : 36;
1188             s->sectors_per_cluster = 1;
1189         }
1190         cyls = 80;
1191         heads = 2;
1192     } else {
1193         /* 32MB or 504MB disk*/
1194         if (!s->fat_type) {
1195             s->fat_type = 16;
1196         }
1197         s->offset_to_bootsector = 0x3f;
1198         cyls = s->fat_type == 12 ? 64 : 1024;
1199         heads = 16;
1200         secs = 63;
1201     }
1202 
1203     switch (s->fat_type) {
1204     case 32:
1205         warn_report("FAT32 has not been tested. You are welcome to do so!");
1206         break;
1207     case 16:
1208     case 12:
1209         break;
1210     default:
1211         error_setg(errp, "Valid FAT types are only 12, 16 and 32");
1212         ret = -EINVAL;
1213         goto fail;
1214     }
1215 
1216 
1217     s->bs = bs;
1218 
1219     /* LATER TODO: if FAT32, adjust */
1220     s->sectors_per_cluster=0x10;
1221 
1222     s->current_cluster=0xffffffff;
1223 
1224     s->qcow = NULL;
1225     s->qcow_filename = NULL;
1226     s->fat2 = NULL;
1227     s->downcase_short_names = 1;
1228 
1229     DLOG(fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
1230                  dirname, cyls, heads, secs));
1231 
1232     s->sector_count = cyls * heads * secs - s->offset_to_bootsector;
1233     bs->total_sectors = cyls * heads * secs;
1234 
1235     if (qemu_opt_get_bool(opts, "rw", false)) {
1236         if (!bdrv_is_read_only(bs)) {
1237             ret = enable_write_target(bs, errp);
1238             if (ret < 0) {
1239                 goto fail;
1240             }
1241         } else {
1242             ret = -EPERM;
1243             error_setg(errp,
1244                        "Unable to set VVFAT to 'rw' when drive is read-only");
1245             goto fail;
1246         }
1247     } else {
1248         ret = bdrv_apply_auto_read_only(bs, NULL, errp);
1249         if (ret < 0) {
1250             goto fail;
1251         }
1252     }
1253 
1254     if (init_directories(s, dirname, heads, secs, errp)) {
1255         ret = -EIO;
1256         goto fail;
1257     }
1258 
1259     s->sector_count = s->offset_to_root_dir
1260                     + s->sectors_per_cluster * s->cluster_count;
1261 
1262     /* Disable migration when vvfat is used rw */
1263     if (s->qcow) {
1264         error_setg(&s->migration_blocker,
1265                    "The vvfat (rw) format used by node '%s' "
1266                    "does not support live migration",
1267                    bdrv_get_device_or_node_name(bs));
1268         ret = migrate_add_blocker(s->migration_blocker, errp);
1269         if (ret < 0) {
1270             error_free(s->migration_blocker);
1271             goto fail;
1272         }
1273     }
1274 
1275     if (s->offset_to_bootsector > 0) {
1276         init_mbr(s, cyls, heads, secs);
1277     }
1278 
1279     qemu_co_mutex_init(&s->lock);
1280 
1281     qemu_opts_del(opts);
1282 
1283     return 0;
1284 
1285 fail:
1286     g_free(s->qcow_filename);
1287     s->qcow_filename = NULL;
1288     g_free(s->cluster_buffer);
1289     s->cluster_buffer = NULL;
1290     g_free(s->used_clusters);
1291     s->used_clusters = NULL;
1292 
1293     qemu_opts_del(opts);
1294     return ret;
1295 }
1296 
1297 static void vvfat_refresh_limits(BlockDriverState *bs, Error **errp)
1298 {
1299     bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
1300 }
1301 
1302 static inline void vvfat_close_current_file(BDRVVVFATState *s)
1303 {
1304     if(s->current_mapping) {
1305         s->current_mapping = NULL;
1306         if (s->current_fd) {
1307                 qemu_close(s->current_fd);
1308                 s->current_fd = 0;
1309         }
1310     }
1311     s->current_cluster = -1;
1312 }
1313 
1314 /* mappings between index1 and index2-1 are supposed to be ordered
1315  * return value is the index of the last mapping for which end>cluster_num
1316  */
1317 static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
1318 {
1319     while(1) {
1320         int index3;
1321         mapping_t* mapping;
1322         index3=(index1+index2)/2;
1323         mapping=array_get(&(s->mapping),index3);
1324         assert(mapping->begin < mapping->end);
1325         if(mapping->begin>=cluster_num) {
1326             assert(index2!=index3 || index2==0);
1327             if(index2==index3)
1328                 return index1;
1329             index2=index3;
1330         } else {
1331             if(index1==index3)
1332                 return mapping->end<=cluster_num ? index2 : index1;
1333             index1=index3;
1334         }
1335         assert(index1<=index2);
1336         DLOG(mapping=array_get(&(s->mapping),index1);
1337         assert(mapping->begin<=cluster_num);
1338         assert(index2 >= s->mapping.next ||
1339                 ((mapping = array_get(&(s->mapping),index2)) &&
1340                 mapping->end>cluster_num)));
1341     }
1342 }
1343 
1344 static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
1345 {
1346     int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
1347     mapping_t* mapping;
1348     if(index>=s->mapping.next)
1349         return NULL;
1350     mapping=array_get(&(s->mapping),index);
1351     if(mapping->begin>cluster_num)
1352         return NULL;
1353     assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
1354     return mapping;
1355 }
1356 
1357 static int open_file(BDRVVVFATState* s,mapping_t* mapping)
1358 {
1359     if(!mapping)
1360         return -1;
1361     if(!s->current_mapping ||
1362             strcmp(s->current_mapping->path,mapping->path)) {
1363         /* open file */
1364         int fd = qemu_open_old(mapping->path,
1365                                O_RDONLY | O_BINARY | O_LARGEFILE);
1366         if(fd<0)
1367             return -1;
1368         vvfat_close_current_file(s);
1369         s->current_fd = fd;
1370         s->current_mapping = mapping;
1371     }
1372     return 0;
1373 }
1374 
1375 static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
1376 {
1377     if(s->current_cluster != cluster_num) {
1378         int result=0;
1379         off_t offset;
1380         assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
1381         if(!s->current_mapping
1382                 || s->current_mapping->begin>cluster_num
1383                 || s->current_mapping->end<=cluster_num) {
1384             /* binary search of mappings for file */
1385             mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
1386 
1387             assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
1388 
1389             if (mapping && mapping->mode & MODE_DIRECTORY) {
1390                 vvfat_close_current_file(s);
1391                 s->current_mapping = mapping;
1392 read_cluster_directory:
1393                 offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
1394                 s->cluster = (unsigned char*)s->directory.pointer+offset
1395                         + 0x20*s->current_mapping->info.dir.first_dir_index;
1396                 assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
1397                 assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
1398                 s->current_cluster = cluster_num;
1399                 return 0;
1400             }
1401 
1402             if(open_file(s,mapping))
1403                 return -2;
1404         } else if (s->current_mapping->mode & MODE_DIRECTORY)
1405             goto read_cluster_directory;
1406 
1407         assert(s->current_fd);
1408 
1409         offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
1410         if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
1411             return -3;
1412         s->cluster=s->cluster_buffer;
1413         result=read(s->current_fd,s->cluster,s->cluster_size);
1414         if(result<0) {
1415             s->current_cluster = -1;
1416             return -1;
1417         }
1418         s->current_cluster = cluster_num;
1419     }
1420     return 0;
1421 }
1422 
1423 #ifdef DEBUG
1424 static void print_direntry(const direntry_t* direntry)
1425 {
1426     int j = 0;
1427     char buffer[1024];
1428 
1429     fprintf(stderr, "direntry %p: ", direntry);
1430     if(!direntry)
1431         return;
1432     if(is_long_name(direntry)) {
1433         unsigned char* c=(unsigned char*)direntry;
1434         int i;
1435         for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
1436 #define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
1437             ADD_CHAR(c[i]);
1438         for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
1439             ADD_CHAR(c[i]);
1440         for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
1441             ADD_CHAR(c[i]);
1442         buffer[j] = 0;
1443         fprintf(stderr, "%s\n", buffer);
1444     } else {
1445         int i;
1446         for(i=0;i<11;i++)
1447             ADD_CHAR(direntry->name[i]);
1448         buffer[j] = 0;
1449         fprintf(stderr, "%s attributes=0x%02x begin=%u size=%u\n",
1450                 buffer,
1451                 direntry->attributes,
1452                 begin_of_direntry(direntry),le32_to_cpu(direntry->size));
1453     }
1454 }
1455 
1456 static void print_mapping(const mapping_t* mapping)
1457 {
1458     fprintf(stderr, "mapping (%p): begin, end = %u, %u, dir_index = %u, "
1459         "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
1460         mapping, mapping->begin, mapping->end, mapping->dir_index,
1461         mapping->first_mapping_index, mapping->path, mapping->mode);
1462 
1463     if (mapping->mode & MODE_DIRECTORY)
1464         fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
1465     else
1466         fprintf(stderr, "offset = %u\n", mapping->info.file.offset);
1467 }
1468 #endif
1469 
1470 static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
1471                     uint8_t *buf, int nb_sectors)
1472 {
1473     BDRVVVFATState *s = bs->opaque;
1474     int i;
1475 
1476     for(i=0;i<nb_sectors;i++,sector_num++) {
1477         if (sector_num >= bs->total_sectors)
1478            return -1;
1479         if (s->qcow) {
1480             int64_t n;
1481             int ret;
1482             ret = bdrv_is_allocated(s->qcow->bs, sector_num * BDRV_SECTOR_SIZE,
1483                                     (nb_sectors - i) * BDRV_SECTOR_SIZE, &n);
1484             if (ret < 0) {
1485                 return ret;
1486             }
1487             if (ret) {
1488                 DLOG(fprintf(stderr, "sectors %" PRId64 "+%" PRId64
1489                              " allocated\n", sector_num,
1490                              n >> BDRV_SECTOR_BITS));
1491                 if (bdrv_pread(s->qcow, sector_num * BDRV_SECTOR_SIZE,
1492                                buf + i * 0x200, n) < 0) {
1493                     return -1;
1494                 }
1495                 i += (n >> BDRV_SECTOR_BITS) - 1;
1496                 sector_num += (n >> BDRV_SECTOR_BITS) - 1;
1497                 continue;
1498             }
1499             DLOG(fprintf(stderr, "sector %" PRId64 " not allocated\n",
1500                          sector_num));
1501         }
1502         if (sector_num < s->offset_to_root_dir) {
1503             if (sector_num < s->offset_to_fat) {
1504                 memcpy(buf + i * 0x200,
1505                        &(s->first_sectors[sector_num * 0x200]),
1506                        0x200);
1507             } else if (sector_num < s->offset_to_fat + s->sectors_per_fat) {
1508                 memcpy(buf + i * 0x200,
1509                        &(s->fat.pointer[(sector_num
1510                                        - s->offset_to_fat) * 0x200]),
1511                        0x200);
1512             } else if (sector_num < s->offset_to_root_dir) {
1513                 memcpy(buf + i * 0x200,
1514                        &(s->fat.pointer[(sector_num - s->offset_to_fat
1515                                        - s->sectors_per_fat) * 0x200]),
1516                        0x200);
1517             }
1518         } else {
1519             uint32_t sector = sector_num - s->offset_to_root_dir,
1520             sector_offset_in_cluster=(sector%s->sectors_per_cluster),
1521             cluster_num=sector/s->sectors_per_cluster;
1522             if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
1523                 /* LATER TODO: strict: return -1; */
1524                 memset(buf+i*0x200,0,0x200);
1525                 continue;
1526             }
1527             memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
1528         }
1529     }
1530     return 0;
1531 }
1532 
1533 static int coroutine_fn
1534 vvfat_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
1535                 QEMUIOVector *qiov, BdrvRequestFlags flags)
1536 {
1537     int ret;
1538     BDRVVVFATState *s = bs->opaque;
1539     uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
1540     int nb_sectors = bytes >> BDRV_SECTOR_BITS;
1541     void *buf;
1542 
1543     assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
1544     assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
1545 
1546     buf = g_try_malloc(bytes);
1547     if (bytes && buf == NULL) {
1548         return -ENOMEM;
1549     }
1550 
1551     qemu_co_mutex_lock(&s->lock);
1552     ret = vvfat_read(bs, sector_num, buf, nb_sectors);
1553     qemu_co_mutex_unlock(&s->lock);
1554 
1555     qemu_iovec_from_buf(qiov, 0, buf, bytes);
1556     g_free(buf);
1557 
1558     return ret;
1559 }
1560 
1561 /* LATER TODO: statify all functions */
1562 
1563 /*
1564  * Idea of the write support (use snapshot):
1565  *
1566  * 1. check if all data is consistent, recording renames, modifications,
1567  *    new files and directories (in s->commits).
1568  *
1569  * 2. if the data is not consistent, stop committing
1570  *
1571  * 3. handle renames, and create new files and directories (do not yet
1572  *    write their contents)
1573  *
1574  * 4. walk the directories, fixing the mapping and direntries, and marking
1575  *    the handled mappings as not deleted
1576  *
1577  * 5. commit the contents of the files
1578  *
1579  * 6. handle deleted files and directories
1580  *
1581  */
1582 
1583 typedef struct commit_t {
1584     char* path;
1585     union {
1586         struct { uint32_t cluster; } rename;
1587         struct { int dir_index; uint32_t modified_offset; } writeout;
1588         struct { uint32_t first_cluster; } new_file;
1589         struct { uint32_t cluster; } mkdir;
1590     } param;
1591     /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
1592     enum {
1593         ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
1594     } action;
1595 } commit_t;
1596 
1597 static void clear_commits(BDRVVVFATState* s)
1598 {
1599     int i;
1600 DLOG(fprintf(stderr, "clear_commits (%u commits)\n", s->commits.next));
1601     for (i = 0; i < s->commits.next; i++) {
1602         commit_t* commit = array_get(&(s->commits), i);
1603         assert(commit->path || commit->action == ACTION_WRITEOUT);
1604         if (commit->action != ACTION_WRITEOUT) {
1605             assert(commit->path);
1606             g_free(commit->path);
1607         } else
1608             assert(commit->path == NULL);
1609     }
1610     s->commits.next = 0;
1611 }
1612 
1613 static void schedule_rename(BDRVVVFATState* s,
1614         uint32_t cluster, char* new_path)
1615 {
1616     commit_t* commit = array_get_next(&(s->commits));
1617     commit->path = new_path;
1618     commit->param.rename.cluster = cluster;
1619     commit->action = ACTION_RENAME;
1620 }
1621 
1622 static void schedule_writeout(BDRVVVFATState* s,
1623         int dir_index, uint32_t modified_offset)
1624 {
1625     commit_t* commit = array_get_next(&(s->commits));
1626     commit->path = NULL;
1627     commit->param.writeout.dir_index = dir_index;
1628     commit->param.writeout.modified_offset = modified_offset;
1629     commit->action = ACTION_WRITEOUT;
1630 }
1631 
1632 static void schedule_new_file(BDRVVVFATState* s,
1633         char* path, uint32_t first_cluster)
1634 {
1635     commit_t* commit = array_get_next(&(s->commits));
1636     commit->path = path;
1637     commit->param.new_file.first_cluster = first_cluster;
1638     commit->action = ACTION_NEW_FILE;
1639 }
1640 
1641 static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
1642 {
1643     commit_t* commit = array_get_next(&(s->commits));
1644     commit->path = path;
1645     commit->param.mkdir.cluster = cluster;
1646     commit->action = ACTION_MKDIR;
1647 }
1648 
1649 typedef struct {
1650     /*
1651      * Since the sequence number is at most 0x3f, and the filename
1652      * length is at most 13 times the sequence number, the maximal
1653      * filename length is 0x3f * 13 bytes.
1654      */
1655     unsigned char name[0x3f * 13 + 1];
1656     gunichar2 name2[0x3f * 13 + 1];
1657     int checksum, len;
1658     int sequence_number;
1659 } long_file_name;
1660 
1661 static void lfn_init(long_file_name* lfn)
1662 {
1663    lfn->sequence_number = lfn->len = 0;
1664    lfn->checksum = 0x100;
1665 }
1666 
1667 /* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
1668 static int parse_long_name(long_file_name* lfn,
1669         const direntry_t* direntry)
1670 {
1671     int i, j, offset;
1672     const unsigned char* pointer = (const unsigned char*)direntry;
1673 
1674     if (!is_long_name(direntry))
1675         return 1;
1676 
1677     if (pointer[0] & 0x40) {
1678         /* first entry; do some initialization */
1679         lfn->sequence_number = pointer[0] & 0x3f;
1680         lfn->checksum = pointer[13];
1681         lfn->name[0] = 0;
1682         lfn->name[lfn->sequence_number * 13] = 0;
1683     } else if ((pointer[0] & 0x3f) != --lfn->sequence_number) {
1684         /* not the expected sequence number */
1685         return -1;
1686     } else if (pointer[13] != lfn->checksum) {
1687         /* not the expected checksum */
1688         return -2;
1689     } else if (pointer[12] || pointer[26] || pointer[27]) {
1690         /* invalid zero fields */
1691         return -3;
1692     }
1693 
1694     offset = 13 * (lfn->sequence_number - 1);
1695     for (i = 0, j = 1; i < 13; i++, j+=2) {
1696         if (j == 11)
1697             j = 14;
1698         else if (j == 26)
1699             j = 28;
1700 
1701         if (pointer[j] == 0 && pointer[j + 1] == 0) {
1702             /* end of long file name */
1703             break;
1704         }
1705         gunichar2 c = (pointer[j + 1] << 8) + pointer[j];
1706         lfn->name2[offset + i] = c;
1707     }
1708 
1709     if (pointer[0] & 0x40) {
1710         /* first entry; set len */
1711         lfn->len = offset + i;
1712     }
1713     if ((pointer[0] & 0x3f) == 0x01) {
1714         /* last entry; finalize entry */
1715         glong olen;
1716         gchar *utf8 = g_utf16_to_utf8(lfn->name2, lfn->len, NULL, &olen, NULL);
1717         if (!utf8) {
1718             return -4;
1719         }
1720         lfn->len = olen;
1721         memcpy(lfn->name, utf8, olen + 1);
1722         g_free(utf8);
1723     }
1724 
1725     return 0;
1726 }
1727 
1728 /* returns 0 if successful, >0 if no short_name, and <0 on error */
1729 static int parse_short_name(BDRVVVFATState* s,
1730         long_file_name* lfn, direntry_t* direntry)
1731 {
1732     int i, j;
1733 
1734     if (!is_short_name(direntry))
1735         return 1;
1736 
1737     for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
1738     for (i = 0; i <= j; i++) {
1739         uint8_t c = direntry->name[i];
1740         if (c != to_valid_short_char(c)) {
1741             return -1;
1742         } else if (s->downcase_short_names) {
1743             lfn->name[i] = qemu_tolower(direntry->name[i]);
1744         } else {
1745             lfn->name[i] = direntry->name[i];
1746         }
1747     }
1748 
1749     for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) {
1750     }
1751     if (j >= 0) {
1752         lfn->name[i++] = '.';
1753         lfn->name[i + j + 1] = '\0';
1754         for (;j >= 0; j--) {
1755             uint8_t c = direntry->name[8 + j];
1756             if (c != to_valid_short_char(c)) {
1757                 return -2;
1758             } else if (s->downcase_short_names) {
1759                 lfn->name[i + j] = qemu_tolower(c);
1760             } else {
1761                 lfn->name[i + j] = c;
1762             }
1763         }
1764     } else
1765         lfn->name[i + j + 1] = '\0';
1766 
1767     if (lfn->name[0] == DIR_KANJI_FAKE) {
1768         lfn->name[0] = DIR_KANJI;
1769     }
1770     lfn->len = strlen((char*)lfn->name);
1771 
1772     return 0;
1773 }
1774 
1775 static inline uint32_t modified_fat_get(BDRVVVFATState* s,
1776         unsigned int cluster)
1777 {
1778     if (cluster < s->last_cluster_of_root_directory) {
1779         if (cluster + 1 == s->last_cluster_of_root_directory)
1780             return s->max_fat_value;
1781         else
1782             return cluster + 1;
1783     }
1784 
1785     if (s->fat_type==32) {
1786         uint32_t* entry=((uint32_t*)s->fat2)+cluster;
1787         return le32_to_cpu(*entry);
1788     } else if (s->fat_type==16) {
1789         uint16_t* entry=((uint16_t*)s->fat2)+cluster;
1790         return le16_to_cpu(*entry);
1791     } else {
1792         const uint8_t* x=s->fat2+cluster*3/2;
1793         return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
1794     }
1795 }
1796 
1797 static inline bool cluster_was_modified(BDRVVVFATState *s,
1798                                         uint32_t cluster_num)
1799 {
1800     int was_modified = 0;
1801     int i;
1802 
1803     if (s->qcow == NULL) {
1804         return 0;
1805     }
1806 
1807     for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) {
1808         was_modified = bdrv_is_allocated(s->qcow->bs,
1809                                          (cluster2sector(s, cluster_num) +
1810                                           i) * BDRV_SECTOR_SIZE,
1811                                          BDRV_SECTOR_SIZE, NULL);
1812     }
1813 
1814     /*
1815      * Note that this treats failures to learn allocation status the
1816      * same as if an allocation has occurred.  It's as safe as
1817      * anything else, given that a failure to learn allocation status
1818      * will probably result in more failures.
1819      */
1820     return !!was_modified;
1821 }
1822 
1823 static const char* get_basename(const char* path)
1824 {
1825     char* basename = strrchr(path, '/');
1826     if (basename == NULL)
1827         return path;
1828     else
1829         return basename + 1; /* strip '/' */
1830 }
1831 
1832 /*
1833  * The array s->used_clusters holds the states of the clusters. If it is
1834  * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
1835  * was modified, bit 3 is set.
1836  * If any cluster is allocated, but not part of a file or directory, this
1837  * driver refuses to commit.
1838  */
1839 typedef enum {
1840      USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
1841 } used_t;
1842 
1843 /*
1844  * get_cluster_count_for_direntry() not only determines how many clusters
1845  * are occupied by direntry, but also if it was renamed or modified.
1846  *
1847  * A file is thought to be renamed *only* if there already was a file with
1848  * exactly the same first cluster, but a different name.
1849  *
1850  * Further, the files/directories handled by this function are
1851  * assumed to be *not* deleted (and *only* those).
1852  */
1853 static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
1854         direntry_t* direntry, const char* path)
1855 {
1856     /*
1857      * This is a little bit tricky:
1858      * IF the guest OS just inserts a cluster into the file chain,
1859      * and leaves the rest alone, (i.e. the original file had clusters
1860      * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
1861      *
1862      * - do_commit will write the cluster into the file at the given
1863      *   offset, but
1864      *
1865      * - the cluster which is overwritten should be moved to a later
1866      *   position in the file.
1867      *
1868      * I am not aware that any OS does something as braindead, but this
1869      * situation could happen anyway when not committing for a long time.
1870      * Just to be sure that this does not bite us, detect it, and copy the
1871      * contents of the clusters to-be-overwritten into the qcow.
1872      */
1873     int copy_it = 0;
1874     int was_modified = 0;
1875     int32_t ret = 0;
1876 
1877     uint32_t cluster_num = begin_of_direntry(direntry);
1878     uint32_t offset = 0;
1879     int first_mapping_index = -1;
1880     mapping_t* mapping = NULL;
1881     const char* basename2 = NULL;
1882 
1883     vvfat_close_current_file(s);
1884 
1885     /* the root directory */
1886     if (cluster_num == 0)
1887         return 0;
1888 
1889     /* write support */
1890     if (s->qcow) {
1891         basename2 = get_basename(path);
1892 
1893         mapping = find_mapping_for_cluster(s, cluster_num);
1894 
1895         if (mapping) {
1896             const char* basename;
1897 
1898             assert(mapping->mode & MODE_DELETED);
1899             mapping->mode &= ~MODE_DELETED;
1900 
1901             basename = get_basename(mapping->path);
1902 
1903             assert(mapping->mode & MODE_NORMAL);
1904 
1905             /* rename */
1906             if (strcmp(basename, basename2))
1907                 schedule_rename(s, cluster_num, g_strdup(path));
1908         } else if (is_file(direntry))
1909             /* new file */
1910             schedule_new_file(s, g_strdup(path), cluster_num);
1911         else {
1912             abort();
1913             return 0;
1914         }
1915     }
1916 
1917     while(1) {
1918         if (s->qcow) {
1919             if (!copy_it && cluster_was_modified(s, cluster_num)) {
1920                 if (mapping == NULL ||
1921                         mapping->begin > cluster_num ||
1922                         mapping->end <= cluster_num)
1923                 mapping = find_mapping_for_cluster(s, cluster_num);
1924 
1925 
1926                 if (mapping &&
1927                         (mapping->mode & MODE_DIRECTORY) == 0) {
1928 
1929                     /* was modified in qcow */
1930                     if (offset != mapping->info.file.offset + s->cluster_size
1931                             * (cluster_num - mapping->begin)) {
1932                         /* offset of this cluster in file chain has changed */
1933                         abort();
1934                         copy_it = 1;
1935                     } else if (offset == 0) {
1936                         const char* basename = get_basename(mapping->path);
1937 
1938                         if (strcmp(basename, basename2))
1939                             copy_it = 1;
1940                         first_mapping_index = array_index(&(s->mapping), mapping);
1941                     }
1942 
1943                     if (mapping->first_mapping_index != first_mapping_index
1944                             && mapping->info.file.offset > 0) {
1945                         abort();
1946                         copy_it = 1;
1947                     }
1948 
1949                     /* need to write out? */
1950                     if (!was_modified && is_file(direntry)) {
1951                         was_modified = 1;
1952                         schedule_writeout(s, mapping->dir_index, offset);
1953                     }
1954                 }
1955             }
1956 
1957             if (copy_it) {
1958                 int i;
1959                 /*
1960                  * This is horribly inefficient, but that is okay, since
1961                  * it is rarely executed, if at all.
1962                  */
1963                 int64_t offset = cluster2sector(s, cluster_num);
1964 
1965                 vvfat_close_current_file(s);
1966                 for (i = 0; i < s->sectors_per_cluster; i++) {
1967                     int res;
1968 
1969                     res = bdrv_is_allocated(s->qcow->bs,
1970                                             (offset + i) * BDRV_SECTOR_SIZE,
1971                                             BDRV_SECTOR_SIZE, NULL);
1972                     if (res < 0) {
1973                         return -1;
1974                     }
1975                     if (!res) {
1976                         res = vvfat_read(s->bs, offset, s->cluster_buffer, 1);
1977                         if (res) {
1978                             return -1;
1979                         }
1980                         res = bdrv_pwrite(s->qcow, offset * BDRV_SECTOR_SIZE,
1981                                           s->cluster_buffer, BDRV_SECTOR_SIZE);
1982                         if (res < 0) {
1983                             return -2;
1984                         }
1985                     }
1986                 }
1987             }
1988         }
1989 
1990         ret++;
1991         if (s->used_clusters[cluster_num] & USED_ANY)
1992             return 0;
1993         s->used_clusters[cluster_num] = USED_FILE;
1994 
1995         cluster_num = modified_fat_get(s, cluster_num);
1996 
1997         if (fat_eof(s, cluster_num))
1998             return ret;
1999         else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
2000             return -1;
2001 
2002         offset += s->cluster_size;
2003     }
2004 }
2005 
2006 /*
2007  * This function looks at the modified data (qcow).
2008  * It returns 0 upon inconsistency or error, and the number of clusters
2009  * used by the directory, its subdirectories and their files.
2010  */
2011 static int check_directory_consistency(BDRVVVFATState *s,
2012         int cluster_num, const char* path)
2013 {
2014     int ret = 0;
2015     unsigned char* cluster = g_malloc(s->cluster_size);
2016     direntry_t* direntries = (direntry_t*)cluster;
2017     mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
2018 
2019     long_file_name lfn;
2020     int path_len = strlen(path);
2021     char path2[PATH_MAX + 1];
2022 
2023     assert(path_len < PATH_MAX); /* len was tested before! */
2024     pstrcpy(path2, sizeof(path2), path);
2025     path2[path_len] = '/';
2026     path2[path_len + 1] = '\0';
2027 
2028     if (mapping) {
2029         const char* basename = get_basename(mapping->path);
2030         const char* basename2 = get_basename(path);
2031 
2032         assert(mapping->mode & MODE_DIRECTORY);
2033 
2034         assert(mapping->mode & MODE_DELETED);
2035         mapping->mode &= ~MODE_DELETED;
2036 
2037         if (strcmp(basename, basename2))
2038             schedule_rename(s, cluster_num, g_strdup(path));
2039     } else
2040         /* new directory */
2041         schedule_mkdir(s, cluster_num, g_strdup(path));
2042 
2043     lfn_init(&lfn);
2044     do {
2045         int i;
2046         int subret = 0;
2047 
2048         ret++;
2049 
2050         if (s->used_clusters[cluster_num] & USED_ANY) {
2051             fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
2052             goto fail;
2053         }
2054         s->used_clusters[cluster_num] = USED_DIRECTORY;
2055 
2056 DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
2057         subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
2058                 s->sectors_per_cluster);
2059         if (subret) {
2060             fprintf(stderr, "Error fetching direntries\n");
2061         fail:
2062             g_free(cluster);
2063             return 0;
2064         }
2065 
2066         for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
2067             int cluster_count = 0;
2068 
2069 DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i));
2070             if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
2071                     is_free(direntries + i))
2072                 continue;
2073 
2074             subret = parse_long_name(&lfn, direntries + i);
2075             if (subret < 0) {
2076                 fprintf(stderr, "Error in long name\n");
2077                 goto fail;
2078             }
2079             if (subret == 0 || is_free(direntries + i))
2080                 continue;
2081 
2082             if (fat_chksum(direntries+i) != lfn.checksum) {
2083                 subret = parse_short_name(s, &lfn, direntries + i);
2084                 if (subret < 0) {
2085                     fprintf(stderr, "Error in short name (%d)\n", subret);
2086                     goto fail;
2087                 }
2088                 if (subret > 0 || !strcmp((char*)lfn.name, ".")
2089                         || !strcmp((char*)lfn.name, ".."))
2090                     continue;
2091             }
2092             lfn.checksum = 0x100; /* cannot use long name twice */
2093 
2094             if (!valid_filename(lfn.name)) {
2095                 fprintf(stderr, "Invalid file name\n");
2096                 goto fail;
2097             }
2098             if (path_len + 1 + lfn.len >= PATH_MAX) {
2099                 fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
2100                 goto fail;
2101             }
2102             pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
2103                     (char*)lfn.name);
2104 
2105             if (is_directory(direntries + i)) {
2106                 if (begin_of_direntry(direntries + i) == 0) {
2107                     DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
2108                     goto fail;
2109                 }
2110                 cluster_count = check_directory_consistency(s,
2111                         begin_of_direntry(direntries + i), path2);
2112                 if (cluster_count == 0) {
2113                     DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
2114                     goto fail;
2115                 }
2116             } else if (is_file(direntries + i)) {
2117                 /* check file size with FAT */
2118                 cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
2119                 if (cluster_count !=
2120             DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) {
2121                     DLOG(fprintf(stderr, "Cluster count mismatch\n"));
2122                     goto fail;
2123                 }
2124             } else
2125                 abort(); /* cluster_count = 0; */
2126 
2127             ret += cluster_count;
2128         }
2129 
2130         cluster_num = modified_fat_get(s, cluster_num);
2131     } while(!fat_eof(s, cluster_num));
2132 
2133     g_free(cluster);
2134     return ret;
2135 }
2136 
2137 /* returns 1 on success */
2138 static int is_consistent(BDRVVVFATState* s)
2139 {
2140     int i, check;
2141     int used_clusters_count = 0;
2142 
2143 DLOG(checkpoint());
2144     /*
2145      * - get modified FAT
2146      * - compare the two FATs (TODO)
2147      * - get buffer for marking used clusters
2148      * - recurse direntries from root (using bs->bdrv_pread to make
2149      *    sure to get the new data)
2150      *   - check that the FAT agrees with the size
2151      *   - count the number of clusters occupied by this directory and
2152      *     its files
2153      * - check that the cumulative used cluster count agrees with the
2154      *   FAT
2155      * - if all is fine, return number of used clusters
2156      */
2157     if (s->fat2 == NULL) {
2158         int size = 0x200 * s->sectors_per_fat;
2159         s->fat2 = g_malloc(size);
2160         memcpy(s->fat2, s->fat.pointer, size);
2161     }
2162     check = vvfat_read(s->bs,
2163             s->offset_to_fat, s->fat2, s->sectors_per_fat);
2164     if (check) {
2165         fprintf(stderr, "Could not copy fat\n");
2166         return 0;
2167     }
2168     assert (s->used_clusters);
2169     for (i = 0; i < sector2cluster(s, s->sector_count); i++)
2170         s->used_clusters[i] &= ~USED_ANY;
2171 
2172     clear_commits(s);
2173 
2174     /* mark every mapped file/directory as deleted.
2175      * (check_directory_consistency() will unmark those still present). */
2176     if (s->qcow)
2177         for (i = 0; i < s->mapping.next; i++) {
2178             mapping_t* mapping = array_get(&(s->mapping), i);
2179             if (mapping->first_mapping_index < 0)
2180                 mapping->mode |= MODE_DELETED;
2181         }
2182 
2183     used_clusters_count = check_directory_consistency(s, 0, s->path);
2184     if (used_clusters_count <= 0) {
2185         DLOG(fprintf(stderr, "problem in directory\n"));
2186         return 0;
2187     }
2188 
2189     check = s->last_cluster_of_root_directory;
2190     for (i = check; i < sector2cluster(s, s->sector_count); i++) {
2191         if (modified_fat_get(s, i)) {
2192             if(!s->used_clusters[i]) {
2193                 DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
2194                 return 0;
2195             }
2196             check++;
2197         }
2198 
2199         if (s->used_clusters[i] == USED_ALLOCATED) {
2200             /* allocated, but not used... */
2201             DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
2202             return 0;
2203         }
2204     }
2205 
2206     if (check != used_clusters_count)
2207         return 0;
2208 
2209     return used_clusters_count;
2210 }
2211 
2212 static inline void adjust_mapping_indices(BDRVVVFATState* s,
2213         int offset, int adjust)
2214 {
2215     int i;
2216 
2217     for (i = 0; i < s->mapping.next; i++) {
2218         mapping_t* mapping = array_get(&(s->mapping), i);
2219 
2220 #define ADJUST_MAPPING_INDEX(name) \
2221         if (mapping->name >= offset) \
2222             mapping->name += adjust
2223 
2224         ADJUST_MAPPING_INDEX(first_mapping_index);
2225         if (mapping->mode & MODE_DIRECTORY)
2226             ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
2227     }
2228 }
2229 
2230 /* insert or update mapping */
2231 static mapping_t* insert_mapping(BDRVVVFATState* s,
2232         uint32_t begin, uint32_t end)
2233 {
2234     /*
2235      * - find mapping where mapping->begin >= begin,
2236      * - if mapping->begin > begin: insert
2237      *   - adjust all references to mappings!
2238      * - else: adjust
2239      * - replace name
2240      */
2241     int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
2242     mapping_t* mapping = NULL;
2243     mapping_t* first_mapping = array_get(&(s->mapping), 0);
2244 
2245     if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
2246             && mapping->begin < begin) {
2247         mapping->end = begin;
2248         index++;
2249         mapping = array_get(&(s->mapping), index);
2250     }
2251     if (index >= s->mapping.next || mapping->begin > begin) {
2252         mapping = array_insert(&(s->mapping), index, 1);
2253         mapping->path = NULL;
2254         adjust_mapping_indices(s, index, +1);
2255     }
2256 
2257     mapping->begin = begin;
2258     mapping->end = end;
2259 
2260 DLOG(mapping_t* next_mapping;
2261 assert(index + 1 >= s->mapping.next ||
2262 ((next_mapping = array_get(&(s->mapping), index + 1)) &&
2263  next_mapping->begin >= end)));
2264 
2265     if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
2266         s->current_mapping = array_get(&(s->mapping),
2267                 s->current_mapping - first_mapping);
2268 
2269     return mapping;
2270 }
2271 
2272 static int remove_mapping(BDRVVVFATState* s, int mapping_index)
2273 {
2274     mapping_t* mapping = array_get(&(s->mapping), mapping_index);
2275     mapping_t* first_mapping = array_get(&(s->mapping), 0);
2276 
2277     /* free mapping */
2278     if (mapping->first_mapping_index < 0) {
2279         g_free(mapping->path);
2280     }
2281 
2282     /* remove from s->mapping */
2283     array_remove(&(s->mapping), mapping_index);
2284 
2285     /* adjust all references to mappings */
2286     adjust_mapping_indices(s, mapping_index, -1);
2287 
2288     if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
2289         s->current_mapping = array_get(&(s->mapping),
2290                 s->current_mapping - first_mapping);
2291 
2292     return 0;
2293 }
2294 
2295 static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
2296 {
2297     int i;
2298     for (i = 0; i < s->mapping.next; i++) {
2299         mapping_t* mapping = array_get(&(s->mapping), i);
2300         if (mapping->dir_index >= offset)
2301             mapping->dir_index += adjust;
2302         if ((mapping->mode & MODE_DIRECTORY) &&
2303                 mapping->info.dir.first_dir_index >= offset)
2304             mapping->info.dir.first_dir_index += adjust;
2305     }
2306 }
2307 
2308 static direntry_t* insert_direntries(BDRVVVFATState* s,
2309         int dir_index, int count)
2310 {
2311     /*
2312      * make room in s->directory,
2313      * adjust_dirindices
2314      */
2315     direntry_t* result = array_insert(&(s->directory), dir_index, count);
2316     if (result == NULL)
2317         return NULL;
2318     adjust_dirindices(s, dir_index, count);
2319     return result;
2320 }
2321 
2322 static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
2323 {
2324     int ret = array_remove_slice(&(s->directory), dir_index, count);
2325     if (ret)
2326         return ret;
2327     adjust_dirindices(s, dir_index, -count);
2328     return 0;
2329 }
2330 
2331 /*
2332  * Adapt the mappings of the cluster chain starting at first cluster
2333  * (i.e. if a file starts at first_cluster, the chain is followed according
2334  * to the modified fat, and the corresponding entries in s->mapping are
2335  * adjusted)
2336  */
2337 static int commit_mappings(BDRVVVFATState* s,
2338         uint32_t first_cluster, int dir_index)
2339 {
2340     mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
2341     direntry_t* direntry = array_get(&(s->directory), dir_index);
2342     uint32_t cluster = first_cluster;
2343 
2344     vvfat_close_current_file(s);
2345 
2346     assert(mapping);
2347     assert(mapping->begin == first_cluster);
2348     mapping->first_mapping_index = -1;
2349     mapping->dir_index = dir_index;
2350     mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
2351         MODE_DIRECTORY : MODE_NORMAL;
2352 
2353     while (!fat_eof(s, cluster)) {
2354         uint32_t c, c1;
2355 
2356         for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
2357                 c = c1, c1 = modified_fat_get(s, c1));
2358 
2359         c++;
2360         if (c > mapping->end) {
2361             int index = array_index(&(s->mapping), mapping);
2362             int i, max_i = s->mapping.next - index;
2363             for (i = 1; i < max_i && mapping[i].begin < c; i++);
2364             while (--i > 0)
2365                 remove_mapping(s, index + 1);
2366         }
2367         assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
2368                 || mapping[1].begin >= c);
2369         mapping->end = c;
2370 
2371         if (!fat_eof(s, c1)) {
2372             int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
2373             mapping_t* next_mapping = i >= s->mapping.next ? NULL :
2374                 array_get(&(s->mapping), i);
2375 
2376             if (next_mapping == NULL || next_mapping->begin > c1) {
2377                 int i1 = array_index(&(s->mapping), mapping);
2378 
2379                 next_mapping = insert_mapping(s, c1, c1+1);
2380 
2381                 if (c1 < c)
2382                     i1++;
2383                 mapping = array_get(&(s->mapping), i1);
2384             }
2385 
2386             next_mapping->dir_index = mapping->dir_index;
2387             next_mapping->first_mapping_index =
2388                 mapping->first_mapping_index < 0 ?
2389                 array_index(&(s->mapping), mapping) :
2390                 mapping->first_mapping_index;
2391             next_mapping->path = mapping->path;
2392             next_mapping->mode = mapping->mode;
2393             next_mapping->read_only = mapping->read_only;
2394             if (mapping->mode & MODE_DIRECTORY) {
2395                 next_mapping->info.dir.parent_mapping_index =
2396                         mapping->info.dir.parent_mapping_index;
2397                 next_mapping->info.dir.first_dir_index =
2398                         mapping->info.dir.first_dir_index +
2399                         0x10 * s->sectors_per_cluster *
2400                         (mapping->end - mapping->begin);
2401             } else
2402                 next_mapping->info.file.offset = mapping->info.file.offset +
2403                         mapping->end - mapping->begin;
2404 
2405             mapping = next_mapping;
2406         }
2407 
2408         cluster = c1;
2409     }
2410 
2411     return 0;
2412 }
2413 
2414 static int commit_direntries(BDRVVVFATState* s,
2415         int dir_index, int parent_mapping_index)
2416 {
2417     direntry_t* direntry = array_get(&(s->directory), dir_index);
2418     uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
2419     mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
2420     int factor = 0x10 * s->sectors_per_cluster;
2421     int old_cluster_count, new_cluster_count;
2422     int current_dir_index;
2423     int first_dir_index;
2424     int ret, i;
2425     uint32_t c;
2426 
2427     assert(direntry);
2428     assert(mapping);
2429     assert(mapping->begin == first_cluster);
2430     assert(mapping->info.dir.first_dir_index < s->directory.next);
2431     assert(mapping->mode & MODE_DIRECTORY);
2432     assert(dir_index == 0 || is_directory(direntry));
2433 
2434     DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n",
2435                  mapping->path, parent_mapping_index));
2436 
2437     current_dir_index = mapping->info.dir.first_dir_index;
2438     first_dir_index = current_dir_index;
2439     mapping->info.dir.parent_mapping_index = parent_mapping_index;
2440 
2441     if (first_cluster == 0) {
2442         old_cluster_count = new_cluster_count =
2443             s->last_cluster_of_root_directory;
2444     } else {
2445         for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2446                 c = fat_get(s, c))
2447             old_cluster_count++;
2448 
2449         for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2450                 c = modified_fat_get(s, c))
2451             new_cluster_count++;
2452     }
2453 
2454     if (new_cluster_count > old_cluster_count) {
2455         if (insert_direntries(s,
2456                 current_dir_index + factor * old_cluster_count,
2457                 factor * (new_cluster_count - old_cluster_count)) == NULL)
2458             return -1;
2459     } else if (new_cluster_count < old_cluster_count)
2460         remove_direntries(s,
2461                 current_dir_index + factor * new_cluster_count,
2462                 factor * (old_cluster_count - new_cluster_count));
2463 
2464     for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
2465         direntry_t *first_direntry;
2466         void* direntry = array_get(&(s->directory), current_dir_index);
2467         int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
2468                 s->sectors_per_cluster);
2469         if (ret)
2470             return ret;
2471 
2472         /* The first directory entry on the filesystem is the volume name */
2473         first_direntry = (direntry_t*) s->directory.pointer;
2474         assert(!memcmp(first_direntry->name, s->volume_label, 11));
2475 
2476         current_dir_index += factor;
2477     }
2478 
2479     ret = commit_mappings(s, first_cluster, dir_index);
2480     if (ret)
2481         return ret;
2482 
2483     /* recurse */
2484     for (i = 0; i < factor * new_cluster_count; i++) {
2485         direntry = array_get(&(s->directory), first_dir_index + i);
2486         if (is_directory(direntry) && !is_dot(direntry)) {
2487             mapping = find_mapping_for_cluster(s, first_cluster);
2488             if (mapping == NULL) {
2489                 return -1;
2490             }
2491             assert(mapping->mode & MODE_DIRECTORY);
2492             ret = commit_direntries(s, first_dir_index + i,
2493                 array_index(&(s->mapping), mapping));
2494             if (ret)
2495                 return ret;
2496         }
2497     }
2498 
2499     return 0;
2500 }
2501 
2502 /* commit one file (adjust contents, adjust mapping),
2503    return first_mapping_index */
2504 static int commit_one_file(BDRVVVFATState* s,
2505         int dir_index, uint32_t offset)
2506 {
2507     direntry_t* direntry = array_get(&(s->directory), dir_index);
2508     uint32_t c = begin_of_direntry(direntry);
2509     uint32_t first_cluster = c;
2510     mapping_t* mapping = find_mapping_for_cluster(s, c);
2511     uint32_t size = filesize_of_direntry(direntry);
2512     char *cluster;
2513     uint32_t i;
2514     int fd = 0;
2515 
2516     assert(offset < size);
2517     assert((offset % s->cluster_size) == 0);
2518 
2519     if (mapping == NULL) {
2520         return -1;
2521     }
2522 
2523     for (i = s->cluster_size; i < offset; i += s->cluster_size)
2524         c = modified_fat_get(s, c);
2525 
2526     fd = qemu_open_old(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
2527     if (fd < 0) {
2528         fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
2529                 strerror(errno), errno);
2530         return fd;
2531     }
2532     if (offset > 0) {
2533         if (lseek(fd, offset, SEEK_SET) != offset) {
2534             qemu_close(fd);
2535             return -3;
2536         }
2537     }
2538 
2539     cluster = g_malloc(s->cluster_size);
2540 
2541     while (offset < size) {
2542         uint32_t c1;
2543         int rest_size = (size - offset > s->cluster_size ?
2544                 s->cluster_size : size - offset);
2545         int ret;
2546 
2547         c1 = modified_fat_get(s, c);
2548 
2549         assert((size - offset == 0 && fat_eof(s, c)) ||
2550                 (size > offset && c >=2 && !fat_eof(s, c)));
2551 
2552         ret = vvfat_read(s->bs, cluster2sector(s, c),
2553             (uint8_t*)cluster, DIV_ROUND_UP(rest_size, 0x200));
2554 
2555         if (ret < 0) {
2556             qemu_close(fd);
2557             g_free(cluster);
2558             return ret;
2559         }
2560 
2561         if (write(fd, cluster, rest_size) < 0) {
2562             qemu_close(fd);
2563             g_free(cluster);
2564             return -2;
2565         }
2566 
2567         offset += rest_size;
2568         c = c1;
2569     }
2570 
2571     if (ftruncate(fd, size)) {
2572         perror("ftruncate()");
2573         qemu_close(fd);
2574         g_free(cluster);
2575         return -4;
2576     }
2577     qemu_close(fd);
2578     g_free(cluster);
2579 
2580     return commit_mappings(s, first_cluster, dir_index);
2581 }
2582 
2583 #ifdef DEBUG
2584 /* test, if all mappings point to valid direntries */
2585 static void check1(BDRVVVFATState* s)
2586 {
2587     int i;
2588     for (i = 0; i < s->mapping.next; i++) {
2589         mapping_t* mapping = array_get(&(s->mapping), i);
2590         if (mapping->mode & MODE_DELETED) {
2591             fprintf(stderr, "deleted\n");
2592             continue;
2593         }
2594         assert(mapping->dir_index < s->directory.next);
2595         direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
2596         assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
2597         if (mapping->mode & MODE_DIRECTORY) {
2598             assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
2599             assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
2600         }
2601     }
2602 }
2603 
2604 /* test, if all direntries have mappings */
2605 static void check2(BDRVVVFATState* s)
2606 {
2607     int i;
2608     int first_mapping = -1;
2609 
2610     for (i = 0; i < s->directory.next; i++) {
2611         direntry_t* direntry = array_get(&(s->directory), i);
2612 
2613         if (is_short_name(direntry) && begin_of_direntry(direntry)) {
2614             mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
2615             assert(mapping);
2616             assert(mapping->dir_index == i || is_dot(direntry));
2617             assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
2618         }
2619 
2620         if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
2621             /* cluster start */
2622             int j, count = 0;
2623 
2624             for (j = 0; j < s->mapping.next; j++) {
2625                 mapping_t* mapping = array_get(&(s->mapping), j);
2626                 if (mapping->mode & MODE_DELETED)
2627                     continue;
2628                 if (mapping->mode & MODE_DIRECTORY) {
2629                     if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
2630                         assert(++count == 1);
2631                         if (mapping->first_mapping_index == -1)
2632                             first_mapping = array_index(&(s->mapping), mapping);
2633                         else
2634                             assert(first_mapping == mapping->first_mapping_index);
2635                         if (mapping->info.dir.parent_mapping_index < 0)
2636                             assert(j == 0);
2637                         else {
2638                             mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
2639                             assert(parent->mode & MODE_DIRECTORY);
2640                             assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
2641                         }
2642                     }
2643                 }
2644             }
2645             if (count == 0)
2646                 first_mapping = -1;
2647         }
2648     }
2649 }
2650 #endif
2651 
2652 static int handle_renames_and_mkdirs(BDRVVVFATState* s)
2653 {
2654     int i;
2655 
2656 #ifdef DEBUG
2657     fprintf(stderr, "handle_renames\n");
2658     for (i = 0; i < s->commits.next; i++) {
2659         commit_t* commit = array_get(&(s->commits), i);
2660         fprintf(stderr, "%d, %s (%u, %d)\n", i,
2661                 commit->path ? commit->path : "(null)",
2662                 commit->param.rename.cluster, commit->action);
2663     }
2664 #endif
2665 
2666     for (i = 0; i < s->commits.next;) {
2667         commit_t* commit = array_get(&(s->commits), i);
2668         if (commit->action == ACTION_RENAME) {
2669             mapping_t* mapping = find_mapping_for_cluster(s,
2670                     commit->param.rename.cluster);
2671             char *old_path;
2672 
2673             if (mapping == NULL) {
2674                 return -1;
2675             }
2676             old_path = mapping->path;
2677             assert(commit->path);
2678             mapping->path = commit->path;
2679             if (rename(old_path, mapping->path))
2680                 return -2;
2681 
2682             if (mapping->mode & MODE_DIRECTORY) {
2683                 int l1 = strlen(mapping->path);
2684                 int l2 = strlen(old_path);
2685                 int diff = l1 - l2;
2686                 direntry_t* direntry = array_get(&(s->directory),
2687                         mapping->info.dir.first_dir_index);
2688                 uint32_t c = mapping->begin;
2689                 int i = 0;
2690 
2691                 /* recurse */
2692                 while (!fat_eof(s, c)) {
2693                     do {
2694                         direntry_t* d = direntry + i;
2695 
2696                         if (is_file(d) || (is_directory(d) && !is_dot(d))) {
2697                             int l;
2698                             char *new_path;
2699                             mapping_t* m = find_mapping_for_cluster(s,
2700                                     begin_of_direntry(d));
2701                             if (m == NULL) {
2702                                 return -1;
2703                             }
2704                             l = strlen(m->path);
2705                             new_path = g_malloc(l + diff + 1);
2706 
2707                             assert(!strncmp(m->path, mapping->path, l2));
2708 
2709                             pstrcpy(new_path, l + diff + 1, mapping->path);
2710                             pstrcpy(new_path + l1, l + diff + 1 - l1,
2711                                     m->path + l2);
2712 
2713                             schedule_rename(s, m->begin, new_path);
2714                         }
2715                         i++;
2716                     } while((i % (0x10 * s->sectors_per_cluster)) != 0);
2717                     c = fat_get(s, c);
2718                 }
2719             }
2720 
2721             g_free(old_path);
2722             array_remove(&(s->commits), i);
2723             continue;
2724         } else if (commit->action == ACTION_MKDIR) {
2725             mapping_t* mapping;
2726             int j, parent_path_len;
2727 
2728 #ifdef __MINGW32__
2729             if (mkdir(commit->path))
2730                 return -5;
2731 #else
2732             if (mkdir(commit->path, 0755))
2733                 return -5;
2734 #endif
2735 
2736             mapping = insert_mapping(s, commit->param.mkdir.cluster,
2737                     commit->param.mkdir.cluster + 1);
2738             if (mapping == NULL)
2739                 return -6;
2740 
2741             mapping->mode = MODE_DIRECTORY;
2742             mapping->read_only = 0;
2743             mapping->path = commit->path;
2744             j = s->directory.next;
2745             assert(j);
2746             insert_direntries(s, s->directory.next,
2747                     0x10 * s->sectors_per_cluster);
2748             mapping->info.dir.first_dir_index = j;
2749 
2750             parent_path_len = strlen(commit->path)
2751                 - strlen(get_basename(commit->path)) - 1;
2752             for (j = 0; j < s->mapping.next; j++) {
2753                 mapping_t* m = array_get(&(s->mapping), j);
2754                 if (m->first_mapping_index < 0 && m != mapping &&
2755                         !strncmp(m->path, mapping->path, parent_path_len) &&
2756                         strlen(m->path) == parent_path_len)
2757                     break;
2758             }
2759             assert(j < s->mapping.next);
2760             mapping->info.dir.parent_mapping_index = j;
2761 
2762             array_remove(&(s->commits), i);
2763             continue;
2764         }
2765 
2766         i++;
2767     }
2768     return 0;
2769 }
2770 
2771 /*
2772  * TODO: make sure that the short name is not matching *another* file
2773  */
2774 static int handle_commits(BDRVVVFATState* s)
2775 {
2776     int i, fail = 0;
2777 
2778     vvfat_close_current_file(s);
2779 
2780     for (i = 0; !fail && i < s->commits.next; i++) {
2781         commit_t* commit = array_get(&(s->commits), i);
2782         switch(commit->action) {
2783         case ACTION_RENAME: case ACTION_MKDIR:
2784             abort();
2785             fail = -2;
2786             break;
2787         case ACTION_WRITEOUT: {
2788 #ifndef NDEBUG
2789             /* these variables are only used by assert() below */
2790             direntry_t* entry = array_get(&(s->directory),
2791                     commit->param.writeout.dir_index);
2792             uint32_t begin = begin_of_direntry(entry);
2793             mapping_t* mapping = find_mapping_for_cluster(s, begin);
2794 #endif
2795 
2796             assert(mapping);
2797             assert(mapping->begin == begin);
2798             assert(commit->path == NULL);
2799 
2800             if (commit_one_file(s, commit->param.writeout.dir_index,
2801                         commit->param.writeout.modified_offset))
2802                 fail = -3;
2803 
2804             break;
2805         }
2806         case ACTION_NEW_FILE: {
2807             int begin = commit->param.new_file.first_cluster;
2808             mapping_t* mapping = find_mapping_for_cluster(s, begin);
2809             direntry_t* entry;
2810             int i;
2811 
2812             /* find direntry */
2813             for (i = 0; i < s->directory.next; i++) {
2814                 entry = array_get(&(s->directory), i);
2815                 if (is_file(entry) && begin_of_direntry(entry) == begin)
2816                     break;
2817             }
2818 
2819             if (i >= s->directory.next) {
2820                 fail = -6;
2821                 continue;
2822             }
2823 
2824             /* make sure there exists an initial mapping */
2825             if (mapping && mapping->begin != begin) {
2826                 mapping->end = begin;
2827                 mapping = NULL;
2828             }
2829             if (mapping == NULL) {
2830                 mapping = insert_mapping(s, begin, begin+1);
2831             }
2832             /* most members will be fixed in commit_mappings() */
2833             assert(commit->path);
2834             mapping->path = commit->path;
2835             mapping->read_only = 0;
2836             mapping->mode = MODE_NORMAL;
2837             mapping->info.file.offset = 0;
2838 
2839             if (commit_one_file(s, i, 0))
2840                 fail = -7;
2841 
2842             break;
2843         }
2844         default:
2845             abort();
2846         }
2847     }
2848     if (i > 0 && array_remove_slice(&(s->commits), 0, i))
2849         return -1;
2850     return fail;
2851 }
2852 
2853 static int handle_deletes(BDRVVVFATState* s)
2854 {
2855     int i, deferred = 1, deleted = 1;
2856 
2857     /* delete files corresponding to mappings marked as deleted */
2858     /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
2859     while (deferred && deleted) {
2860         deferred = 0;
2861         deleted = 0;
2862 
2863         for (i = 1; i < s->mapping.next; i++) {
2864             mapping_t* mapping = array_get(&(s->mapping), i);
2865             if (mapping->mode & MODE_DELETED) {
2866                 direntry_t* entry = array_get(&(s->directory),
2867                         mapping->dir_index);
2868 
2869                 if (is_free(entry)) {
2870                     /* remove file/directory */
2871                     if (mapping->mode & MODE_DIRECTORY) {
2872                         int j, next_dir_index = s->directory.next,
2873                         first_dir_index = mapping->info.dir.first_dir_index;
2874 
2875                         if (rmdir(mapping->path) < 0) {
2876                             if (errno == ENOTEMPTY) {
2877                                 deferred++;
2878                                 continue;
2879                             } else
2880                                 return -5;
2881                         }
2882 
2883                         for (j = 1; j < s->mapping.next; j++) {
2884                             mapping_t* m = array_get(&(s->mapping), j);
2885                             if (m->mode & MODE_DIRECTORY &&
2886                                     m->info.dir.first_dir_index >
2887                                     first_dir_index &&
2888                                     m->info.dir.first_dir_index <
2889                                     next_dir_index)
2890                                 next_dir_index =
2891                                     m->info.dir.first_dir_index;
2892                         }
2893                         remove_direntries(s, first_dir_index,
2894                                 next_dir_index - first_dir_index);
2895 
2896                         deleted++;
2897                     }
2898                 } else {
2899                     if (unlink(mapping->path))
2900                         return -4;
2901                     deleted++;
2902                 }
2903                 DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
2904                 remove_mapping(s, i);
2905             }
2906         }
2907     }
2908 
2909     return 0;
2910 }
2911 
2912 /*
2913  * synchronize mapping with new state:
2914  *
2915  * - copy FAT (with bdrv_pread)
2916  * - mark all filenames corresponding to mappings as deleted
2917  * - recurse direntries from root (using bs->bdrv_pread)
2918  * - delete files corresponding to mappings marked as deleted
2919  */
2920 static int do_commit(BDRVVVFATState* s)
2921 {
2922     int ret = 0;
2923 
2924     /* the real meat are the commits. Nothing to do? Move along! */
2925     if (s->commits.next == 0)
2926         return 0;
2927 
2928     vvfat_close_current_file(s);
2929 
2930     ret = handle_renames_and_mkdirs(s);
2931     if (ret) {
2932         fprintf(stderr, "Error handling renames (%d)\n", ret);
2933         abort();
2934         return ret;
2935     }
2936 
2937     /* copy FAT (with bdrv_pread) */
2938     memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
2939 
2940     /* recurse direntries from root (using bs->bdrv_pread) */
2941     ret = commit_direntries(s, 0, -1);
2942     if (ret) {
2943         fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
2944         abort();
2945         return ret;
2946     }
2947 
2948     ret = handle_commits(s);
2949     if (ret) {
2950         fprintf(stderr, "Error handling commits (%d)\n", ret);
2951         abort();
2952         return ret;
2953     }
2954 
2955     ret = handle_deletes(s);
2956     if (ret) {
2957         fprintf(stderr, "Error deleting\n");
2958         abort();
2959         return ret;
2960     }
2961 
2962     bdrv_make_empty(s->qcow, NULL);
2963 
2964     memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
2965 
2966 DLOG(checkpoint());
2967     return 0;
2968 }
2969 
2970 static int try_commit(BDRVVVFATState* s)
2971 {
2972     vvfat_close_current_file(s);
2973 DLOG(checkpoint());
2974     if(!is_consistent(s))
2975         return -1;
2976     return do_commit(s);
2977 }
2978 
2979 static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
2980                     const uint8_t *buf, int nb_sectors)
2981 {
2982     BDRVVVFATState *s = bs->opaque;
2983     int i, ret;
2984     int first_cluster, last_cluster;
2985 
2986 DLOG(checkpoint());
2987 
2988     /* Check if we're operating in read-only mode */
2989     if (s->qcow == NULL) {
2990         return -EACCES;
2991     }
2992 
2993     vvfat_close_current_file(s);
2994 
2995     /*
2996      * Some sanity checks:
2997      * - do not allow writing to the boot sector
2998      */
2999 
3000     if (sector_num < s->offset_to_fat)
3001         return -1;
3002 
3003     /*
3004      * Values will be negative for writes to the FAT, which is located before
3005      * the root directory.
3006      */
3007     first_cluster = sector2cluster(s, sector_num);
3008     last_cluster = sector2cluster(s, sector_num + nb_sectors - 1);
3009 
3010     for (i = first_cluster; i <= last_cluster;) {
3011         mapping_t *mapping = NULL;
3012 
3013         if (i >= 0) {
3014             mapping = find_mapping_for_cluster(s, i);
3015         }
3016 
3017         if (mapping) {
3018             if (mapping->read_only) {
3019                 fprintf(stderr, "Tried to write to write-protected file %s\n",
3020                         mapping->path);
3021                 return -1;
3022             }
3023 
3024             if (mapping->mode & MODE_DIRECTORY) {
3025                 int begin = cluster2sector(s, i);
3026                 int end = begin + s->sectors_per_cluster, k;
3027                 int dir_index;
3028                 const direntry_t* direntries;
3029                 long_file_name lfn;
3030 
3031                 lfn_init(&lfn);
3032 
3033                 if (begin < sector_num)
3034                     begin = sector_num;
3035                 if (end > sector_num + nb_sectors)
3036                     end = sector_num + nb_sectors;
3037                 dir_index  = mapping->dir_index +
3038                     0x10 * (begin - mapping->begin * s->sectors_per_cluster);
3039                 direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
3040 
3041                 for (k = 0; k < (end - begin) * 0x10; k++) {
3042                     /* no access to the direntry of a read-only file */
3043                     if (is_short_name(direntries + k) &&
3044                             (direntries[k].attributes & 1)) {
3045                         if (memcmp(direntries + k,
3046                                     array_get(&(s->directory), dir_index + k),
3047                                     sizeof(direntry_t))) {
3048                             warn_report("tried to write to write-protected "
3049                                         "file");
3050                             return -1;
3051                         }
3052                     }
3053                 }
3054             }
3055             i = mapping->end;
3056         } else {
3057             i++;
3058         }
3059     }
3060 
3061     /*
3062      * Use qcow backend. Commit later.
3063      */
3064 DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
3065     ret = bdrv_pwrite(s->qcow, sector_num * BDRV_SECTOR_SIZE, buf,
3066                       nb_sectors * BDRV_SECTOR_SIZE);
3067     if (ret < 0) {
3068         fprintf(stderr, "Error writing to qcow backend\n");
3069         return ret;
3070     }
3071 
3072     for (i = first_cluster; i <= last_cluster; i++) {
3073         if (i >= 0) {
3074             s->used_clusters[i] |= USED_ALLOCATED;
3075         }
3076     }
3077 
3078 DLOG(checkpoint());
3079     /* TODO: add timeout */
3080     try_commit(s);
3081 
3082 DLOG(checkpoint());
3083     return 0;
3084 }
3085 
3086 static int coroutine_fn
3087 vvfat_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
3088                  QEMUIOVector *qiov, BdrvRequestFlags flags)
3089 {
3090     int ret;
3091     BDRVVVFATState *s = bs->opaque;
3092     uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
3093     int nb_sectors = bytes >> BDRV_SECTOR_BITS;
3094     void *buf;
3095 
3096     assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
3097     assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
3098 
3099     buf = g_try_malloc(bytes);
3100     if (bytes && buf == NULL) {
3101         return -ENOMEM;
3102     }
3103     qemu_iovec_to_buf(qiov, 0, buf, bytes);
3104 
3105     qemu_co_mutex_lock(&s->lock);
3106     ret = vvfat_write(bs, sector_num, buf, nb_sectors);
3107     qemu_co_mutex_unlock(&s->lock);
3108 
3109     g_free(buf);
3110 
3111     return ret;
3112 }
3113 
3114 static int coroutine_fn vvfat_co_block_status(BlockDriverState *bs,
3115                                               bool want_zero, int64_t offset,
3116                                               int64_t bytes, int64_t *n,
3117                                               int64_t *map,
3118                                               BlockDriverState **file)
3119 {
3120     *n = bytes;
3121     return BDRV_BLOCK_DATA;
3122 }
3123 
3124 static void vvfat_qcow_options(BdrvChildRole role, bool parent_is_format,
3125                                int *child_flags, QDict *child_options,
3126                                int parent_flags, QDict *parent_options)
3127 {
3128     qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
3129     qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
3130     qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
3131 }
3132 
3133 static BdrvChildClass child_vvfat_qcow;
3134 
3135 static int enable_write_target(BlockDriverState *bs, Error **errp)
3136 {
3137     BDRVVVFATState *s = bs->opaque;
3138     BlockDriver *bdrv_qcow = NULL;
3139     QemuOpts *opts = NULL;
3140     int ret;
3141     int size = sector2cluster(s, s->sector_count);
3142     QDict *options;
3143 
3144     s->used_clusters = g_malloc0(size);
3145 
3146     array_init(&(s->commits), sizeof(commit_t));
3147 
3148     s->qcow_filename = g_malloc(PATH_MAX);
3149     ret = get_tmp_filename(s->qcow_filename, PATH_MAX);
3150     if (ret < 0) {
3151         error_setg_errno(errp, -ret, "can't create temporary file");
3152         goto err;
3153     }
3154 
3155     bdrv_qcow = bdrv_find_format("qcow");
3156     if (!bdrv_qcow) {
3157         error_setg(errp, "Failed to locate qcow driver");
3158         ret = -ENOENT;
3159         goto err;
3160     }
3161 
3162     opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
3163     qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
3164                         bs->total_sectors * BDRV_SECTOR_SIZE, &error_abort);
3165     qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:", &error_abort);
3166 
3167     ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts, errp);
3168     qemu_opts_del(opts);
3169     if (ret < 0) {
3170         goto err;
3171     }
3172 
3173     options = qdict_new();
3174     qdict_put_str(options, "write-target.driver", "qcow");
3175     s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs,
3176                               &child_vvfat_qcow,
3177                               BDRV_CHILD_DATA | BDRV_CHILD_METADATA,
3178                               false, errp);
3179     qobject_unref(options);
3180     if (!s->qcow) {
3181         ret = -EINVAL;
3182         goto err;
3183     }
3184 
3185 #ifndef _WIN32
3186     unlink(s->qcow_filename);
3187 #endif
3188 
3189     return 0;
3190 
3191 err:
3192     return ret;
3193 }
3194 
3195 static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
3196                              BdrvChildRole role,
3197                              BlockReopenQueue *reopen_queue,
3198                              uint64_t perm, uint64_t shared,
3199                              uint64_t *nperm, uint64_t *nshared)
3200 {
3201     assert(role & BDRV_CHILD_DATA);
3202     /* This is a private node, nobody should try to attach to it */
3203     *nperm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE;
3204     *nshared = BLK_PERM_WRITE_UNCHANGED;
3205 }
3206 
3207 static void vvfat_close(BlockDriverState *bs)
3208 {
3209     BDRVVVFATState *s = bs->opaque;
3210 
3211     vvfat_close_current_file(s);
3212     array_free(&(s->fat));
3213     array_free(&(s->directory));
3214     array_free(&(s->mapping));
3215     g_free(s->cluster_buffer);
3216 
3217     if (s->qcow) {
3218         migrate_del_blocker(s->migration_blocker);
3219         error_free(s->migration_blocker);
3220     }
3221 }
3222 
3223 static const char *const vvfat_strong_runtime_opts[] = {
3224     "dir",
3225     "fat-type",
3226     "floppy",
3227     "label",
3228     "rw",
3229 
3230     NULL
3231 };
3232 
3233 static BlockDriver bdrv_vvfat = {
3234     .format_name            = "vvfat",
3235     .protocol_name          = "fat",
3236     .instance_size          = sizeof(BDRVVVFATState),
3237 
3238     .bdrv_parse_filename    = vvfat_parse_filename,
3239     .bdrv_file_open         = vvfat_open,
3240     .bdrv_refresh_limits    = vvfat_refresh_limits,
3241     .bdrv_close             = vvfat_close,
3242     .bdrv_child_perm        = vvfat_child_perm,
3243 
3244     .bdrv_co_preadv         = vvfat_co_preadv,
3245     .bdrv_co_pwritev        = vvfat_co_pwritev,
3246     .bdrv_co_block_status   = vvfat_co_block_status,
3247 
3248     .strong_runtime_opts    = vvfat_strong_runtime_opts,
3249 };
3250 
3251 static void bdrv_vvfat_init(void)
3252 {
3253     child_vvfat_qcow = child_of_bds;
3254     child_vvfat_qcow.inherit_options = vvfat_qcow_options;
3255     bdrv_register(&bdrv_vvfat);
3256 }
3257 
3258 block_init(bdrv_vvfat_init);
3259 
3260 #ifdef DEBUG
3261 static void checkpoint(void)
3262 {
3263     assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
3264     check1(vvv);
3265     check2(vvv);
3266     assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
3267 }
3268 #endif
3269