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