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