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