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