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