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