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