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