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