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