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