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