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