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