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