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