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