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