xref: /openbmc/qemu/block/vvfat.c (revision 1fd6bb44)
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,
992                       QDict *options, int flags)
993 {
994     BDRVVVFATState *s = bs->opaque;
995     int i, cyls, heads, secs;
996 
997 #ifdef DEBUG
998     vvv = s;
999 #endif
1000 
1001 DLOG(if (stderr == NULL) {
1002     stderr = fopen("vvfat.log", "a");
1003     setbuf(stderr, NULL);
1004 })
1005 
1006     s->bs = bs;
1007 
1008     /* LATER TODO: if FAT32, adjust */
1009     s->sectors_per_cluster=0x10;
1010 
1011     s->current_cluster=0xffffffff;
1012 
1013     s->first_sectors_number=0x40;
1014     /* read only is the default for safety */
1015     bs->read_only = 1;
1016     s->qcow = s->write_target = NULL;
1017     s->qcow_filename = NULL;
1018     s->fat2 = NULL;
1019     s->downcase_short_names = 1;
1020 
1021     if (!strstart(dirname, "fat:", NULL))
1022 	return -1;
1023 
1024     if (strstr(dirname, ":32:")) {
1025 	fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");
1026 	s->fat_type = 32;
1027     } else if (strstr(dirname, ":16:")) {
1028 	s->fat_type = 16;
1029     } else if (strstr(dirname, ":12:")) {
1030 	s->fat_type = 12;
1031     }
1032 
1033     if (strstr(dirname, ":floppy:")) {
1034 	/* 1.44MB or 2.88MB floppy.  2.88MB can be FAT12 (default) or FAT16. */
1035 	if (!s->fat_type) {
1036 	    s->fat_type = 12;
1037             secs = 36;
1038 	    s->sectors_per_cluster=2;
1039 	} else {
1040             secs = s->fat_type == 12 ? 18 : 36;
1041 	    s->sectors_per_cluster=1;
1042 	}
1043 	s->first_sectors_number = 1;
1044         cyls = 80;
1045         heads = 2;
1046     } else {
1047 	/* 32MB or 504MB disk*/
1048 	if (!s->fat_type) {
1049 	    s->fat_type = 16;
1050 	}
1051         cyls = s->fat_type == 12 ? 64 : 1024;
1052         heads = 16;
1053         secs = 63;
1054     }
1055     fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
1056             dirname, cyls, heads, secs);
1057 
1058     s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);
1059 
1060     if (strstr(dirname, ":rw:")) {
1061 	if (enable_write_target(s))
1062 	    return -1;
1063 	bs->read_only = 0;
1064     }
1065 
1066     i = strrchr(dirname, ':') - dirname;
1067     assert(i >= 3);
1068     if (dirname[i-2] == ':' && qemu_isalpha(dirname[i-1]))
1069 	/* workaround for DOS drive names */
1070 	dirname += i-1;
1071     else
1072 	dirname += i+1;
1073 
1074     bs->total_sectors = cyls * heads * secs;
1075 
1076     if (init_directories(s, dirname, heads, secs)) {
1077 	return -1;
1078     }
1079 
1080     s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;
1081 
1082     if (s->first_sectors_number == 0x40) {
1083         init_mbr(s, cyls, heads, secs);
1084     }
1085 
1086     //    assert(is_consistent(s));
1087     qemu_co_mutex_init(&s->lock);
1088 
1089     /* Disable migration when vvfat is used rw */
1090     if (s->qcow) {
1091         error_set(&s->migration_blocker,
1092                   QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
1093                   "vvfat (rw)", bs->device_name, "live migration");
1094         migrate_add_blocker(s->migration_blocker);
1095     }
1096 
1097     return 0;
1098 }
1099 
1100 static inline void vvfat_close_current_file(BDRVVVFATState *s)
1101 {
1102     if(s->current_mapping) {
1103 	s->current_mapping = NULL;
1104 	if (s->current_fd) {
1105 		qemu_close(s->current_fd);
1106 		s->current_fd = 0;
1107 	}
1108     }
1109     s->current_cluster = -1;
1110 }
1111 
1112 /* mappings between index1 and index2-1 are supposed to be ordered
1113  * return value is the index of the last mapping for which end>cluster_num
1114  */
1115 static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
1116 {
1117     while(1) {
1118         int index3;
1119 	mapping_t* mapping;
1120 	index3=(index1+index2)/2;
1121 	mapping=array_get(&(s->mapping),index3);
1122 	assert(mapping->begin < mapping->end);
1123 	if(mapping->begin>=cluster_num) {
1124 	    assert(index2!=index3 || index2==0);
1125 	    if(index2==index3)
1126 		return index1;
1127 	    index2=index3;
1128 	} else {
1129 	    if(index1==index3)
1130 		return mapping->end<=cluster_num ? index2 : index1;
1131 	    index1=index3;
1132 	}
1133 	assert(index1<=index2);
1134 	DLOG(mapping=array_get(&(s->mapping),index1);
1135 	assert(mapping->begin<=cluster_num);
1136 	assert(index2 >= s->mapping.next ||
1137 		((mapping = array_get(&(s->mapping),index2)) &&
1138 		mapping->end>cluster_num)));
1139     }
1140 }
1141 
1142 static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
1143 {
1144     int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
1145     mapping_t* mapping;
1146     if(index>=s->mapping.next)
1147         return NULL;
1148     mapping=array_get(&(s->mapping),index);
1149     if(mapping->begin>cluster_num)
1150         return NULL;
1151     assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
1152     return mapping;
1153 }
1154 
1155 static int open_file(BDRVVVFATState* s,mapping_t* mapping)
1156 {
1157     if(!mapping)
1158 	return -1;
1159     if(!s->current_mapping ||
1160 	    strcmp(s->current_mapping->path,mapping->path)) {
1161 	/* open file */
1162 	int fd = qemu_open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
1163 	if(fd<0)
1164 	    return -1;
1165 	vvfat_close_current_file(s);
1166 	s->current_fd = fd;
1167 	s->current_mapping = mapping;
1168     }
1169     return 0;
1170 }
1171 
1172 static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
1173 {
1174     if(s->current_cluster != cluster_num) {
1175 	int result=0;
1176 	off_t offset;
1177 	assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
1178 	if(!s->current_mapping
1179 		|| s->current_mapping->begin>cluster_num
1180 		|| s->current_mapping->end<=cluster_num) {
1181 	    /* binary search of mappings for file */
1182 	    mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
1183 
1184 	    assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
1185 
1186 	    if (mapping && mapping->mode & MODE_DIRECTORY) {
1187 		vvfat_close_current_file(s);
1188 		s->current_mapping = mapping;
1189 read_cluster_directory:
1190 		offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
1191 		s->cluster = (unsigned char*)s->directory.pointer+offset
1192 			+ 0x20*s->current_mapping->info.dir.first_dir_index;
1193 		assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
1194 		assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
1195 		s->current_cluster = cluster_num;
1196 		return 0;
1197 	    }
1198 
1199 	    if(open_file(s,mapping))
1200 		return -2;
1201 	} else if (s->current_mapping->mode & MODE_DIRECTORY)
1202 	    goto read_cluster_directory;
1203 
1204 	assert(s->current_fd);
1205 
1206 	offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
1207 	if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
1208 	    return -3;
1209 	s->cluster=s->cluster_buffer;
1210 	result=read(s->current_fd,s->cluster,s->cluster_size);
1211 	if(result<0) {
1212 	    s->current_cluster = -1;
1213 	    return -1;
1214 	}
1215 	s->current_cluster = cluster_num;
1216     }
1217     return 0;
1218 }
1219 
1220 #ifdef DEBUG
1221 static void print_direntry(const direntry_t* direntry)
1222 {
1223     int j = 0;
1224     char buffer[1024];
1225 
1226     fprintf(stderr, "direntry %p: ", direntry);
1227     if(!direntry)
1228 	return;
1229     if(is_long_name(direntry)) {
1230 	unsigned char* c=(unsigned char*)direntry;
1231 	int i;
1232 	for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
1233 #define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
1234 	    ADD_CHAR(c[i]);
1235 	for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
1236 	    ADD_CHAR(c[i]);
1237 	for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
1238 	    ADD_CHAR(c[i]);
1239 	buffer[j] = 0;
1240 	fprintf(stderr, "%s\n", buffer);
1241     } else {
1242 	int i;
1243 	for(i=0;i<11;i++)
1244 	    ADD_CHAR(direntry->name[i]);
1245 	buffer[j] = 0;
1246 	fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
1247 		buffer,
1248 		direntry->attributes,
1249 		begin_of_direntry(direntry),le32_to_cpu(direntry->size));
1250     }
1251 }
1252 
1253 static void print_mapping(const mapping_t* mapping)
1254 {
1255     fprintf(stderr, "mapping (%p): begin, end = %d, %d, dir_index = %d, "
1256         "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
1257         mapping, mapping->begin, mapping->end, mapping->dir_index,
1258         mapping->first_mapping_index, mapping->path, mapping->mode);
1259 
1260     if (mapping->mode & MODE_DIRECTORY)
1261 	fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
1262     else
1263 	fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
1264 }
1265 #endif
1266 
1267 static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
1268                     uint8_t *buf, int nb_sectors)
1269 {
1270     BDRVVVFATState *s = bs->opaque;
1271     int i;
1272 
1273     for(i=0;i<nb_sectors;i++,sector_num++) {
1274 	if (sector_num >= bs->total_sectors)
1275 	   return -1;
1276 	if (s->qcow) {
1277 	    int n;
1278             if (bdrv_is_allocated(s->qcow, sector_num, nb_sectors-i, &n)) {
1279 DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n));
1280                 if (bdrv_read(s->qcow, sector_num, buf + i*0x200, n)) {
1281                     return -1;
1282                 }
1283                 i += n - 1;
1284                 sector_num += n - 1;
1285                 continue;
1286             }
1287 DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
1288 	}
1289 	if(sector_num<s->faked_sectors) {
1290 	    if(sector_num<s->first_sectors_number)
1291 		memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
1292 	    else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
1293 		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
1294 	    else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
1295 		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
1296 	} else {
1297 	    uint32_t sector=sector_num-s->faked_sectors,
1298 	    sector_offset_in_cluster=(sector%s->sectors_per_cluster),
1299 	    cluster_num=sector/s->sectors_per_cluster;
1300 	    if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
1301 		/* LATER TODO: strict: return -1; */
1302 		memset(buf+i*0x200,0,0x200);
1303 		continue;
1304 	    }
1305 	    memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
1306 	}
1307     }
1308     return 0;
1309 }
1310 
1311 static coroutine_fn int vvfat_co_read(BlockDriverState *bs, int64_t sector_num,
1312                                       uint8_t *buf, int nb_sectors)
1313 {
1314     int ret;
1315     BDRVVVFATState *s = bs->opaque;
1316     qemu_co_mutex_lock(&s->lock);
1317     ret = vvfat_read(bs, sector_num, buf, nb_sectors);
1318     qemu_co_mutex_unlock(&s->lock);
1319     return ret;
1320 }
1321 
1322 /* LATER TODO: statify all functions */
1323 
1324 /*
1325  * Idea of the write support (use snapshot):
1326  *
1327  * 1. check if all data is consistent, recording renames, modifications,
1328  *    new files and directories (in s->commits).
1329  *
1330  * 2. if the data is not consistent, stop committing
1331  *
1332  * 3. handle renames, and create new files and directories (do not yet
1333  *    write their contents)
1334  *
1335  * 4. walk the directories, fixing the mapping and direntries, and marking
1336  *    the handled mappings as not deleted
1337  *
1338  * 5. commit the contents of the files
1339  *
1340  * 6. handle deleted files and directories
1341  *
1342  */
1343 
1344 typedef struct commit_t {
1345     char* path;
1346     union {
1347 	struct { uint32_t cluster; } rename;
1348 	struct { int dir_index; uint32_t modified_offset; } writeout;
1349 	struct { uint32_t first_cluster; } new_file;
1350 	struct { uint32_t cluster; } mkdir;
1351     } param;
1352     /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
1353     enum {
1354 	ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
1355     } action;
1356 } commit_t;
1357 
1358 static void clear_commits(BDRVVVFATState* s)
1359 {
1360     int i;
1361 DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
1362     for (i = 0; i < s->commits.next; i++) {
1363 	commit_t* commit = array_get(&(s->commits), i);
1364 	assert(commit->path || commit->action == ACTION_WRITEOUT);
1365 	if (commit->action != ACTION_WRITEOUT) {
1366 	    assert(commit->path);
1367             g_free(commit->path);
1368 	} else
1369 	    assert(commit->path == NULL);
1370     }
1371     s->commits.next = 0;
1372 }
1373 
1374 static void schedule_rename(BDRVVVFATState* s,
1375 	uint32_t cluster, char* new_path)
1376 {
1377     commit_t* commit = array_get_next(&(s->commits));
1378     commit->path = new_path;
1379     commit->param.rename.cluster = cluster;
1380     commit->action = ACTION_RENAME;
1381 }
1382 
1383 static void schedule_writeout(BDRVVVFATState* s,
1384 	int dir_index, uint32_t modified_offset)
1385 {
1386     commit_t* commit = array_get_next(&(s->commits));
1387     commit->path = NULL;
1388     commit->param.writeout.dir_index = dir_index;
1389     commit->param.writeout.modified_offset = modified_offset;
1390     commit->action = ACTION_WRITEOUT;
1391 }
1392 
1393 static void schedule_new_file(BDRVVVFATState* s,
1394 	char* path, uint32_t first_cluster)
1395 {
1396     commit_t* commit = array_get_next(&(s->commits));
1397     commit->path = path;
1398     commit->param.new_file.first_cluster = first_cluster;
1399     commit->action = ACTION_NEW_FILE;
1400 }
1401 
1402 static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
1403 {
1404     commit_t* commit = array_get_next(&(s->commits));
1405     commit->path = path;
1406     commit->param.mkdir.cluster = cluster;
1407     commit->action = ACTION_MKDIR;
1408 }
1409 
1410 typedef struct {
1411     /*
1412      * Since the sequence number is at most 0x3f, and the filename
1413      * length is at most 13 times the sequence number, the maximal
1414      * filename length is 0x3f * 13 bytes.
1415      */
1416     unsigned char name[0x3f * 13 + 1];
1417     int checksum, len;
1418     int sequence_number;
1419 } long_file_name;
1420 
1421 static void lfn_init(long_file_name* lfn)
1422 {
1423    lfn->sequence_number = lfn->len = 0;
1424    lfn->checksum = 0x100;
1425 }
1426 
1427 /* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
1428 static int parse_long_name(long_file_name* lfn,
1429 	const direntry_t* direntry)
1430 {
1431     int i, j, offset;
1432     const unsigned char* pointer = (const unsigned char*)direntry;
1433 
1434     if (!is_long_name(direntry))
1435 	return 1;
1436 
1437     if (pointer[0] & 0x40) {
1438 	lfn->sequence_number = pointer[0] & 0x3f;
1439 	lfn->checksum = pointer[13];
1440 	lfn->name[0] = 0;
1441 	lfn->name[lfn->sequence_number * 13] = 0;
1442     } else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
1443 	return -1;
1444     else if (pointer[13] != lfn->checksum)
1445 	return -2;
1446     else if (pointer[12] || pointer[26] || pointer[27])
1447 	return -3;
1448 
1449     offset = 13 * (lfn->sequence_number - 1);
1450     for (i = 0, j = 1; i < 13; i++, j+=2) {
1451 	if (j == 11)
1452 	    j = 14;
1453 	else if (j == 26)
1454 	    j = 28;
1455 
1456 	if (pointer[j+1] == 0)
1457 	    lfn->name[offset + i] = pointer[j];
1458 	else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
1459 	    return -4;
1460 	else
1461 	    lfn->name[offset + i] = 0;
1462     }
1463 
1464     if (pointer[0] & 0x40)
1465 	lfn->len = offset + strlen((char*)lfn->name + offset);
1466 
1467     return 0;
1468 }
1469 
1470 /* returns 0 if successful, >0 if no short_name, and <0 on error */
1471 static int parse_short_name(BDRVVVFATState* s,
1472 	long_file_name* lfn, direntry_t* direntry)
1473 {
1474     int i, j;
1475 
1476     if (!is_short_name(direntry))
1477 	return 1;
1478 
1479     for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
1480     for (i = 0; i <= j; i++) {
1481 	if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
1482 	    return -1;
1483 	else if (s->downcase_short_names)
1484 	    lfn->name[i] = qemu_tolower(direntry->name[i]);
1485 	else
1486 	    lfn->name[i] = direntry->name[i];
1487     }
1488 
1489     for (j = 2; j >= 0 && direntry->extension[j] == ' '; j--);
1490     if (j >= 0) {
1491 	lfn->name[i++] = '.';
1492 	lfn->name[i + j + 1] = '\0';
1493 	for (;j >= 0; j--) {
1494 	    if (direntry->extension[j] <= ' ' || direntry->extension[j] > 0x7f)
1495 		return -2;
1496 	    else if (s->downcase_short_names)
1497 		lfn->name[i + j] = qemu_tolower(direntry->extension[j]);
1498 	    else
1499 		lfn->name[i + j] = direntry->extension[j];
1500 	}
1501     } else
1502 	lfn->name[i + j + 1] = '\0';
1503 
1504     lfn->len = strlen((char*)lfn->name);
1505 
1506     return 0;
1507 }
1508 
1509 static inline uint32_t modified_fat_get(BDRVVVFATState* s,
1510 	unsigned int cluster)
1511 {
1512     if (cluster < s->last_cluster_of_root_directory) {
1513 	if (cluster + 1 == s->last_cluster_of_root_directory)
1514 	    return s->max_fat_value;
1515 	else
1516 	    return cluster + 1;
1517     }
1518 
1519     if (s->fat_type==32) {
1520         uint32_t* entry=((uint32_t*)s->fat2)+cluster;
1521         return le32_to_cpu(*entry);
1522     } else if (s->fat_type==16) {
1523         uint16_t* entry=((uint16_t*)s->fat2)+cluster;
1524         return le16_to_cpu(*entry);
1525     } else {
1526         const uint8_t* x=s->fat2+cluster*3/2;
1527         return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
1528     }
1529 }
1530 
1531 static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num)
1532 {
1533     int was_modified = 0;
1534     int i, dummy;
1535 
1536     if (s->qcow == NULL)
1537 	return 0;
1538 
1539     for (i = 0; !was_modified && i < s->sectors_per_cluster; i++)
1540 	was_modified = bdrv_is_allocated(s->qcow,
1541 		cluster2sector(s, cluster_num) + i, 1, &dummy);
1542 
1543     return was_modified;
1544 }
1545 
1546 static const char* get_basename(const char* path)
1547 {
1548     char* basename = strrchr(path, '/');
1549     if (basename == NULL)
1550 	return path;
1551     else
1552 	return basename + 1; /* strip '/' */
1553 }
1554 
1555 /*
1556  * The array s->used_clusters holds the states of the clusters. If it is
1557  * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
1558  * was modified, bit 3 is set.
1559  * If any cluster is allocated, but not part of a file or directory, this
1560  * driver refuses to commit.
1561  */
1562 typedef enum {
1563      USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
1564 } used_t;
1565 
1566 /*
1567  * get_cluster_count_for_direntry() not only determines how many clusters
1568  * are occupied by direntry, but also if it was renamed or modified.
1569  *
1570  * A file is thought to be renamed *only* if there already was a file with
1571  * exactly the same first cluster, but a different name.
1572  *
1573  * Further, the files/directories handled by this function are
1574  * assumed to be *not* deleted (and *only* those).
1575  */
1576 static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
1577 	direntry_t* direntry, const char* path)
1578 {
1579     /*
1580      * This is a little bit tricky:
1581      * IF the guest OS just inserts a cluster into the file chain,
1582      * and leaves the rest alone, (i.e. the original file had clusters
1583      * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
1584      *
1585      * - do_commit will write the cluster into the file at the given
1586      *   offset, but
1587      *
1588      * - the cluster which is overwritten should be moved to a later
1589      *   position in the file.
1590      *
1591      * I am not aware that any OS does something as braindead, but this
1592      * situation could happen anyway when not committing for a long time.
1593      * Just to be sure that this does not bite us, detect it, and copy the
1594      * contents of the clusters to-be-overwritten into the qcow.
1595      */
1596     int copy_it = 0;
1597     int was_modified = 0;
1598     int32_t ret = 0;
1599 
1600     uint32_t cluster_num = begin_of_direntry(direntry);
1601     uint32_t offset = 0;
1602     int first_mapping_index = -1;
1603     mapping_t* mapping = NULL;
1604     const char* basename2 = NULL;
1605 
1606     vvfat_close_current_file(s);
1607 
1608     /* the root directory */
1609     if (cluster_num == 0)
1610 	return 0;
1611 
1612     /* write support */
1613     if (s->qcow) {
1614 	basename2 = get_basename(path);
1615 
1616 	mapping = find_mapping_for_cluster(s, cluster_num);
1617 
1618 	if (mapping) {
1619 	    const char* basename;
1620 
1621 	    assert(mapping->mode & MODE_DELETED);
1622 	    mapping->mode &= ~MODE_DELETED;
1623 
1624 	    basename = get_basename(mapping->path);
1625 
1626 	    assert(mapping->mode & MODE_NORMAL);
1627 
1628 	    /* rename */
1629 	    if (strcmp(basename, basename2))
1630 		schedule_rename(s, cluster_num, g_strdup(path));
1631 	} else if (is_file(direntry))
1632 	    /* new file */
1633 	    schedule_new_file(s, g_strdup(path), cluster_num);
1634 	else {
1635             abort();
1636 	    return 0;
1637 	}
1638     }
1639 
1640     while(1) {
1641 	if (s->qcow) {
1642 	    if (!copy_it && cluster_was_modified(s, cluster_num)) {
1643 		if (mapping == NULL ||
1644 			mapping->begin > cluster_num ||
1645 			mapping->end <= cluster_num)
1646 		mapping = find_mapping_for_cluster(s, cluster_num);
1647 
1648 
1649 		if (mapping &&
1650 			(mapping->mode & MODE_DIRECTORY) == 0) {
1651 
1652 		    /* was modified in qcow */
1653 		    if (offset != mapping->info.file.offset + s->cluster_size
1654 			    * (cluster_num - mapping->begin)) {
1655 			/* offset of this cluster in file chain has changed */
1656                         abort();
1657 			copy_it = 1;
1658 		    } else if (offset == 0) {
1659 			const char* basename = get_basename(mapping->path);
1660 
1661 			if (strcmp(basename, basename2))
1662 			    copy_it = 1;
1663 			first_mapping_index = array_index(&(s->mapping), mapping);
1664 		    }
1665 
1666 		    if (mapping->first_mapping_index != first_mapping_index
1667 			    && mapping->info.file.offset > 0) {
1668                         abort();
1669 			copy_it = 1;
1670 		    }
1671 
1672 		    /* need to write out? */
1673 		    if (!was_modified && is_file(direntry)) {
1674 			was_modified = 1;
1675 			schedule_writeout(s, mapping->dir_index, offset);
1676 		    }
1677 		}
1678 	    }
1679 
1680 	    if (copy_it) {
1681 		int i, dummy;
1682 		/*
1683 		 * This is horribly inefficient, but that is okay, since
1684 		 * it is rarely executed, if at all.
1685 		 */
1686 		int64_t offset = cluster2sector(s, cluster_num);
1687 
1688 		vvfat_close_current_file(s);
1689                 for (i = 0; i < s->sectors_per_cluster; i++) {
1690                     if (!bdrv_is_allocated(s->qcow, offset + i, 1, &dummy)) {
1691                         if (vvfat_read(s->bs, offset, s->cluster_buffer, 1)) {
1692                             return -1;
1693                         }
1694                         if (bdrv_write(s->qcow, offset, s->cluster_buffer, 1)) {
1695                             return -2;
1696                         }
1697                     }
1698                 }
1699 	    }
1700 	}
1701 
1702 	ret++;
1703 	if (s->used_clusters[cluster_num] & USED_ANY)
1704 	    return 0;
1705 	s->used_clusters[cluster_num] = USED_FILE;
1706 
1707 	cluster_num = modified_fat_get(s, cluster_num);
1708 
1709 	if (fat_eof(s, cluster_num))
1710 	    return ret;
1711 	else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
1712 	    return -1;
1713 
1714 	offset += s->cluster_size;
1715     }
1716 }
1717 
1718 /*
1719  * This function looks at the modified data (qcow).
1720  * It returns 0 upon inconsistency or error, and the number of clusters
1721  * used by the directory, its subdirectories and their files.
1722  */
1723 static int check_directory_consistency(BDRVVVFATState *s,
1724 	int cluster_num, const char* path)
1725 {
1726     int ret = 0;
1727     unsigned char* cluster = g_malloc(s->cluster_size);
1728     direntry_t* direntries = (direntry_t*)cluster;
1729     mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
1730 
1731     long_file_name lfn;
1732     int path_len = strlen(path);
1733     char path2[PATH_MAX + 1];
1734 
1735     assert(path_len < PATH_MAX); /* len was tested before! */
1736     pstrcpy(path2, sizeof(path2), path);
1737     path2[path_len] = '/';
1738     path2[path_len + 1] = '\0';
1739 
1740     if (mapping) {
1741 	const char* basename = get_basename(mapping->path);
1742 	const char* basename2 = get_basename(path);
1743 
1744 	assert(mapping->mode & MODE_DIRECTORY);
1745 
1746 	assert(mapping->mode & MODE_DELETED);
1747 	mapping->mode &= ~MODE_DELETED;
1748 
1749 	if (strcmp(basename, basename2))
1750 	    schedule_rename(s, cluster_num, g_strdup(path));
1751     } else
1752 	/* new directory */
1753 	schedule_mkdir(s, cluster_num, g_strdup(path));
1754 
1755     lfn_init(&lfn);
1756     do {
1757 	int i;
1758 	int subret = 0;
1759 
1760 	ret++;
1761 
1762 	if (s->used_clusters[cluster_num] & USED_ANY) {
1763 	    fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
1764 	    return 0;
1765 	}
1766 	s->used_clusters[cluster_num] = USED_DIRECTORY;
1767 
1768 DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
1769 	subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
1770 		s->sectors_per_cluster);
1771 	if (subret) {
1772 	    fprintf(stderr, "Error fetching direntries\n");
1773 	fail:
1774             g_free(cluster);
1775 	    return 0;
1776 	}
1777 
1778 	for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
1779 	    int cluster_count = 0;
1780 
1781 DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i));
1782 	    if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
1783 		    is_free(direntries + i))
1784 		continue;
1785 
1786 	    subret = parse_long_name(&lfn, direntries + i);
1787 	    if (subret < 0) {
1788 		fprintf(stderr, "Error in long name\n");
1789 		goto fail;
1790 	    }
1791 	    if (subret == 0 || is_free(direntries + i))
1792 		continue;
1793 
1794 	    if (fat_chksum(direntries+i) != lfn.checksum) {
1795 		subret = parse_short_name(s, &lfn, direntries + i);
1796 		if (subret < 0) {
1797 		    fprintf(stderr, "Error in short name (%d)\n", subret);
1798 		    goto fail;
1799 		}
1800 		if (subret > 0 || !strcmp((char*)lfn.name, ".")
1801 			|| !strcmp((char*)lfn.name, ".."))
1802 		    continue;
1803 	    }
1804 	    lfn.checksum = 0x100; /* cannot use long name twice */
1805 
1806 	    if (path_len + 1 + lfn.len >= PATH_MAX) {
1807 		fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
1808 		goto fail;
1809 	    }
1810             pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
1811                     (char*)lfn.name);
1812 
1813 	    if (is_directory(direntries + i)) {
1814 		if (begin_of_direntry(direntries + i) == 0) {
1815 		    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
1816 		    goto fail;
1817 		}
1818 		cluster_count = check_directory_consistency(s,
1819 			begin_of_direntry(direntries + i), path2);
1820 		if (cluster_count == 0) {
1821 		    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
1822 		    goto fail;
1823 		}
1824 	    } else if (is_file(direntries + i)) {
1825 		/* check file size with FAT */
1826 		cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
1827 		if (cluster_count !=
1828 			(le32_to_cpu(direntries[i].size) + s->cluster_size
1829 			 - 1) / s->cluster_size) {
1830 		    DLOG(fprintf(stderr, "Cluster count mismatch\n"));
1831 		    goto fail;
1832 		}
1833 	    } else
1834                 abort(); /* cluster_count = 0; */
1835 
1836 	    ret += cluster_count;
1837 	}
1838 
1839 	cluster_num = modified_fat_get(s, cluster_num);
1840     } while(!fat_eof(s, cluster_num));
1841 
1842     g_free(cluster);
1843     return ret;
1844 }
1845 
1846 /* returns 1 on success */
1847 static int is_consistent(BDRVVVFATState* s)
1848 {
1849     int i, check;
1850     int used_clusters_count = 0;
1851 
1852 DLOG(checkpoint());
1853     /*
1854      * - get modified FAT
1855      * - compare the two FATs (TODO)
1856      * - get buffer for marking used clusters
1857      * - recurse direntries from root (using bs->bdrv_read to make
1858      *    sure to get the new data)
1859      *   - check that the FAT agrees with the size
1860      *   - count the number of clusters occupied by this directory and
1861      *     its files
1862      * - check that the cumulative used cluster count agrees with the
1863      *   FAT
1864      * - if all is fine, return number of used clusters
1865      */
1866     if (s->fat2 == NULL) {
1867 	int size = 0x200 * s->sectors_per_fat;
1868 	s->fat2 = g_malloc(size);
1869 	memcpy(s->fat2, s->fat.pointer, size);
1870     }
1871     check = vvfat_read(s->bs,
1872 	    s->first_sectors_number, s->fat2, s->sectors_per_fat);
1873     if (check) {
1874 	fprintf(stderr, "Could not copy fat\n");
1875 	return 0;
1876     }
1877     assert (s->used_clusters);
1878     for (i = 0; i < sector2cluster(s, s->sector_count); i++)
1879 	s->used_clusters[i] &= ~USED_ANY;
1880 
1881     clear_commits(s);
1882 
1883     /* mark every mapped file/directory as deleted.
1884      * (check_directory_consistency() will unmark those still present). */
1885     if (s->qcow)
1886 	for (i = 0; i < s->mapping.next; i++) {
1887 	    mapping_t* mapping = array_get(&(s->mapping), i);
1888 	    if (mapping->first_mapping_index < 0)
1889 		mapping->mode |= MODE_DELETED;
1890 	}
1891 
1892     used_clusters_count = check_directory_consistency(s, 0, s->path);
1893     if (used_clusters_count <= 0) {
1894 	DLOG(fprintf(stderr, "problem in directory\n"));
1895 	return 0;
1896     }
1897 
1898     check = s->last_cluster_of_root_directory;
1899     for (i = check; i < sector2cluster(s, s->sector_count); i++) {
1900 	if (modified_fat_get(s, i)) {
1901 	    if(!s->used_clusters[i]) {
1902 		DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
1903 		return 0;
1904 	    }
1905 	    check++;
1906 	}
1907 
1908 	if (s->used_clusters[i] == USED_ALLOCATED) {
1909 	    /* allocated, but not used... */
1910 	    DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
1911 	    return 0;
1912 	}
1913     }
1914 
1915     if (check != used_clusters_count)
1916 	return 0;
1917 
1918     return used_clusters_count;
1919 }
1920 
1921 static inline void adjust_mapping_indices(BDRVVVFATState* s,
1922 	int offset, int adjust)
1923 {
1924     int i;
1925 
1926     for (i = 0; i < s->mapping.next; i++) {
1927 	mapping_t* mapping = array_get(&(s->mapping), i);
1928 
1929 #define ADJUST_MAPPING_INDEX(name) \
1930 	if (mapping->name >= offset) \
1931 	    mapping->name += adjust
1932 
1933 	ADJUST_MAPPING_INDEX(first_mapping_index);
1934 	if (mapping->mode & MODE_DIRECTORY)
1935 	    ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
1936     }
1937 }
1938 
1939 /* insert or update mapping */
1940 static mapping_t* insert_mapping(BDRVVVFATState* s,
1941 	uint32_t begin, uint32_t end)
1942 {
1943     /*
1944      * - find mapping where mapping->begin >= begin,
1945      * - if mapping->begin > begin: insert
1946      *   - adjust all references to mappings!
1947      * - else: adjust
1948      * - replace name
1949      */
1950     int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
1951     mapping_t* mapping = NULL;
1952     mapping_t* first_mapping = array_get(&(s->mapping), 0);
1953 
1954     if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
1955 	    && mapping->begin < begin) {
1956 	mapping->end = begin;
1957 	index++;
1958 	mapping = array_get(&(s->mapping), index);
1959     }
1960     if (index >= s->mapping.next || mapping->begin > begin) {
1961 	mapping = array_insert(&(s->mapping), index, 1);
1962 	mapping->path = NULL;
1963 	adjust_mapping_indices(s, index, +1);
1964     }
1965 
1966     mapping->begin = begin;
1967     mapping->end = end;
1968 
1969 DLOG(mapping_t* next_mapping;
1970 assert(index + 1 >= s->mapping.next ||
1971 ((next_mapping = array_get(&(s->mapping), index + 1)) &&
1972  next_mapping->begin >= end)));
1973 
1974     if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
1975 	s->current_mapping = array_get(&(s->mapping),
1976 		s->current_mapping - first_mapping);
1977 
1978     return mapping;
1979 }
1980 
1981 static int remove_mapping(BDRVVVFATState* s, int mapping_index)
1982 {
1983     mapping_t* mapping = array_get(&(s->mapping), mapping_index);
1984     mapping_t* first_mapping = array_get(&(s->mapping), 0);
1985 
1986     /* free mapping */
1987     if (mapping->first_mapping_index < 0) {
1988         g_free(mapping->path);
1989     }
1990 
1991     /* remove from s->mapping */
1992     array_remove(&(s->mapping), mapping_index);
1993 
1994     /* adjust all references to mappings */
1995     adjust_mapping_indices(s, mapping_index, -1);
1996 
1997     if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
1998 	s->current_mapping = array_get(&(s->mapping),
1999 		s->current_mapping - first_mapping);
2000 
2001     return 0;
2002 }
2003 
2004 static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
2005 {
2006     int i;
2007     for (i = 0; i < s->mapping.next; i++) {
2008 	mapping_t* mapping = array_get(&(s->mapping), i);
2009 	if (mapping->dir_index >= offset)
2010 	    mapping->dir_index += adjust;
2011 	if ((mapping->mode & MODE_DIRECTORY) &&
2012 		mapping->info.dir.first_dir_index >= offset)
2013 	    mapping->info.dir.first_dir_index += adjust;
2014     }
2015 }
2016 
2017 static direntry_t* insert_direntries(BDRVVVFATState* s,
2018 	int dir_index, int count)
2019 {
2020     /*
2021      * make room in s->directory,
2022      * adjust_dirindices
2023      */
2024     direntry_t* result = array_insert(&(s->directory), dir_index, count);
2025     if (result == NULL)
2026 	return NULL;
2027     adjust_dirindices(s, dir_index, count);
2028     return result;
2029 }
2030 
2031 static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
2032 {
2033     int ret = array_remove_slice(&(s->directory), dir_index, count);
2034     if (ret)
2035 	return ret;
2036     adjust_dirindices(s, dir_index, -count);
2037     return 0;
2038 }
2039 
2040 /*
2041  * Adapt the mappings of the cluster chain starting at first cluster
2042  * (i.e. if a file starts at first_cluster, the chain is followed according
2043  * to the modified fat, and the corresponding entries in s->mapping are
2044  * adjusted)
2045  */
2046 static int commit_mappings(BDRVVVFATState* s,
2047 	uint32_t first_cluster, int dir_index)
2048 {
2049     mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
2050     direntry_t* direntry = array_get(&(s->directory), dir_index);
2051     uint32_t cluster = first_cluster;
2052 
2053     vvfat_close_current_file(s);
2054 
2055     assert(mapping);
2056     assert(mapping->begin == first_cluster);
2057     mapping->first_mapping_index = -1;
2058     mapping->dir_index = dir_index;
2059     mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
2060 	MODE_DIRECTORY : MODE_NORMAL;
2061 
2062     while (!fat_eof(s, cluster)) {
2063 	uint32_t c, c1;
2064 
2065 	for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
2066 		c = c1, c1 = modified_fat_get(s, c1));
2067 
2068 	c++;
2069 	if (c > mapping->end) {
2070 	    int index = array_index(&(s->mapping), mapping);
2071 	    int i, max_i = s->mapping.next - index;
2072 	    for (i = 1; i < max_i && mapping[i].begin < c; i++);
2073 	    while (--i > 0)
2074 		remove_mapping(s, index + 1);
2075 	}
2076 	assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
2077 		|| mapping[1].begin >= c);
2078 	mapping->end = c;
2079 
2080 	if (!fat_eof(s, c1)) {
2081 	    int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
2082 	    mapping_t* next_mapping = i >= s->mapping.next ? NULL :
2083 		array_get(&(s->mapping), i);
2084 
2085 	    if (next_mapping == NULL || next_mapping->begin > c1) {
2086 		int i1 = array_index(&(s->mapping), mapping);
2087 
2088 		next_mapping = insert_mapping(s, c1, c1+1);
2089 
2090 		if (c1 < c)
2091 		    i1++;
2092 		mapping = array_get(&(s->mapping), i1);
2093 	    }
2094 
2095 	    next_mapping->dir_index = mapping->dir_index;
2096 	    next_mapping->first_mapping_index =
2097 		mapping->first_mapping_index < 0 ?
2098 		array_index(&(s->mapping), mapping) :
2099 		mapping->first_mapping_index;
2100 	    next_mapping->path = mapping->path;
2101 	    next_mapping->mode = mapping->mode;
2102 	    next_mapping->read_only = mapping->read_only;
2103 	    if (mapping->mode & MODE_DIRECTORY) {
2104 		next_mapping->info.dir.parent_mapping_index =
2105 			mapping->info.dir.parent_mapping_index;
2106 		next_mapping->info.dir.first_dir_index =
2107 			mapping->info.dir.first_dir_index +
2108 			0x10 * s->sectors_per_cluster *
2109 			(mapping->end - mapping->begin);
2110 	    } else
2111 		next_mapping->info.file.offset = mapping->info.file.offset +
2112 			mapping->end - mapping->begin;
2113 
2114 	    mapping = next_mapping;
2115 	}
2116 
2117 	cluster = c1;
2118     }
2119 
2120     return 0;
2121 }
2122 
2123 static int commit_direntries(BDRVVVFATState* s,
2124 	int dir_index, int parent_mapping_index)
2125 {
2126     direntry_t* direntry = array_get(&(s->directory), dir_index);
2127     uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
2128     mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
2129 
2130     int factor = 0x10 * s->sectors_per_cluster;
2131     int old_cluster_count, new_cluster_count;
2132     int current_dir_index = mapping->info.dir.first_dir_index;
2133     int first_dir_index = current_dir_index;
2134     int ret, i;
2135     uint32_t c;
2136 
2137 DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapping->path, parent_mapping_index));
2138 
2139     assert(direntry);
2140     assert(mapping);
2141     assert(mapping->begin == first_cluster);
2142     assert(mapping->info.dir.first_dir_index < s->directory.next);
2143     assert(mapping->mode & MODE_DIRECTORY);
2144     assert(dir_index == 0 || is_directory(direntry));
2145 
2146     mapping->info.dir.parent_mapping_index = parent_mapping_index;
2147 
2148     if (first_cluster == 0) {
2149 	old_cluster_count = new_cluster_count =
2150 	    s->last_cluster_of_root_directory;
2151     } else {
2152 	for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2153 		c = fat_get(s, c))
2154 	    old_cluster_count++;
2155 
2156 	for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2157 		c = modified_fat_get(s, c))
2158 	    new_cluster_count++;
2159     }
2160 
2161     if (new_cluster_count > old_cluster_count) {
2162 	if (insert_direntries(s,
2163 		current_dir_index + factor * old_cluster_count,
2164 		factor * (new_cluster_count - old_cluster_count)) == NULL)
2165 	    return -1;
2166     } else if (new_cluster_count < old_cluster_count)
2167 	remove_direntries(s,
2168 		current_dir_index + factor * new_cluster_count,
2169 		factor * (old_cluster_count - new_cluster_count));
2170 
2171     for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
2172 	void* direntry = array_get(&(s->directory), current_dir_index);
2173 	int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
2174 		s->sectors_per_cluster);
2175 	if (ret)
2176 	    return ret;
2177 	assert(!strncmp(s->directory.pointer, "QEMU", 4));
2178 	current_dir_index += factor;
2179     }
2180 
2181     ret = commit_mappings(s, first_cluster, dir_index);
2182     if (ret)
2183 	return ret;
2184 
2185     /* recurse */
2186     for (i = 0; i < factor * new_cluster_count; i++) {
2187 	direntry = array_get(&(s->directory), first_dir_index + i);
2188 	if (is_directory(direntry) && !is_dot(direntry)) {
2189 	    mapping = find_mapping_for_cluster(s, first_cluster);
2190 	    assert(mapping->mode & MODE_DIRECTORY);
2191 	    ret = commit_direntries(s, first_dir_index + i,
2192 		array_index(&(s->mapping), mapping));
2193 	    if (ret)
2194 		return ret;
2195 	}
2196     }
2197 
2198     return 0;
2199 }
2200 
2201 /* commit one file (adjust contents, adjust mapping),
2202    return first_mapping_index */
2203 static int commit_one_file(BDRVVVFATState* s,
2204 	int dir_index, uint32_t offset)
2205 {
2206     direntry_t* direntry = array_get(&(s->directory), dir_index);
2207     uint32_t c = begin_of_direntry(direntry);
2208     uint32_t first_cluster = c;
2209     mapping_t* mapping = find_mapping_for_cluster(s, c);
2210     uint32_t size = filesize_of_direntry(direntry);
2211     char* cluster = g_malloc(s->cluster_size);
2212     uint32_t i;
2213     int fd = 0;
2214 
2215     assert(offset < size);
2216     assert((offset % s->cluster_size) == 0);
2217 
2218     for (i = s->cluster_size; i < offset; i += s->cluster_size)
2219 	c = modified_fat_get(s, c);
2220 
2221     fd = qemu_open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
2222     if (fd < 0) {
2223 	fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
2224 		strerror(errno), errno);
2225         g_free(cluster);
2226 	return fd;
2227     }
2228     if (offset > 0) {
2229         if (lseek(fd, offset, SEEK_SET) != offset) {
2230             qemu_close(fd);
2231             g_free(cluster);
2232             return -3;
2233         }
2234     }
2235 
2236     while (offset < size) {
2237 	uint32_t c1;
2238 	int rest_size = (size - offset > s->cluster_size ?
2239 		s->cluster_size : size - offset);
2240 	int ret;
2241 
2242 	c1 = modified_fat_get(s, c);
2243 
2244 	assert((size - offset == 0 && fat_eof(s, c)) ||
2245 		(size > offset && c >=2 && !fat_eof(s, c)));
2246 
2247 	ret = vvfat_read(s->bs, cluster2sector(s, c),
2248 	    (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
2249 
2250         if (ret < 0) {
2251             qemu_close(fd);
2252             g_free(cluster);
2253             return ret;
2254         }
2255 
2256         if (write(fd, cluster, rest_size) < 0) {
2257             qemu_close(fd);
2258             g_free(cluster);
2259             return -2;
2260         }
2261 
2262 	offset += rest_size;
2263 	c = c1;
2264     }
2265 
2266     if (ftruncate(fd, size)) {
2267         perror("ftruncate()");
2268         qemu_close(fd);
2269         g_free(cluster);
2270         return -4;
2271     }
2272     qemu_close(fd);
2273     g_free(cluster);
2274 
2275     return commit_mappings(s, first_cluster, dir_index);
2276 }
2277 
2278 #ifdef DEBUG
2279 /* test, if all mappings point to valid direntries */
2280 static void check1(BDRVVVFATState* s)
2281 {
2282     int i;
2283     for (i = 0; i < s->mapping.next; i++) {
2284 	mapping_t* mapping = array_get(&(s->mapping), i);
2285 	if (mapping->mode & MODE_DELETED) {
2286 	    fprintf(stderr, "deleted\n");
2287 	    continue;
2288 	}
2289 	assert(mapping->dir_index < s->directory.next);
2290 	direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
2291 	assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
2292 	if (mapping->mode & MODE_DIRECTORY) {
2293 	    assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
2294 	    assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
2295 	}
2296     }
2297 }
2298 
2299 /* test, if all direntries have mappings */
2300 static void check2(BDRVVVFATState* s)
2301 {
2302     int i;
2303     int first_mapping = -1;
2304 
2305     for (i = 0; i < s->directory.next; i++) {
2306 	direntry_t* direntry = array_get(&(s->directory), i);
2307 
2308 	if (is_short_name(direntry) && begin_of_direntry(direntry)) {
2309 	    mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
2310 	    assert(mapping);
2311 	    assert(mapping->dir_index == i || is_dot(direntry));
2312 	    assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
2313 	}
2314 
2315 	if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
2316 	    /* cluster start */
2317 	    int j, count = 0;
2318 
2319 	    for (j = 0; j < s->mapping.next; j++) {
2320 		mapping_t* mapping = array_get(&(s->mapping), j);
2321 		if (mapping->mode & MODE_DELETED)
2322 		    continue;
2323 		if (mapping->mode & MODE_DIRECTORY) {
2324 		    if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
2325 			assert(++count == 1);
2326 			if (mapping->first_mapping_index == -1)
2327 			    first_mapping = array_index(&(s->mapping), mapping);
2328 			else
2329 			    assert(first_mapping == mapping->first_mapping_index);
2330 			if (mapping->info.dir.parent_mapping_index < 0)
2331 			    assert(j == 0);
2332 			else {
2333 			    mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
2334 			    assert(parent->mode & MODE_DIRECTORY);
2335 			    assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
2336 			}
2337 		    }
2338 		}
2339 	    }
2340 	    if (count == 0)
2341 		first_mapping = -1;
2342 	}
2343     }
2344 }
2345 #endif
2346 
2347 static int handle_renames_and_mkdirs(BDRVVVFATState* s)
2348 {
2349     int i;
2350 
2351 #ifdef DEBUG
2352     fprintf(stderr, "handle_renames\n");
2353     for (i = 0; i < s->commits.next; i++) {
2354 	commit_t* commit = array_get(&(s->commits), i);
2355 	fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
2356     }
2357 #endif
2358 
2359     for (i = 0; i < s->commits.next;) {
2360 	commit_t* commit = array_get(&(s->commits), i);
2361 	if (commit->action == ACTION_RENAME) {
2362 	    mapping_t* mapping = find_mapping_for_cluster(s,
2363 		    commit->param.rename.cluster);
2364 	    char* old_path = mapping->path;
2365 
2366 	    assert(commit->path);
2367 	    mapping->path = commit->path;
2368 	    if (rename(old_path, mapping->path))
2369 		return -2;
2370 
2371 	    if (mapping->mode & MODE_DIRECTORY) {
2372 		int l1 = strlen(mapping->path);
2373 		int l2 = strlen(old_path);
2374 		int diff = l1 - l2;
2375 		direntry_t* direntry = array_get(&(s->directory),
2376 			mapping->info.dir.first_dir_index);
2377 		uint32_t c = mapping->begin;
2378 		int i = 0;
2379 
2380 		/* recurse */
2381 		while (!fat_eof(s, c)) {
2382 		    do {
2383 			direntry_t* d = direntry + i;
2384 
2385 			if (is_file(d) || (is_directory(d) && !is_dot(d))) {
2386 			    mapping_t* m = find_mapping_for_cluster(s,
2387 				    begin_of_direntry(d));
2388 			    int l = strlen(m->path);
2389 			    char* new_path = g_malloc(l + diff + 1);
2390 
2391 			    assert(!strncmp(m->path, mapping->path, l2));
2392 
2393                             pstrcpy(new_path, l + diff + 1, mapping->path);
2394                             pstrcpy(new_path + l1, l + diff + 1 - l1,
2395                                     m->path + l2);
2396 
2397 			    schedule_rename(s, m->begin, new_path);
2398 			}
2399 			i++;
2400 		    } while((i % (0x10 * s->sectors_per_cluster)) != 0);
2401 		    c = fat_get(s, c);
2402 		}
2403 	    }
2404 
2405             g_free(old_path);
2406 	    array_remove(&(s->commits), i);
2407 	    continue;
2408 	} else if (commit->action == ACTION_MKDIR) {
2409 	    mapping_t* mapping;
2410 	    int j, parent_path_len;
2411 
2412 #ifdef __MINGW32__
2413             if (mkdir(commit->path))
2414                 return -5;
2415 #else
2416             if (mkdir(commit->path, 0755))
2417                 return -5;
2418 #endif
2419 
2420 	    mapping = insert_mapping(s, commit->param.mkdir.cluster,
2421 		    commit->param.mkdir.cluster + 1);
2422 	    if (mapping == NULL)
2423 		return -6;
2424 
2425 	    mapping->mode = MODE_DIRECTORY;
2426 	    mapping->read_only = 0;
2427 	    mapping->path = commit->path;
2428 	    j = s->directory.next;
2429 	    assert(j);
2430 	    insert_direntries(s, s->directory.next,
2431 		    0x10 * s->sectors_per_cluster);
2432 	    mapping->info.dir.first_dir_index = j;
2433 
2434 	    parent_path_len = strlen(commit->path)
2435 		- strlen(get_basename(commit->path)) - 1;
2436 	    for (j = 0; j < s->mapping.next; j++) {
2437 		mapping_t* m = array_get(&(s->mapping), j);
2438 		if (m->first_mapping_index < 0 && m != mapping &&
2439 			!strncmp(m->path, mapping->path, parent_path_len) &&
2440 			strlen(m->path) == parent_path_len)
2441 		    break;
2442 	    }
2443 	    assert(j < s->mapping.next);
2444 	    mapping->info.dir.parent_mapping_index = j;
2445 
2446 	    array_remove(&(s->commits), i);
2447 	    continue;
2448 	}
2449 
2450 	i++;
2451     }
2452     return 0;
2453 }
2454 
2455 /*
2456  * TODO: make sure that the short name is not matching *another* file
2457  */
2458 static int handle_commits(BDRVVVFATState* s)
2459 {
2460     int i, fail = 0;
2461 
2462     vvfat_close_current_file(s);
2463 
2464     for (i = 0; !fail && i < s->commits.next; i++) {
2465 	commit_t* commit = array_get(&(s->commits), i);
2466 	switch(commit->action) {
2467 	case ACTION_RENAME: case ACTION_MKDIR:
2468             abort();
2469 	    fail = -2;
2470 	    break;
2471 	case ACTION_WRITEOUT: {
2472 #ifndef NDEBUG
2473             /* these variables are only used by assert() below */
2474 	    direntry_t* entry = array_get(&(s->directory),
2475 		    commit->param.writeout.dir_index);
2476 	    uint32_t begin = begin_of_direntry(entry);
2477 	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
2478 #endif
2479 
2480 	    assert(mapping);
2481 	    assert(mapping->begin == begin);
2482 	    assert(commit->path == NULL);
2483 
2484 	    if (commit_one_file(s, commit->param.writeout.dir_index,
2485 			commit->param.writeout.modified_offset))
2486 		fail = -3;
2487 
2488 	    break;
2489 	}
2490 	case ACTION_NEW_FILE: {
2491 	    int begin = commit->param.new_file.first_cluster;
2492 	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
2493 	    direntry_t* entry;
2494 	    int i;
2495 
2496 	    /* find direntry */
2497 	    for (i = 0; i < s->directory.next; i++) {
2498 		entry = array_get(&(s->directory), i);
2499 		if (is_file(entry) && begin_of_direntry(entry) == begin)
2500 		    break;
2501 	    }
2502 
2503 	    if (i >= s->directory.next) {
2504 		fail = -6;
2505 		continue;
2506 	    }
2507 
2508 	    /* make sure there exists an initial mapping */
2509 	    if (mapping && mapping->begin != begin) {
2510 		mapping->end = begin;
2511 		mapping = NULL;
2512 	    }
2513 	    if (mapping == NULL) {
2514 		mapping = insert_mapping(s, begin, begin+1);
2515 	    }
2516 	    /* most members will be fixed in commit_mappings() */
2517 	    assert(commit->path);
2518 	    mapping->path = commit->path;
2519 	    mapping->read_only = 0;
2520 	    mapping->mode = MODE_NORMAL;
2521 	    mapping->info.file.offset = 0;
2522 
2523 	    if (commit_one_file(s, i, 0))
2524 		fail = -7;
2525 
2526 	    break;
2527 	}
2528 	default:
2529             abort();
2530 	}
2531     }
2532     if (i > 0 && array_remove_slice(&(s->commits), 0, i))
2533 	return -1;
2534     return fail;
2535 }
2536 
2537 static int handle_deletes(BDRVVVFATState* s)
2538 {
2539     int i, deferred = 1, deleted = 1;
2540 
2541     /* delete files corresponding to mappings marked as deleted */
2542     /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
2543     while (deferred && deleted) {
2544 	deferred = 0;
2545 	deleted = 0;
2546 
2547 	for (i = 1; i < s->mapping.next; i++) {
2548 	    mapping_t* mapping = array_get(&(s->mapping), i);
2549 	    if (mapping->mode & MODE_DELETED) {
2550 		direntry_t* entry = array_get(&(s->directory),
2551 			mapping->dir_index);
2552 
2553 		if (is_free(entry)) {
2554 		    /* remove file/directory */
2555 		    if (mapping->mode & MODE_DIRECTORY) {
2556 			int j, next_dir_index = s->directory.next,
2557 			first_dir_index = mapping->info.dir.first_dir_index;
2558 
2559 			if (rmdir(mapping->path) < 0) {
2560 			    if (errno == ENOTEMPTY) {
2561 				deferred++;
2562 				continue;
2563 			    } else
2564 				return -5;
2565 			}
2566 
2567 			for (j = 1; j < s->mapping.next; j++) {
2568 			    mapping_t* m = array_get(&(s->mapping), j);
2569 			    if (m->mode & MODE_DIRECTORY &&
2570 				    m->info.dir.first_dir_index >
2571 				    first_dir_index &&
2572 				    m->info.dir.first_dir_index <
2573 				    next_dir_index)
2574 				next_dir_index =
2575 				    m->info.dir.first_dir_index;
2576 			}
2577 			remove_direntries(s, first_dir_index,
2578 				next_dir_index - first_dir_index);
2579 
2580 			deleted++;
2581 		    }
2582 		} else {
2583 		    if (unlink(mapping->path))
2584 			return -4;
2585 		    deleted++;
2586 		}
2587 		DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
2588 		remove_mapping(s, i);
2589 	    }
2590 	}
2591     }
2592 
2593     return 0;
2594 }
2595 
2596 /*
2597  * synchronize mapping with new state:
2598  *
2599  * - copy FAT (with bdrv_read)
2600  * - mark all filenames corresponding to mappings as deleted
2601  * - recurse direntries from root (using bs->bdrv_read)
2602  * - delete files corresponding to mappings marked as deleted
2603  */
2604 static int do_commit(BDRVVVFATState* s)
2605 {
2606     int ret = 0;
2607 
2608     /* the real meat are the commits. Nothing to do? Move along! */
2609     if (s->commits.next == 0)
2610 	return 0;
2611 
2612     vvfat_close_current_file(s);
2613 
2614     ret = handle_renames_and_mkdirs(s);
2615     if (ret) {
2616 	fprintf(stderr, "Error handling renames (%d)\n", ret);
2617         abort();
2618 	return ret;
2619     }
2620 
2621     /* copy FAT (with bdrv_read) */
2622     memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
2623 
2624     /* recurse direntries from root (using bs->bdrv_read) */
2625     ret = commit_direntries(s, 0, -1);
2626     if (ret) {
2627 	fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
2628         abort();
2629 	return ret;
2630     }
2631 
2632     ret = handle_commits(s);
2633     if (ret) {
2634 	fprintf(stderr, "Error handling commits (%d)\n", ret);
2635         abort();
2636 	return ret;
2637     }
2638 
2639     ret = handle_deletes(s);
2640     if (ret) {
2641 	fprintf(stderr, "Error deleting\n");
2642         abort();
2643 	return ret;
2644     }
2645 
2646     if (s->qcow->drv->bdrv_make_empty) {
2647         s->qcow->drv->bdrv_make_empty(s->qcow);
2648     }
2649 
2650     memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
2651 
2652 DLOG(checkpoint());
2653     return 0;
2654 }
2655 
2656 static int try_commit(BDRVVVFATState* s)
2657 {
2658     vvfat_close_current_file(s);
2659 DLOG(checkpoint());
2660     if(!is_consistent(s))
2661 	return -1;
2662     return do_commit(s);
2663 }
2664 
2665 static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
2666                     const uint8_t *buf, int nb_sectors)
2667 {
2668     BDRVVVFATState *s = bs->opaque;
2669     int i, ret;
2670 
2671 DLOG(checkpoint());
2672 
2673     /* Check if we're operating in read-only mode */
2674     if (s->qcow == NULL) {
2675         return -EACCES;
2676     }
2677 
2678     vvfat_close_current_file(s);
2679 
2680     /*
2681      * Some sanity checks:
2682      * - do not allow writing to the boot sector
2683      * - do not allow to write non-ASCII filenames
2684      */
2685 
2686     if (sector_num < s->first_sectors_number)
2687 	return -1;
2688 
2689     for (i = sector2cluster(s, sector_num);
2690 	    i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
2691 	mapping_t* mapping = find_mapping_for_cluster(s, i);
2692 	if (mapping) {
2693 	    if (mapping->read_only) {
2694 		fprintf(stderr, "Tried to write to write-protected file %s\n",
2695 			mapping->path);
2696 		return -1;
2697 	    }
2698 
2699 	    if (mapping->mode & MODE_DIRECTORY) {
2700 		int begin = cluster2sector(s, i);
2701 		int end = begin + s->sectors_per_cluster, k;
2702 		int dir_index;
2703 		const direntry_t* direntries;
2704 		long_file_name lfn;
2705 
2706 		lfn_init(&lfn);
2707 
2708 		if (begin < sector_num)
2709 		    begin = sector_num;
2710 		if (end > sector_num + nb_sectors)
2711 		    end = sector_num + nb_sectors;
2712 		dir_index  = mapping->dir_index +
2713 		    0x10 * (begin - mapping->begin * s->sectors_per_cluster);
2714 		direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
2715 
2716 		for (k = 0; k < (end - begin) * 0x10; k++) {
2717 		    /* do not allow non-ASCII filenames */
2718 		    if (parse_long_name(&lfn, direntries + k) < 0) {
2719 			fprintf(stderr, "Warning: non-ASCII filename\n");
2720 			return -1;
2721 		    }
2722 		    /* no access to the direntry of a read-only file */
2723 		    else if (is_short_name(direntries+k) &&
2724 			    (direntries[k].attributes & 1)) {
2725 			if (memcmp(direntries + k,
2726 				    array_get(&(s->directory), dir_index + k),
2727 				    sizeof(direntry_t))) {
2728 			    fprintf(stderr, "Warning: tried to write to write-protected file\n");
2729 			    return -1;
2730 			}
2731 		    }
2732 		}
2733 	    }
2734 	    i = mapping->end;
2735 	} else
2736 	    i++;
2737     }
2738 
2739     /*
2740      * Use qcow backend. Commit later.
2741      */
2742 DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
2743     ret = bdrv_write(s->qcow, sector_num, buf, nb_sectors);
2744     if (ret < 0) {
2745 	fprintf(stderr, "Error writing to qcow backend\n");
2746 	return ret;
2747     }
2748 
2749     for (i = sector2cluster(s, sector_num);
2750 	    i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
2751 	if (i >= 0)
2752 	    s->used_clusters[i] |= USED_ALLOCATED;
2753 
2754 DLOG(checkpoint());
2755     /* TODO: add timeout */
2756     try_commit(s);
2757 
2758 DLOG(checkpoint());
2759     return 0;
2760 }
2761 
2762 static coroutine_fn int vvfat_co_write(BlockDriverState *bs, int64_t sector_num,
2763                                        const uint8_t *buf, int nb_sectors)
2764 {
2765     int ret;
2766     BDRVVVFATState *s = bs->opaque;
2767     qemu_co_mutex_lock(&s->lock);
2768     ret = vvfat_write(bs, sector_num, buf, nb_sectors);
2769     qemu_co_mutex_unlock(&s->lock);
2770     return ret;
2771 }
2772 
2773 static int coroutine_fn vvfat_co_is_allocated(BlockDriverState *bs,
2774 	int64_t sector_num, int nb_sectors, int* n)
2775 {
2776     BDRVVVFATState* s = bs->opaque;
2777     *n = s->sector_count - sector_num;
2778     if (*n > nb_sectors)
2779 	*n = nb_sectors;
2780     else if (*n < 0)
2781 	return 0;
2782     return 1;
2783 }
2784 
2785 static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
2786 	const uint8_t* buffer, int nb_sectors) {
2787     BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
2788     return try_commit(s);
2789 }
2790 
2791 static void write_target_close(BlockDriverState *bs) {
2792     BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
2793     bdrv_delete(s->qcow);
2794     g_free(s->qcow_filename);
2795 }
2796 
2797 static BlockDriver vvfat_write_target = {
2798     .format_name        = "vvfat_write_target",
2799     .bdrv_write         = write_target_commit,
2800     .bdrv_close         = write_target_close,
2801 };
2802 
2803 static int enable_write_target(BDRVVVFATState *s)
2804 {
2805     BlockDriver *bdrv_qcow;
2806     QEMUOptionParameter *options;
2807     int ret;
2808     int size = sector2cluster(s, s->sector_count);
2809     s->used_clusters = calloc(size, 1);
2810 
2811     array_init(&(s->commits), sizeof(commit_t));
2812 
2813     s->qcow_filename = g_malloc(1024);
2814     ret = get_tmp_filename(s->qcow_filename, 1024);
2815     if (ret < 0) {
2816         g_free(s->qcow_filename);
2817         s->qcow_filename = NULL;
2818         return ret;
2819     }
2820 
2821     bdrv_qcow = bdrv_find_format("qcow");
2822     options = parse_option_parameters("", bdrv_qcow->create_options, NULL);
2823     set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
2824     set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
2825 
2826     if (bdrv_create(bdrv_qcow, s->qcow_filename, options) < 0)
2827 	return -1;
2828 
2829     s->qcow = bdrv_new("");
2830     if (s->qcow == NULL) {
2831         return -1;
2832     }
2833 
2834     ret = bdrv_open(s->qcow, s->qcow_filename, NULL,
2835             BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow);
2836     if (ret < 0) {
2837 	return ret;
2838     }
2839 
2840 #ifndef _WIN32
2841     unlink(s->qcow_filename);
2842 #endif
2843 
2844     s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1);
2845     s->bs->backing_hd->drv = &vvfat_write_target;
2846     s->bs->backing_hd->opaque = g_malloc(sizeof(void*));
2847     *(void**)s->bs->backing_hd->opaque = s;
2848 
2849     return 0;
2850 }
2851 
2852 static void vvfat_close(BlockDriverState *bs)
2853 {
2854     BDRVVVFATState *s = bs->opaque;
2855 
2856     vvfat_close_current_file(s);
2857     array_free(&(s->fat));
2858     array_free(&(s->directory));
2859     array_free(&(s->mapping));
2860     g_free(s->cluster_buffer);
2861 
2862     if (s->qcow) {
2863         migrate_del_blocker(s->migration_blocker);
2864         error_free(s->migration_blocker);
2865     }
2866 }
2867 
2868 static BlockDriver bdrv_vvfat = {
2869     .format_name	= "vvfat",
2870     .instance_size	= sizeof(BDRVVVFATState),
2871     .bdrv_file_open	= vvfat_open,
2872     .bdrv_rebind	= vvfat_rebind,
2873     .bdrv_read          = vvfat_co_read,
2874     .bdrv_write         = vvfat_co_write,
2875     .bdrv_close		= vvfat_close,
2876     .bdrv_co_is_allocated = vvfat_co_is_allocated,
2877     .protocol_name	= "fat",
2878 };
2879 
2880 static void bdrv_vvfat_init(void)
2881 {
2882     bdrv_register(&bdrv_vvfat);
2883 }
2884 
2885 block_init(bdrv_vvfat_init);
2886 
2887 #ifdef DEBUG
2888 static void checkpoint(void) {
2889     assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
2890     check1(vvv);
2891     check2(vvv);
2892     assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
2893 #if 0
2894     if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)
2895 	fprintf(stderr, "Nonono!\n");
2896     mapping_t* mapping;
2897     direntry_t* direntry;
2898     assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);
2899     assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);
2900     if (vvv->mapping.next<47)
2901 	return;
2902     assert((mapping = array_get(&(vvv->mapping), 47)));
2903     assert(mapping->dir_index < vvv->directory.next);
2904     direntry = array_get(&(vvv->directory), mapping->dir_index);
2905     assert(!memcmp(direntry->name, "USB     H  ", 11) || direntry->name[0]==0);
2906 #endif
2907 }
2908 #endif
2909