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