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