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