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