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