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