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