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