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