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