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