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