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