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