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