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