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