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