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