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