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