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