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