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    ret = 0;
1283fail:
1284    qemu_opts_del(opts);
1285    return ret;
1286}
1287
1288static void vvfat_refresh_limits(BlockDriverState *bs, Error **errp)
1289{
1290    bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
1291}
1292
1293static inline void vvfat_close_current_file(BDRVVVFATState *s)
1294{
1295    if(s->current_mapping) {
1296        s->current_mapping = NULL;
1297        if (s->current_fd) {
1298                qemu_close(s->current_fd);
1299                s->current_fd = 0;
1300        }
1301    }
1302    s->current_cluster = -1;
1303}
1304
1305/* mappings between index1 and index2-1 are supposed to be ordered
1306 * return value is the index of the last mapping for which end>cluster_num
1307 */
1308static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
1309{
1310    while(1) {
1311        int index3;
1312        mapping_t* mapping;
1313        index3=(index1+index2)/2;
1314        mapping=array_get(&(s->mapping),index3);
1315        assert(mapping->begin < mapping->end);
1316        if(mapping->begin>=cluster_num) {
1317            assert(index2!=index3 || index2==0);
1318            if(index2==index3)
1319                return index1;
1320            index2=index3;
1321        } else {
1322            if(index1==index3)
1323                return mapping->end<=cluster_num ? index2 : index1;
1324            index1=index3;
1325        }
1326        assert(index1<=index2);
1327        DLOG(mapping=array_get(&(s->mapping),index1);
1328        assert(mapping->begin<=cluster_num);
1329        assert(index2 >= s->mapping.next ||
1330                ((mapping = array_get(&(s->mapping),index2)) &&
1331                mapping->end>cluster_num)));
1332    }
1333}
1334
1335static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
1336{
1337    int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
1338    mapping_t* mapping;
1339    if(index>=s->mapping.next)
1340        return NULL;
1341    mapping=array_get(&(s->mapping),index);
1342    if(mapping->begin>cluster_num)
1343        return NULL;
1344    assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
1345    return mapping;
1346}
1347
1348static int open_file(BDRVVVFATState* s,mapping_t* mapping)
1349{
1350    if(!mapping)
1351        return -1;
1352    if(!s->current_mapping ||
1353            strcmp(s->current_mapping->path,mapping->path)) {
1354        /* open file */
1355        int fd = qemu_open_old(mapping->path,
1356                               O_RDONLY | O_BINARY | O_LARGEFILE);
1357        if(fd<0)
1358            return -1;
1359        vvfat_close_current_file(s);
1360        s->current_fd = fd;
1361        s->current_mapping = mapping;
1362    }
1363    return 0;
1364}
1365
1366static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
1367{
1368    if(s->current_cluster != cluster_num) {
1369        int result=0;
1370        off_t offset;
1371        assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
1372        if(!s->current_mapping
1373                || s->current_mapping->begin>cluster_num
1374                || s->current_mapping->end<=cluster_num) {
1375            /* binary search of mappings for file */
1376            mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
1377
1378            assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
1379
1380            if (mapping && mapping->mode & MODE_DIRECTORY) {
1381                vvfat_close_current_file(s);
1382                s->current_mapping = mapping;
1383read_cluster_directory:
1384                offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
1385                s->cluster = (unsigned char*)s->directory.pointer+offset
1386                        + 0x20*s->current_mapping->info.dir.first_dir_index;
1387                assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
1388                assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
1389                s->current_cluster = cluster_num;
1390                return 0;
1391            }
1392
1393            if(open_file(s,mapping))
1394                return -2;
1395        } else if (s->current_mapping->mode & MODE_DIRECTORY)
1396            goto read_cluster_directory;
1397
1398        assert(s->current_fd);
1399
1400        offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
1401        if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
1402            return -3;
1403        s->cluster=s->cluster_buffer;
1404        result=read(s->current_fd,s->cluster,s->cluster_size);
1405        if(result<0) {
1406            s->current_cluster = -1;
1407            return -1;
1408        }
1409        s->current_cluster = cluster_num;
1410    }
1411    return 0;
1412}
1413
1414#ifdef DEBUG
1415static void print_direntry(const direntry_t* direntry)
1416{
1417    int j = 0;
1418    char buffer[1024];
1419
1420    fprintf(stderr, "direntry %p: ", direntry);
1421    if(!direntry)
1422        return;
1423    if(is_long_name(direntry)) {
1424        unsigned char* c=(unsigned char*)direntry;
1425        int i;
1426        for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
1427#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
1428            ADD_CHAR(c[i]);
1429        for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
1430            ADD_CHAR(c[i]);
1431        for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
1432            ADD_CHAR(c[i]);
1433        buffer[j] = 0;
1434        fprintf(stderr, "%s\n", buffer);
1435    } else {
1436        int i;
1437        for(i=0;i<11;i++)
1438            ADD_CHAR(direntry->name[i]);
1439        buffer[j] = 0;
1440        fprintf(stderr, "%s attributes=0x%02x begin=%u size=%u\n",
1441                buffer,
1442                direntry->attributes,
1443                begin_of_direntry(direntry),le32_to_cpu(direntry->size));
1444    }
1445}
1446
1447static void print_mapping(const mapping_t* mapping)
1448{
1449    fprintf(stderr, "mapping (%p): begin, end = %u, %u, dir_index = %u, "
1450        "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
1451        mapping, mapping->begin, mapping->end, mapping->dir_index,
1452        mapping->first_mapping_index, mapping->path, mapping->mode);
1453
1454    if (mapping->mode & MODE_DIRECTORY)
1455        fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
1456    else
1457        fprintf(stderr, "offset = %u\n", mapping->info.file.offset);
1458}
1459#endif
1460
1461static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
1462                    uint8_t *buf, int nb_sectors)
1463{
1464    BDRVVVFATState *s = bs->opaque;
1465    int i;
1466
1467    for(i=0;i<nb_sectors;i++,sector_num++) {
1468        if (sector_num >= bs->total_sectors)
1469           return -1;
1470        if (s->qcow) {
1471            int64_t n;
1472            int ret;
1473            ret = bdrv_is_allocated(s->qcow->bs, sector_num * BDRV_SECTOR_SIZE,
1474                                    (nb_sectors - i) * BDRV_SECTOR_SIZE, &n);
1475            if (ret < 0) {
1476                return ret;
1477            }
1478            if (ret) {
1479                DLOG(fprintf(stderr, "sectors %" PRId64 "+%" PRId64
1480                             " allocated\n", sector_num,
1481                             n >> BDRV_SECTOR_BITS));
1482                if (bdrv_pread(s->qcow, sector_num * BDRV_SECTOR_SIZE,
1483                               buf + i * 0x200, n) < 0) {
1484                    return -1;
1485                }
1486                i += (n >> BDRV_SECTOR_BITS) - 1;
1487                sector_num += (n >> BDRV_SECTOR_BITS) - 1;
1488                continue;
1489            }
1490            DLOG(fprintf(stderr, "sector %" PRId64 " not allocated\n",
1491                         sector_num));
1492        }
1493        if (sector_num < s->offset_to_root_dir) {
1494            if (sector_num < s->offset_to_fat) {
1495                memcpy(buf + i * 0x200,
1496                       &(s->first_sectors[sector_num * 0x200]),
1497                       0x200);
1498            } else if (sector_num < s->offset_to_fat + s->sectors_per_fat) {
1499                memcpy(buf + i * 0x200,
1500                       &(s->fat.pointer[(sector_num
1501                                       - s->offset_to_fat) * 0x200]),
1502                       0x200);
1503            } else if (sector_num < s->offset_to_root_dir) {
1504                memcpy(buf + i * 0x200,
1505                       &(s->fat.pointer[(sector_num - s->offset_to_fat
1506                                       - s->sectors_per_fat) * 0x200]),
1507                       0x200);
1508            }
1509        } else {
1510            uint32_t sector = sector_num - s->offset_to_root_dir,
1511            sector_offset_in_cluster=(sector%s->sectors_per_cluster),
1512            cluster_num=sector/s->sectors_per_cluster;
1513            if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
1514                /* LATER TODO: strict: return -1; */
1515                memset(buf+i*0x200,0,0x200);
1516                continue;
1517            }
1518            memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
1519        }
1520    }
1521    return 0;
1522}
1523
1524static int coroutine_fn
1525vvfat_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
1526                QEMUIOVector *qiov, int flags)
1527{
1528    int ret;
1529    BDRVVVFATState *s = bs->opaque;
1530    uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
1531    int nb_sectors = bytes >> BDRV_SECTOR_BITS;
1532    void *buf;
1533
1534    assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
1535    assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
1536
1537    buf = g_try_malloc(bytes);
1538    if (bytes && buf == NULL) {
1539        return -ENOMEM;
1540    }
1541
1542    qemu_co_mutex_lock(&s->lock);
1543    ret = vvfat_read(bs, sector_num, buf, nb_sectors);
1544    qemu_co_mutex_unlock(&s->lock);
1545
1546    qemu_iovec_from_buf(qiov, 0, buf, bytes);
1547    g_free(buf);
1548
1549    return ret;
1550}
1551
1552/* LATER TODO: statify all functions */
1553
1554/*
1555 * Idea of the write support (use snapshot):
1556 *
1557 * 1. check if all data is consistent, recording renames, modifications,
1558 *    new files and directories (in s->commits).
1559 *
1560 * 2. if the data is not consistent, stop committing
1561 *
1562 * 3. handle renames, and create new files and directories (do not yet
1563 *    write their contents)
1564 *
1565 * 4. walk the directories, fixing the mapping and direntries, and marking
1566 *    the handled mappings as not deleted
1567 *
1568 * 5. commit the contents of the files
1569 *
1570 * 6. handle deleted files and directories
1571 *
1572 */
1573
1574typedef struct commit_t {
1575    char* path;
1576    union {
1577        struct { uint32_t cluster; } rename;
1578        struct { int dir_index; uint32_t modified_offset; } writeout;
1579        struct { uint32_t first_cluster; } new_file;
1580        struct { uint32_t cluster; } mkdir;
1581    } param;
1582    /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
1583    enum {
1584        ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
1585    } action;
1586} commit_t;
1587
1588static void clear_commits(BDRVVVFATState* s)
1589{
1590    int i;
1591DLOG(fprintf(stderr, "clear_commits (%u commits)\n", s->commits.next));
1592    for (i = 0; i < s->commits.next; i++) {
1593        commit_t* commit = array_get(&(s->commits), i);
1594        assert(commit->path || commit->action == ACTION_WRITEOUT);
1595        if (commit->action != ACTION_WRITEOUT) {
1596            assert(commit->path);
1597            g_free(commit->path);
1598        } else
1599            assert(commit->path == NULL);
1600    }
1601    s->commits.next = 0;
1602}
1603
1604static void schedule_rename(BDRVVVFATState* s,
1605        uint32_t cluster, char* new_path)
1606{
1607    commit_t* commit = array_get_next(&(s->commits));
1608    commit->path = new_path;
1609    commit->param.rename.cluster = cluster;
1610    commit->action = ACTION_RENAME;
1611}
1612
1613static void schedule_writeout(BDRVVVFATState* s,
1614        int dir_index, uint32_t modified_offset)
1615{
1616    commit_t* commit = array_get_next(&(s->commits));
1617    commit->path = NULL;
1618    commit->param.writeout.dir_index = dir_index;
1619    commit->param.writeout.modified_offset = modified_offset;
1620    commit->action = ACTION_WRITEOUT;
1621}
1622
1623static void schedule_new_file(BDRVVVFATState* s,
1624        char* path, uint32_t first_cluster)
1625{
1626    commit_t* commit = array_get_next(&(s->commits));
1627    commit->path = path;
1628    commit->param.new_file.first_cluster = first_cluster;
1629    commit->action = ACTION_NEW_FILE;
1630}
1631
1632static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
1633{
1634    commit_t* commit = array_get_next(&(s->commits));
1635    commit->path = path;
1636    commit->param.mkdir.cluster = cluster;
1637    commit->action = ACTION_MKDIR;
1638}
1639
1640typedef struct {
1641    /*
1642     * Since the sequence number is at most 0x3f, and the filename
1643     * length is at most 13 times the sequence number, the maximal
1644     * filename length is 0x3f * 13 bytes.
1645     */
1646    unsigned char name[0x3f * 13 + 1];
1647    gunichar2 name2[0x3f * 13 + 1];
1648    int checksum, len;
1649    int sequence_number;
1650} long_file_name;
1651
1652static void lfn_init(long_file_name* lfn)
1653{
1654   lfn->sequence_number = lfn->len = 0;
1655   lfn->checksum = 0x100;
1656}
1657
1658/* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
1659static int parse_long_name(long_file_name* lfn,
1660        const direntry_t* direntry)
1661{
1662    int i, j, offset;
1663    const unsigned char* pointer = (const unsigned char*)direntry;
1664
1665    if (!is_long_name(direntry))
1666        return 1;
1667
1668    if (pointer[0] & 0x40) {
1669        /* first entry; do some initialization */
1670        lfn->sequence_number = pointer[0] & 0x3f;
1671        lfn->checksum = pointer[13];
1672        lfn->name[0] = 0;
1673        lfn->name[lfn->sequence_number * 13] = 0;
1674    } else if ((pointer[0] & 0x3f) != --lfn->sequence_number) {
1675        /* not the expected sequence number */
1676        return -1;
1677    } else if (pointer[13] != lfn->checksum) {
1678        /* not the expected checksum */
1679        return -2;
1680    } else if (pointer[12] || pointer[26] || pointer[27]) {
1681        /* invalid zero fields */
1682        return -3;
1683    }
1684
1685    offset = 13 * (lfn->sequence_number - 1);
1686    for (i = 0, j = 1; i < 13; i++, j+=2) {
1687        if (j == 11)
1688            j = 14;
1689        else if (j == 26)
1690            j = 28;
1691
1692        if (pointer[j] == 0 && pointer[j + 1] == 0) {
1693            /* end of long file name */
1694            break;
1695        }
1696        gunichar2 c = (pointer[j + 1] << 8) + pointer[j];
1697        lfn->name2[offset + i] = c;
1698    }
1699
1700    if (pointer[0] & 0x40) {
1701        /* first entry; set len */
1702        lfn->len = offset + i;
1703    }
1704    if ((pointer[0] & 0x3f) == 0x01) {
1705        /* last entry; finalize entry */
1706        glong olen;
1707        gchar *utf8 = g_utf16_to_utf8(lfn->name2, lfn->len, NULL, &olen, NULL);
1708        if (!utf8) {
1709            return -4;
1710        }
1711        lfn->len = olen;
1712        memcpy(lfn->name, utf8, olen + 1);
1713        g_free(utf8);
1714    }
1715
1716    return 0;
1717}
1718
1719/* returns 0 if successful, >0 if no short_name, and <0 on error */
1720static int parse_short_name(BDRVVVFATState* s,
1721        long_file_name* lfn, direntry_t* direntry)
1722{
1723    int i, j;
1724
1725    if (!is_short_name(direntry))
1726        return 1;
1727
1728    for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
1729    for (i = 0; i <= j; i++) {
1730        uint8_t c = direntry->name[i];
1731        if (c != to_valid_short_char(c)) {
1732            return -1;
1733        } else if (s->downcase_short_names) {
1734            lfn->name[i] = qemu_tolower(direntry->name[i]);
1735        } else {
1736            lfn->name[i] = direntry->name[i];
1737        }
1738    }
1739
1740    for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) {
1741    }
1742    if (j >= 0) {
1743        lfn->name[i++] = '.';
1744        lfn->name[i + j + 1] = '\0';
1745        for (;j >= 0; j--) {
1746            uint8_t c = direntry->name[8 + j];
1747            if (c != to_valid_short_char(c)) {
1748                return -2;
1749            } else if (s->downcase_short_names) {
1750                lfn->name[i + j] = qemu_tolower(c);
1751            } else {
1752                lfn->name[i + j] = c;
1753            }
1754        }
1755    } else
1756        lfn->name[i + j + 1] = '\0';
1757
1758    if (lfn->name[0] == DIR_KANJI_FAKE) {
1759        lfn->name[0] = DIR_KANJI;
1760    }
1761    lfn->len = strlen((char*)lfn->name);
1762
1763    return 0;
1764}
1765
1766static inline uint32_t modified_fat_get(BDRVVVFATState* s,
1767        unsigned int cluster)
1768{
1769    if (cluster < s->last_cluster_of_root_directory) {
1770        if (cluster + 1 == s->last_cluster_of_root_directory)
1771            return s->max_fat_value;
1772        else
1773            return cluster + 1;
1774    }
1775
1776    if (s->fat_type==32) {
1777        uint32_t* entry=((uint32_t*)s->fat2)+cluster;
1778        return le32_to_cpu(*entry);
1779    } else if (s->fat_type==16) {
1780        uint16_t* entry=((uint16_t*)s->fat2)+cluster;
1781        return le16_to_cpu(*entry);
1782    } else {
1783        const uint8_t* x=s->fat2+cluster*3/2;
1784        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
1785    }
1786}
1787
1788static inline bool cluster_was_modified(BDRVVVFATState *s,
1789                                        uint32_t cluster_num)
1790{
1791    int was_modified = 0;
1792    int i;
1793
1794    if (s->qcow == NULL) {
1795        return 0;
1796    }
1797
1798    for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) {
1799        was_modified = bdrv_is_allocated(s->qcow->bs,
1800                                         (cluster2sector(s, cluster_num) +
1801                                          i) * BDRV_SECTOR_SIZE,
1802                                         BDRV_SECTOR_SIZE, NULL);
1803    }
1804
1805    /*
1806     * Note that this treats failures to learn allocation status the
1807     * same as if an allocation has occurred.  It's as safe as
1808     * anything else, given that a failure to learn allocation status
1809     * will probably result in more failures.
1810     */
1811    return !!was_modified;
1812}
1813
1814static const char* get_basename(const char* path)
1815{
1816    char* basename = strrchr(path, '/');
1817    if (basename == NULL)
1818        return path;
1819    else
1820        return basename + 1; /* strip '/' */
1821}
1822
1823/*
1824 * The array s->used_clusters holds the states of the clusters. If it is
1825 * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
1826 * was modified, bit 3 is set.
1827 * If any cluster is allocated, but not part of a file or directory, this
1828 * driver refuses to commit.
1829 */
1830typedef enum {
1831     USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
1832} used_t;
1833
1834/*
1835 * get_cluster_count_for_direntry() not only determines how many clusters
1836 * are occupied by direntry, but also if it was renamed or modified.
1837 *
1838 * A file is thought to be renamed *only* if there already was a file with
1839 * exactly the same first cluster, but a different name.
1840 *
1841 * Further, the files/directories handled by this function are
1842 * assumed to be *not* deleted (and *only* those).
1843 */
1844static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
1845        direntry_t* direntry, const char* path)
1846{
1847    /*
1848     * This is a little bit tricky:
1849     * IF the guest OS just inserts a cluster into the file chain,
1850     * and leaves the rest alone, (i.e. the original file had clusters
1851     * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
1852     *
1853     * - do_commit will write the cluster into the file at the given
1854     *   offset, but
1855     *
1856     * - the cluster which is overwritten should be moved to a later
1857     *   position in the file.
1858     *
1859     * I am not aware that any OS does something as braindead, but this
1860     * situation could happen anyway when not committing for a long time.
1861     * Just to be sure that this does not bite us, detect it, and copy the
1862     * contents of the clusters to-be-overwritten into the qcow.
1863     */
1864    int copy_it = 0;
1865    int was_modified = 0;
1866    int32_t ret = 0;
1867
1868    uint32_t cluster_num = begin_of_direntry(direntry);
1869    uint32_t offset = 0;
1870    int first_mapping_index = -1;
1871    mapping_t* mapping = NULL;
1872    const char* basename2 = NULL;
1873
1874    vvfat_close_current_file(s);
1875
1876    /* the root directory */
1877    if (cluster_num == 0)
1878        return 0;
1879
1880    /* write support */
1881    if (s->qcow) {
1882        basename2 = get_basename(path);
1883
1884        mapping = find_mapping_for_cluster(s, cluster_num);
1885
1886        if (mapping) {
1887            const char* basename;
1888
1889            assert(mapping->mode & MODE_DELETED);
1890            mapping->mode &= ~MODE_DELETED;
1891
1892            basename = get_basename(mapping->path);
1893
1894            assert(mapping->mode & MODE_NORMAL);
1895
1896            /* rename */
1897            if (strcmp(basename, basename2))
1898                schedule_rename(s, cluster_num, g_strdup(path));
1899        } else if (is_file(direntry))
1900            /* new file */
1901            schedule_new_file(s, g_strdup(path), cluster_num);
1902        else {
1903            abort();
1904            return 0;
1905        }
1906    }
1907
1908    while(1) {
1909        if (s->qcow) {
1910            if (!copy_it && cluster_was_modified(s, cluster_num)) {
1911                if (mapping == NULL ||
1912                        mapping->begin > cluster_num ||
1913                        mapping->end <= cluster_num)
1914                mapping = find_mapping_for_cluster(s, cluster_num);
1915
1916
1917                if (mapping &&
1918                        (mapping->mode & MODE_DIRECTORY) == 0) {
1919
1920                    /* was modified in qcow */
1921                    if (offset != mapping->info.file.offset + s->cluster_size
1922                            * (cluster_num - mapping->begin)) {
1923                        /* offset of this cluster in file chain has changed */
1924                        abort();
1925                        copy_it = 1;
1926                    } else if (offset == 0) {
1927                        const char* basename = get_basename(mapping->path);
1928
1929                        if (strcmp(basename, basename2))
1930                            copy_it = 1;
1931                        first_mapping_index = array_index(&(s->mapping), mapping);
1932                    }
1933
1934                    if (mapping->first_mapping_index != first_mapping_index
1935                            && mapping->info.file.offset > 0) {
1936                        abort();
1937                        copy_it = 1;
1938                    }
1939
1940                    /* need to write out? */
1941                    if (!was_modified && is_file(direntry)) {
1942                        was_modified = 1;
1943                        schedule_writeout(s, mapping->dir_index, offset);
1944                    }
1945                }
1946            }
1947
1948            if (copy_it) {
1949                int i;
1950                /*
1951                 * This is horribly inefficient, but that is okay, since
1952                 * it is rarely executed, if at all.
1953                 */
1954                int64_t offset = cluster2sector(s, cluster_num);
1955
1956                vvfat_close_current_file(s);
1957                for (i = 0; i < s->sectors_per_cluster; i++) {
1958                    int res;
1959
1960                    res = bdrv_is_allocated(s->qcow->bs,
1961                                            (offset + i) * BDRV_SECTOR_SIZE,
1962                                            BDRV_SECTOR_SIZE, NULL);
1963                    if (res < 0) {
1964                        return -1;
1965                    }
1966                    if (!res) {
1967                        res = vvfat_read(s->bs, offset, s->cluster_buffer, 1);
1968                        if (res) {
1969                            return -1;
1970                        }
1971                        res = bdrv_pwrite(s->qcow, offset * BDRV_SECTOR_SIZE,
1972                                          s->cluster_buffer, BDRV_SECTOR_SIZE);
1973                        if (res < 0) {
1974                            return -2;
1975                        }
1976                    }
1977                }
1978            }
1979        }
1980
1981        ret++;
1982        if (s->used_clusters[cluster_num] & USED_ANY)
1983            return 0;
1984        s->used_clusters[cluster_num] = USED_FILE;
1985
1986        cluster_num = modified_fat_get(s, cluster_num);
1987
1988        if (fat_eof(s, cluster_num))
1989            return ret;
1990        else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
1991            return -1;
1992
1993        offset += s->cluster_size;
1994    }
1995}
1996
1997/*
1998 * This function looks at the modified data (qcow).
1999 * It returns 0 upon inconsistency or error, and the number of clusters
2000 * used by the directory, its subdirectories and their files.
2001 */
2002static int check_directory_consistency(BDRVVVFATState *s,
2003        int cluster_num, const char* path)
2004{
2005    int ret = 0;
2006    unsigned char* cluster = g_malloc(s->cluster_size);
2007    direntry_t* direntries = (direntry_t*)cluster;
2008    mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
2009
2010    long_file_name lfn;
2011    int path_len = strlen(path);
2012    char path2[PATH_MAX + 1];
2013
2014    assert(path_len < PATH_MAX); /* len was tested before! */
2015    pstrcpy(path2, sizeof(path2), path);
2016    path2[path_len] = '/';
2017    path2[path_len + 1] = '\0';
2018
2019    if (mapping) {
2020        const char* basename = get_basename(mapping->path);
2021        const char* basename2 = get_basename(path);
2022
2023        assert(mapping->mode & MODE_DIRECTORY);
2024
2025        assert(mapping->mode & MODE_DELETED);
2026        mapping->mode &= ~MODE_DELETED;
2027
2028        if (strcmp(basename, basename2))
2029            schedule_rename(s, cluster_num, g_strdup(path));
2030    } else
2031        /* new directory */
2032        schedule_mkdir(s, cluster_num, g_strdup(path));
2033
2034    lfn_init(&lfn);
2035    do {
2036        int i;
2037        int subret = 0;
2038
2039        ret++;
2040
2041        if (s->used_clusters[cluster_num] & USED_ANY) {
2042            fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
2043            goto fail;
2044        }
2045        s->used_clusters[cluster_num] = USED_DIRECTORY;
2046
2047DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
2048        subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
2049                s->sectors_per_cluster);
2050        if (subret) {
2051            fprintf(stderr, "Error fetching direntries\n");
2052        fail:
2053            g_free(cluster);
2054            return 0;
2055        }
2056
2057        for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
2058            int cluster_count = 0;
2059
2060DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i));
2061            if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
2062                    is_free(direntries + i))
2063                continue;
2064
2065            subret = parse_long_name(&lfn, direntries + i);
2066            if (subret < 0) {
2067                fprintf(stderr, "Error in long name\n");
2068                goto fail;
2069            }
2070            if (subret == 0 || is_free(direntries + i))
2071                continue;
2072
2073            if (fat_chksum(direntries+i) != lfn.checksum) {
2074                subret = parse_short_name(s, &lfn, direntries + i);
2075                if (subret < 0) {
2076                    fprintf(stderr, "Error in short name (%d)\n", subret);
2077                    goto fail;
2078                }
2079                if (subret > 0 || !strcmp((char*)lfn.name, ".")
2080                        || !strcmp((char*)lfn.name, ".."))
2081                    continue;
2082            }
2083            lfn.checksum = 0x100; /* cannot use long name twice */
2084
2085            if (!valid_filename(lfn.name)) {
2086                fprintf(stderr, "Invalid file name\n");
2087                goto fail;
2088            }
2089            if (path_len + 1 + lfn.len >= PATH_MAX) {
2090                fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
2091                goto fail;
2092            }
2093            pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
2094                    (char*)lfn.name);
2095
2096            if (is_directory(direntries + i)) {
2097                if (begin_of_direntry(direntries + i) == 0) {
2098                    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
2099                    goto fail;
2100                }
2101                cluster_count = check_directory_consistency(s,
2102                        begin_of_direntry(direntries + i), path2);
2103                if (cluster_count == 0) {
2104                    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
2105                    goto fail;
2106                }
2107            } else if (is_file(direntries + i)) {
2108                /* check file size with FAT */
2109                cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
2110                if (cluster_count !=
2111            DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) {
2112                    DLOG(fprintf(stderr, "Cluster count mismatch\n"));
2113                    goto fail;
2114                }
2115            } else
2116                abort(); /* cluster_count = 0; */
2117
2118            ret += cluster_count;
2119        }
2120
2121        cluster_num = modified_fat_get(s, cluster_num);
2122    } while(!fat_eof(s, cluster_num));
2123
2124    g_free(cluster);
2125    return ret;
2126}
2127
2128/* returns 1 on success */
2129static int is_consistent(BDRVVVFATState* s)
2130{
2131    int i, check;
2132    int used_clusters_count = 0;
2133
2134DLOG(checkpoint());
2135    /*
2136     * - get modified FAT
2137     * - compare the two FATs (TODO)
2138     * - get buffer for marking used clusters
2139     * - recurse direntries from root (using bs->bdrv_pread to make
2140     *    sure to get the new data)
2141     *   - check that the FAT agrees with the size
2142     *   - count the number of clusters occupied by this directory and
2143     *     its files
2144     * - check that the cumulative used cluster count agrees with the
2145     *   FAT
2146     * - if all is fine, return number of used clusters
2147     */
2148    if (s->fat2 == NULL) {
2149        int size = 0x200 * s->sectors_per_fat;
2150        s->fat2 = g_malloc(size);
2151        memcpy(s->fat2, s->fat.pointer, size);
2152    }
2153    check = vvfat_read(s->bs,
2154            s->offset_to_fat, s->fat2, s->sectors_per_fat);
2155    if (check) {
2156        fprintf(stderr, "Could not copy fat\n");
2157        return 0;
2158    }
2159    assert (s->used_clusters);
2160    for (i = 0; i < sector2cluster(s, s->sector_count); i++)
2161        s->used_clusters[i] &= ~USED_ANY;
2162
2163    clear_commits(s);
2164
2165    /* mark every mapped file/directory as deleted.
2166     * (check_directory_consistency() will unmark those still present). */
2167    if (s->qcow)
2168        for (i = 0; i < s->mapping.next; i++) {
2169            mapping_t* mapping = array_get(&(s->mapping), i);
2170            if (mapping->first_mapping_index < 0)
2171                mapping->mode |= MODE_DELETED;
2172        }
2173
2174    used_clusters_count = check_directory_consistency(s, 0, s->path);
2175    if (used_clusters_count <= 0) {
2176        DLOG(fprintf(stderr, "problem in directory\n"));
2177        return 0;
2178    }
2179
2180    check = s->last_cluster_of_root_directory;
2181    for (i = check; i < sector2cluster(s, s->sector_count); i++) {
2182        if (modified_fat_get(s, i)) {
2183            if(!s->used_clusters[i]) {
2184                DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
2185                return 0;
2186            }
2187            check++;
2188        }
2189
2190        if (s->used_clusters[i] == USED_ALLOCATED) {
2191            /* allocated, but not used... */
2192            DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
2193            return 0;
2194        }
2195    }
2196
2197    if (check != used_clusters_count)
2198        return 0;
2199
2200    return used_clusters_count;
2201}
2202
2203static inline void adjust_mapping_indices(BDRVVVFATState* s,
2204        int offset, int adjust)
2205{
2206    int i;
2207
2208    for (i = 0; i < s->mapping.next; i++) {
2209        mapping_t* mapping = array_get(&(s->mapping), i);
2210
2211#define ADJUST_MAPPING_INDEX(name) \
2212        if (mapping->name >= offset) \
2213            mapping->name += adjust
2214
2215        ADJUST_MAPPING_INDEX(first_mapping_index);
2216        if (mapping->mode & MODE_DIRECTORY)
2217            ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
2218    }
2219}
2220
2221/* insert or update mapping */
2222static mapping_t* insert_mapping(BDRVVVFATState* s,
2223        uint32_t begin, uint32_t end)
2224{
2225    /*
2226     * - find mapping where mapping->begin >= begin,
2227     * - if mapping->begin > begin: insert
2228     *   - adjust all references to mappings!
2229     * - else: adjust
2230     * - replace name
2231     */
2232    int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
2233    mapping_t* mapping = NULL;
2234    mapping_t* first_mapping = array_get(&(s->mapping), 0);
2235
2236    if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
2237            && mapping->begin < begin) {
2238        mapping->end = begin;
2239        index++;
2240        mapping = array_get(&(s->mapping), index);
2241    }
2242    if (index >= s->mapping.next || mapping->begin > begin) {
2243        mapping = array_insert(&(s->mapping), index, 1);
2244        mapping->path = NULL;
2245        adjust_mapping_indices(s, index, +1);
2246    }
2247
2248    mapping->begin = begin;
2249    mapping->end = end;
2250
2251DLOG(mapping_t* next_mapping;
2252assert(index + 1 >= s->mapping.next ||
2253((next_mapping = array_get(&(s->mapping), index + 1)) &&
2254 next_mapping->begin >= end)));
2255
2256    if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
2257        s->current_mapping = array_get(&(s->mapping),
2258                s->current_mapping - first_mapping);
2259
2260    return mapping;
2261}
2262
2263static int remove_mapping(BDRVVVFATState* s, int mapping_index)
2264{
2265    mapping_t* mapping = array_get(&(s->mapping), mapping_index);
2266    mapping_t* first_mapping = array_get(&(s->mapping), 0);
2267
2268    /* free mapping */
2269    if (mapping->first_mapping_index < 0) {
2270        g_free(mapping->path);
2271    }
2272
2273    /* remove from s->mapping */
2274    array_remove(&(s->mapping), mapping_index);
2275
2276    /* adjust all references to mappings */
2277    adjust_mapping_indices(s, mapping_index, -1);
2278
2279    if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
2280        s->current_mapping = array_get(&(s->mapping),
2281                s->current_mapping - first_mapping);
2282
2283    return 0;
2284}
2285
2286static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
2287{
2288    int i;
2289    for (i = 0; i < s->mapping.next; i++) {
2290        mapping_t* mapping = array_get(&(s->mapping), i);
2291        if (mapping->dir_index >= offset)
2292            mapping->dir_index += adjust;
2293        if ((mapping->mode & MODE_DIRECTORY) &&
2294                mapping->info.dir.first_dir_index >= offset)
2295            mapping->info.dir.first_dir_index += adjust;
2296    }
2297}
2298
2299static direntry_t* insert_direntries(BDRVVVFATState* s,
2300        int dir_index, int count)
2301{
2302    /*
2303     * make room in s->directory,
2304     * adjust_dirindices
2305     */
2306    direntry_t* result = array_insert(&(s->directory), dir_index, count);
2307    if (result == NULL)
2308        return NULL;
2309    adjust_dirindices(s, dir_index, count);
2310    return result;
2311}
2312
2313static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
2314{
2315    int ret = array_remove_slice(&(s->directory), dir_index, count);
2316    if (ret)
2317        return ret;
2318    adjust_dirindices(s, dir_index, -count);
2319    return 0;
2320}
2321
2322/*
2323 * Adapt the mappings of the cluster chain starting at first cluster
2324 * (i.e. if a file starts at first_cluster, the chain is followed according
2325 * to the modified fat, and the corresponding entries in s->mapping are
2326 * adjusted)
2327 */
2328static int commit_mappings(BDRVVVFATState* s,
2329        uint32_t first_cluster, int dir_index)
2330{
2331    mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
2332    direntry_t* direntry = array_get(&(s->directory), dir_index);
2333    uint32_t cluster = first_cluster;
2334
2335    vvfat_close_current_file(s);
2336
2337    assert(mapping);
2338    assert(mapping->begin == first_cluster);
2339    mapping->first_mapping_index = -1;
2340    mapping->dir_index = dir_index;
2341    mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
2342        MODE_DIRECTORY : MODE_NORMAL;
2343
2344    while (!fat_eof(s, cluster)) {
2345        uint32_t c, c1;
2346
2347        for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
2348                c = c1, c1 = modified_fat_get(s, c1));
2349
2350        c++;
2351        if (c > mapping->end) {
2352            int index = array_index(&(s->mapping), mapping);
2353            int i, max_i = s->mapping.next - index;
2354            for (i = 1; i < max_i && mapping[i].begin < c; i++);
2355            while (--i > 0)
2356                remove_mapping(s, index + 1);
2357        }
2358        assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
2359                || mapping[1].begin >= c);
2360        mapping->end = c;
2361
2362        if (!fat_eof(s, c1)) {
2363            int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
2364            mapping_t* next_mapping = i >= s->mapping.next ? NULL :
2365                array_get(&(s->mapping), i);
2366
2367            if (next_mapping == NULL || next_mapping->begin > c1) {
2368                int i1 = array_index(&(s->mapping), mapping);
2369
2370                next_mapping = insert_mapping(s, c1, c1+1);
2371
2372                if (c1 < c)
2373                    i1++;
2374                mapping = array_get(&(s->mapping), i1);
2375            }
2376
2377            next_mapping->dir_index = mapping->dir_index;
2378            next_mapping->first_mapping_index =
2379                mapping->first_mapping_index < 0 ?
2380                array_index(&(s->mapping), mapping) :
2381                mapping->first_mapping_index;
2382            next_mapping->path = mapping->path;
2383            next_mapping->mode = mapping->mode;
2384            next_mapping->read_only = mapping->read_only;
2385            if (mapping->mode & MODE_DIRECTORY) {
2386                next_mapping->info.dir.parent_mapping_index =
2387                        mapping->info.dir.parent_mapping_index;
2388                next_mapping->info.dir.first_dir_index =
2389                        mapping->info.dir.first_dir_index +
2390                        0x10 * s->sectors_per_cluster *
2391                        (mapping->end - mapping->begin);
2392            } else
2393                next_mapping->info.file.offset = mapping->info.file.offset +
2394                        mapping->end - mapping->begin;
2395
2396            mapping = next_mapping;
2397        }
2398
2399        cluster = c1;
2400    }
2401
2402    return 0;
2403}
2404
2405static int commit_direntries(BDRVVVFATState* s,
2406        int dir_index, int parent_mapping_index)
2407{
2408    direntry_t* direntry = array_get(&(s->directory), dir_index);
2409    uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
2410    mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
2411    int factor = 0x10 * s->sectors_per_cluster;
2412    int old_cluster_count, new_cluster_count;
2413    int current_dir_index;
2414    int first_dir_index;
2415    int ret, i;
2416    uint32_t c;
2417
2418    assert(direntry);
2419    assert(mapping);
2420    assert(mapping->begin == first_cluster);
2421    assert(mapping->info.dir.first_dir_index < s->directory.next);
2422    assert(mapping->mode & MODE_DIRECTORY);
2423    assert(dir_index == 0 || is_directory(direntry));
2424
2425    DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n",
2426                 mapping->path, parent_mapping_index));
2427
2428    current_dir_index = mapping->info.dir.first_dir_index;
2429    first_dir_index = current_dir_index;
2430    mapping->info.dir.parent_mapping_index = parent_mapping_index;
2431
2432    if (first_cluster == 0) {
2433        old_cluster_count = new_cluster_count =
2434            s->last_cluster_of_root_directory;
2435    } else {
2436        for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2437                c = fat_get(s, c))
2438            old_cluster_count++;
2439
2440        for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2441                c = modified_fat_get(s, c))
2442            new_cluster_count++;
2443    }
2444
2445    if (new_cluster_count > old_cluster_count) {
2446        if (insert_direntries(s,
2447                current_dir_index + factor * old_cluster_count,
2448                factor * (new_cluster_count - old_cluster_count)) == NULL)
2449            return -1;
2450    } else if (new_cluster_count < old_cluster_count)
2451        remove_direntries(s,
2452                current_dir_index + factor * new_cluster_count,
2453                factor * (old_cluster_count - new_cluster_count));
2454
2455    for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
2456        direntry_t *first_direntry;
2457        void* direntry = array_get(&(s->directory), current_dir_index);
2458        int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
2459                s->sectors_per_cluster);
2460        if (ret)
2461            return ret;
2462
2463        /* The first directory entry on the filesystem is the volume name */
2464        first_direntry = (direntry_t*) s->directory.pointer;
2465        assert(!memcmp(first_direntry->name, s->volume_label, 11));
2466
2467        current_dir_index += factor;
2468    }
2469
2470    ret = commit_mappings(s, first_cluster, dir_index);
2471    if (ret)
2472        return ret;
2473
2474    /* recurse */
2475    for (i = 0; i < factor * new_cluster_count; i++) {
2476        direntry = array_get(&(s->directory), first_dir_index + i);
2477        if (is_directory(direntry) && !is_dot(direntry)) {
2478            mapping = find_mapping_for_cluster(s, first_cluster);
2479            if (mapping == NULL) {
2480                return -1;
2481            }
2482            assert(mapping->mode & MODE_DIRECTORY);
2483            ret = commit_direntries(s, first_dir_index + i,
2484                array_index(&(s->mapping), mapping));
2485            if (ret)
2486                return ret;
2487        }
2488    }
2489
2490    return 0;
2491}
2492
2493/* commit one file (adjust contents, adjust mapping),
2494   return first_mapping_index */
2495static int commit_one_file(BDRVVVFATState* s,
2496        int dir_index, uint32_t offset)
2497{
2498    direntry_t* direntry = array_get(&(s->directory), dir_index);
2499    uint32_t c = begin_of_direntry(direntry);
2500    uint32_t first_cluster = c;
2501    mapping_t* mapping = find_mapping_for_cluster(s, c);
2502    uint32_t size = filesize_of_direntry(direntry);
2503    char *cluster;
2504    uint32_t i;
2505    int fd = 0;
2506
2507    assert(offset < size);
2508    assert((offset % s->cluster_size) == 0);
2509
2510    if (mapping == NULL) {
2511        return -1;
2512    }
2513
2514    for (i = s->cluster_size; i < offset; i += s->cluster_size)
2515        c = modified_fat_get(s, c);
2516
2517    fd = qemu_open_old(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
2518    if (fd < 0) {
2519        fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
2520                strerror(errno), errno);
2521        return fd;
2522    }
2523    if (offset > 0) {
2524        if (lseek(fd, offset, SEEK_SET) != offset) {
2525            qemu_close(fd);
2526            return -3;
2527        }
2528    }
2529
2530    cluster = g_malloc(s->cluster_size);
2531
2532    while (offset < size) {
2533        uint32_t c1;
2534        int rest_size = (size - offset > s->cluster_size ?
2535                s->cluster_size : size - offset);
2536        int ret;
2537
2538        c1 = modified_fat_get(s, c);
2539
2540        assert((size - offset == 0 && fat_eof(s, c)) ||
2541                (size > offset && c >=2 && !fat_eof(s, c)));
2542
2543        ret = vvfat_read(s->bs, cluster2sector(s, c),
2544            (uint8_t*)cluster, DIV_ROUND_UP(rest_size, 0x200));
2545
2546        if (ret < 0) {
2547            qemu_close(fd);
2548            g_free(cluster);
2549            return ret;
2550        }
2551
2552        if (write(fd, cluster, rest_size) < 0) {
2553            qemu_close(fd);
2554            g_free(cluster);
2555            return -2;
2556        }
2557
2558        offset += rest_size;
2559        c = c1;
2560    }
2561
2562    if (ftruncate(fd, size)) {
2563        perror("ftruncate()");
2564        qemu_close(fd);
2565        g_free(cluster);
2566        return -4;
2567    }
2568    qemu_close(fd);
2569    g_free(cluster);
2570
2571    return commit_mappings(s, first_cluster, dir_index);
2572}
2573
2574#ifdef DEBUG
2575/* test, if all mappings point to valid direntries */
2576static void check1(BDRVVVFATState* s)
2577{
2578    int i;
2579    for (i = 0; i < s->mapping.next; i++) {
2580        mapping_t* mapping = array_get(&(s->mapping), i);
2581        if (mapping->mode & MODE_DELETED) {
2582            fprintf(stderr, "deleted\n");
2583            continue;
2584        }
2585        assert(mapping->dir_index < s->directory.next);
2586        direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
2587        assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
2588        if (mapping->mode & MODE_DIRECTORY) {
2589            assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
2590            assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
2591        }
2592    }
2593}
2594
2595/* test, if all direntries have mappings */
2596static void check2(BDRVVVFATState* s)
2597{
2598    int i;
2599    int first_mapping = -1;
2600
2601    for (i = 0; i < s->directory.next; i++) {
2602        direntry_t* direntry = array_get(&(s->directory), i);
2603
2604        if (is_short_name(direntry) && begin_of_direntry(direntry)) {
2605            mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
2606            assert(mapping);
2607            assert(mapping->dir_index == i || is_dot(direntry));
2608            assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
2609        }
2610
2611        if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
2612            /* cluster start */
2613            int j, count = 0;
2614
2615            for (j = 0; j < s->mapping.next; j++) {
2616                mapping_t* mapping = array_get(&(s->mapping), j);
2617                if (mapping->mode & MODE_DELETED)
2618                    continue;
2619                if (mapping->mode & MODE_DIRECTORY) {
2620                    if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
2621                        assert(++count == 1);
2622                        if (mapping->first_mapping_index == -1)
2623                            first_mapping = array_index(&(s->mapping), mapping);
2624                        else
2625                            assert(first_mapping == mapping->first_mapping_index);
2626                        if (mapping->info.dir.parent_mapping_index < 0)
2627                            assert(j == 0);
2628                        else {
2629                            mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
2630                            assert(parent->mode & MODE_DIRECTORY);
2631                            assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
2632                        }
2633                    }
2634                }
2635            }
2636            if (count == 0)
2637                first_mapping = -1;
2638        }
2639    }
2640}
2641#endif
2642
2643static int handle_renames_and_mkdirs(BDRVVVFATState* s)
2644{
2645    int i;
2646
2647#ifdef DEBUG
2648    fprintf(stderr, "handle_renames\n");
2649    for (i = 0; i < s->commits.next; i++) {
2650        commit_t* commit = array_get(&(s->commits), i);
2651        fprintf(stderr, "%d, %s (%u, %d)\n", i,
2652                commit->path ? commit->path : "(null)",
2653                commit->param.rename.cluster, commit->action);
2654    }
2655#endif
2656
2657    for (i = 0; i < s->commits.next;) {
2658        commit_t* commit = array_get(&(s->commits), i);
2659        if (commit->action == ACTION_RENAME) {
2660            mapping_t* mapping = find_mapping_for_cluster(s,
2661                    commit->param.rename.cluster);
2662            char *old_path;
2663
2664            if (mapping == NULL) {
2665                return -1;
2666            }
2667            old_path = mapping->path;
2668            assert(commit->path);
2669            mapping->path = commit->path;
2670            if (rename(old_path, mapping->path))
2671                return -2;
2672
2673            if (mapping->mode & MODE_DIRECTORY) {
2674                int l1 = strlen(mapping->path);
2675                int l2 = strlen(old_path);
2676                int diff = l1 - l2;
2677                direntry_t* direntry = array_get(&(s->directory),
2678                        mapping->info.dir.first_dir_index);
2679                uint32_t c = mapping->begin;
2680                int i = 0;
2681
2682                /* recurse */
2683                while (!fat_eof(s, c)) {
2684                    do {
2685                        direntry_t* d = direntry + i;
2686
2687                        if (is_file(d) || (is_directory(d) && !is_dot(d))) {
2688                            int l;
2689                            char *new_path;
2690                            mapping_t* m = find_mapping_for_cluster(s,
2691                                    begin_of_direntry(d));
2692                            if (m == NULL) {
2693                                return -1;
2694                            }
2695                            l = strlen(m->path);
2696                            new_path = g_malloc(l + diff + 1);
2697
2698                            assert(!strncmp(m->path, mapping->path, l2));
2699
2700                            pstrcpy(new_path, l + diff + 1, mapping->path);
2701                            pstrcpy(new_path + l1, l + diff + 1 - l1,
2702                                    m->path + l2);
2703
2704                            schedule_rename(s, m->begin, new_path);
2705                        }
2706                        i++;
2707                    } while((i % (0x10 * s->sectors_per_cluster)) != 0);
2708                    c = fat_get(s, c);
2709                }
2710            }
2711
2712            g_free(old_path);
2713            array_remove(&(s->commits), i);
2714            continue;
2715        } else if (commit->action == ACTION_MKDIR) {
2716            mapping_t* mapping;
2717            int j, parent_path_len;
2718
2719#ifdef __MINGW32__
2720            if (mkdir(commit->path))
2721                return -5;
2722#else
2723            if (mkdir(commit->path, 0755))
2724                return -5;
2725#endif
2726
2727            mapping = insert_mapping(s, commit->param.mkdir.cluster,
2728                    commit->param.mkdir.cluster + 1);
2729            if (mapping == NULL)
2730                return -6;
2731
2732            mapping->mode = MODE_DIRECTORY;
2733            mapping->read_only = 0;
2734            mapping->path = commit->path;
2735            j = s->directory.next;
2736            assert(j);
2737            insert_direntries(s, s->directory.next,
2738                    0x10 * s->sectors_per_cluster);
2739            mapping->info.dir.first_dir_index = j;
2740
2741            parent_path_len = strlen(commit->path)
2742                - strlen(get_basename(commit->path)) - 1;
2743            for (j = 0; j < s->mapping.next; j++) {
2744                mapping_t* m = array_get(&(s->mapping), j);
2745                if (m->first_mapping_index < 0 && m != mapping &&
2746                        !strncmp(m->path, mapping->path, parent_path_len) &&
2747                        strlen(m->path) == parent_path_len)
2748                    break;
2749            }
2750            assert(j < s->mapping.next);
2751            mapping->info.dir.parent_mapping_index = j;
2752
2753            array_remove(&(s->commits), i);
2754            continue;
2755        }
2756
2757        i++;
2758    }
2759    return 0;
2760}
2761
2762/*
2763 * TODO: make sure that the short name is not matching *another* file
2764 */
2765static int handle_commits(BDRVVVFATState* s)
2766{
2767    int i, fail = 0;
2768
2769    vvfat_close_current_file(s);
2770
2771    for (i = 0; !fail && i < s->commits.next; i++) {
2772        commit_t* commit = array_get(&(s->commits), i);
2773        switch(commit->action) {
2774        case ACTION_RENAME: case ACTION_MKDIR:
2775            abort();
2776            fail = -2;
2777            break;
2778        case ACTION_WRITEOUT: {
2779#ifndef NDEBUG
2780            /* these variables are only used by assert() below */
2781            direntry_t* entry = array_get(&(s->directory),
2782                    commit->param.writeout.dir_index);
2783            uint32_t begin = begin_of_direntry(entry);
2784            mapping_t* mapping = find_mapping_for_cluster(s, begin);
2785#endif
2786
2787            assert(mapping);
2788            assert(mapping->begin == begin);
2789            assert(commit->path == NULL);
2790
2791            if (commit_one_file(s, commit->param.writeout.dir_index,
2792                        commit->param.writeout.modified_offset))
2793                fail = -3;
2794
2795            break;
2796        }
2797        case ACTION_NEW_FILE: {
2798            int begin = commit->param.new_file.first_cluster;
2799            mapping_t* mapping = find_mapping_for_cluster(s, begin);
2800            direntry_t* entry;
2801            int i;
2802
2803            /* find direntry */
2804            for (i = 0; i < s->directory.next; i++) {
2805                entry = array_get(&(s->directory), i);
2806                if (is_file(entry) && begin_of_direntry(entry) == begin)
2807                    break;
2808            }
2809
2810            if (i >= s->directory.next) {
2811                fail = -6;
2812                continue;
2813            }
2814
2815            /* make sure there exists an initial mapping */
2816            if (mapping && mapping->begin != begin) {
2817                mapping->end = begin;
2818                mapping = NULL;
2819            }
2820            if (mapping == NULL) {
2821                mapping = insert_mapping(s, begin, begin+1);
2822            }
2823            /* most members will be fixed in commit_mappings() */
2824            assert(commit->path);
2825            mapping->path = commit->path;
2826            mapping->read_only = 0;
2827            mapping->mode = MODE_NORMAL;
2828            mapping->info.file.offset = 0;
2829
2830            if (commit_one_file(s, i, 0))
2831                fail = -7;
2832
2833            break;
2834        }
2835        default:
2836            abort();
2837        }
2838    }
2839    if (i > 0 && array_remove_slice(&(s->commits), 0, i))
2840        return -1;
2841    return fail;
2842}
2843
2844static int handle_deletes(BDRVVVFATState* s)
2845{
2846    int i, deferred = 1, deleted = 1;
2847
2848    /* delete files corresponding to mappings marked as deleted */
2849    /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
2850    while (deferred && deleted) {
2851        deferred = 0;
2852        deleted = 0;
2853
2854        for (i = 1; i < s->mapping.next; i++) {
2855            mapping_t* mapping = array_get(&(s->mapping), i);
2856            if (mapping->mode & MODE_DELETED) {
2857                direntry_t* entry = array_get(&(s->directory),
2858                        mapping->dir_index);
2859
2860                if (is_free(entry)) {
2861                    /* remove file/directory */
2862                    if (mapping->mode & MODE_DIRECTORY) {
2863                        int j, next_dir_index = s->directory.next,
2864                        first_dir_index = mapping->info.dir.first_dir_index;
2865
2866                        if (rmdir(mapping->path) < 0) {
2867                            if (errno == ENOTEMPTY) {
2868                                deferred++;
2869                                continue;
2870                            } else
2871                                return -5;
2872                        }
2873
2874                        for (j = 1; j < s->mapping.next; j++) {
2875                            mapping_t* m = array_get(&(s->mapping), j);
2876                            if (m->mode & MODE_DIRECTORY &&
2877                                    m->info.dir.first_dir_index >
2878                                    first_dir_index &&
2879                                    m->info.dir.first_dir_index <
2880                                    next_dir_index)
2881                                next_dir_index =
2882                                    m->info.dir.first_dir_index;
2883                        }
2884                        remove_direntries(s, first_dir_index,
2885                                next_dir_index - first_dir_index);
2886
2887                        deleted++;
2888                    }
2889                } else {
2890                    if (unlink(mapping->path))
2891                        return -4;
2892                    deleted++;
2893                }
2894                DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
2895                remove_mapping(s, i);
2896            }
2897        }
2898    }
2899
2900    return 0;
2901}
2902
2903/*
2904 * synchronize mapping with new state:
2905 *
2906 * - copy FAT (with bdrv_pread)
2907 * - mark all filenames corresponding to mappings as deleted
2908 * - recurse direntries from root (using bs->bdrv_pread)
2909 * - delete files corresponding to mappings marked as deleted
2910 */
2911static int do_commit(BDRVVVFATState* s)
2912{
2913    int ret = 0;
2914
2915    /* the real meat are the commits. Nothing to do? Move along! */
2916    if (s->commits.next == 0)
2917        return 0;
2918
2919    vvfat_close_current_file(s);
2920
2921    ret = handle_renames_and_mkdirs(s);
2922    if (ret) {
2923        fprintf(stderr, "Error handling renames (%d)\n", ret);
2924        abort();
2925        return ret;
2926    }
2927
2928    /* copy FAT (with bdrv_pread) */
2929    memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
2930
2931    /* recurse direntries from root (using bs->bdrv_pread) */
2932    ret = commit_direntries(s, 0, -1);
2933    if (ret) {
2934        fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
2935        abort();
2936        return ret;
2937    }
2938
2939    ret = handle_commits(s);
2940    if (ret) {
2941        fprintf(stderr, "Error handling commits (%d)\n", ret);
2942        abort();
2943        return ret;
2944    }
2945
2946    ret = handle_deletes(s);
2947    if (ret) {
2948        fprintf(stderr, "Error deleting\n");
2949        abort();
2950        return ret;
2951    }
2952
2953    bdrv_make_empty(s->qcow, NULL);
2954
2955    memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
2956
2957DLOG(checkpoint());
2958    return 0;
2959}
2960
2961static int try_commit(BDRVVVFATState* s)
2962{
2963    vvfat_close_current_file(s);
2964DLOG(checkpoint());
2965    if(!is_consistent(s))
2966        return -1;
2967    return do_commit(s);
2968}
2969
2970static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
2971                    const uint8_t *buf, int nb_sectors)
2972{
2973    BDRVVVFATState *s = bs->opaque;
2974    int i, ret;
2975
2976DLOG(checkpoint());
2977
2978    /* Check if we're operating in read-only mode */
2979    if (s->qcow == NULL) {
2980        return -EACCES;
2981    }
2982
2983    vvfat_close_current_file(s);
2984
2985    /*
2986     * Some sanity checks:
2987     * - do not allow writing to the boot sector
2988     */
2989
2990    if (sector_num < s->offset_to_fat)
2991        return -1;
2992
2993    for (i = sector2cluster(s, sector_num);
2994            i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
2995        mapping_t* mapping = find_mapping_for_cluster(s, i);
2996        if (mapping) {
2997            if (mapping->read_only) {
2998                fprintf(stderr, "Tried to write to write-protected file %s\n",
2999                        mapping->path);
3000                return -1;
3001            }
3002
3003            if (mapping->mode & MODE_DIRECTORY) {
3004                int begin = cluster2sector(s, i);
3005                int end = begin + s->sectors_per_cluster, k;
3006                int dir_index;
3007                const direntry_t* direntries;
3008                long_file_name lfn;
3009
3010                lfn_init(&lfn);
3011
3012                if (begin < sector_num)
3013                    begin = sector_num;
3014                if (end > sector_num + nb_sectors)
3015                    end = sector_num + nb_sectors;
3016                dir_index  = mapping->dir_index +
3017                    0x10 * (begin - mapping->begin * s->sectors_per_cluster);
3018                direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
3019
3020                for (k = 0; k < (end - begin) * 0x10; k++) {
3021                    /* no access to the direntry of a read-only file */
3022                    if (is_short_name(direntries + k) &&
3023                            (direntries[k].attributes & 1)) {
3024                        if (memcmp(direntries + k,
3025                                    array_get(&(s->directory), dir_index + k),
3026                                    sizeof(direntry_t))) {
3027                            warn_report("tried to write to write-protected "
3028                                        "file");
3029                            return -1;
3030                        }
3031                    }
3032                }
3033            }
3034            i = mapping->end;
3035        } else
3036            i++;
3037    }
3038
3039    /*
3040     * Use qcow backend. Commit later.
3041     */
3042DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
3043    ret = bdrv_pwrite(s->qcow, sector_num * BDRV_SECTOR_SIZE, buf,
3044                      nb_sectors * BDRV_SECTOR_SIZE);
3045    if (ret < 0) {
3046        fprintf(stderr, "Error writing to qcow backend\n");
3047        return ret;
3048    }
3049
3050    for (i = sector2cluster(s, sector_num);
3051            i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
3052        if (i >= 0)
3053            s->used_clusters[i] |= USED_ALLOCATED;
3054
3055DLOG(checkpoint());
3056    /* TODO: add timeout */
3057    try_commit(s);
3058
3059DLOG(checkpoint());
3060    return 0;
3061}
3062
3063static int coroutine_fn
3064vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
3065                 QEMUIOVector *qiov, int flags)
3066{
3067    int ret;
3068    BDRVVVFATState *s = bs->opaque;
3069    uint64_t sector_num = offset >> BDRV_SECTOR_BITS;
3070    int nb_sectors = bytes >> BDRV_SECTOR_BITS;
3071    void *buf;
3072
3073    assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
3074    assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
3075
3076    buf = g_try_malloc(bytes);
3077    if (bytes && buf == NULL) {
3078        return -ENOMEM;
3079    }
3080    qemu_iovec_to_buf(qiov, 0, buf, bytes);
3081
3082    qemu_co_mutex_lock(&s->lock);
3083    ret = vvfat_write(bs, sector_num, buf, nb_sectors);
3084    qemu_co_mutex_unlock(&s->lock);
3085
3086    g_free(buf);
3087
3088    return ret;
3089}
3090
3091static int coroutine_fn vvfat_co_block_status(BlockDriverState *bs,
3092                                              bool want_zero, int64_t offset,
3093                                              int64_t bytes, int64_t *n,
3094                                              int64_t *map,
3095                                              BlockDriverState **file)
3096{
3097    *n = bytes;
3098    return BDRV_BLOCK_DATA;
3099}
3100
3101static void vvfat_qcow_options(BdrvChildRole role, bool parent_is_format,
3102                               int *child_flags, QDict *child_options,
3103                               int parent_flags, QDict *parent_options)
3104{
3105    qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
3106    qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
3107    qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
3108}
3109
3110static BdrvChildClass child_vvfat_qcow;
3111
3112static int enable_write_target(BlockDriverState *bs, Error **errp)
3113{
3114    BDRVVVFATState *s = bs->opaque;
3115    BlockDriver *bdrv_qcow = NULL;
3116    QemuOpts *opts = NULL;
3117    int ret;
3118    int size = sector2cluster(s, s->sector_count);
3119    QDict *options;
3120
3121    s->used_clusters = calloc(size, 1);
3122
3123    array_init(&(s->commits), sizeof(commit_t));
3124
3125    s->qcow_filename = g_malloc(PATH_MAX);
3126    ret = get_tmp_filename(s->qcow_filename, PATH_MAX);
3127    if (ret < 0) {
3128        error_setg_errno(errp, -ret, "can't create temporary file");
3129        goto err;
3130    }
3131
3132    bdrv_qcow = bdrv_find_format("qcow");
3133    if (!bdrv_qcow) {
3134        error_setg(errp, "Failed to locate qcow driver");
3135        ret = -ENOENT;
3136        goto err;
3137    }
3138
3139    opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
3140    qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512,
3141                        &error_abort);
3142    qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:", &error_abort);
3143
3144    ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts, errp);
3145    qemu_opts_del(opts);
3146    if (ret < 0) {
3147        goto err;
3148    }
3149
3150    options = qdict_new();
3151    qdict_put_str(options, "write-target.driver", "qcow");
3152    s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs,
3153                              &child_vvfat_qcow,
3154                              BDRV_CHILD_DATA | BDRV_CHILD_METADATA,
3155                              false, errp);
3156    qobject_unref(options);
3157    if (!s->qcow) {
3158        ret = -EINVAL;
3159        goto err;
3160    }
3161
3162#ifndef _WIN32
3163    unlink(s->qcow_filename);
3164#endif
3165
3166    return 0;
3167
3168err:
3169    g_free(s->qcow_filename);
3170    s->qcow_filename = NULL;
3171    return ret;
3172}
3173
3174static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
3175                             BdrvChildRole role,
3176                             BlockReopenQueue *reopen_queue,
3177                             uint64_t perm, uint64_t shared,
3178                             uint64_t *nperm, uint64_t *nshared)
3179{
3180    assert(role & BDRV_CHILD_DATA);
3181    /* This is a private node, nobody should try to attach to it */
3182    *nperm = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE;
3183    *nshared = BLK_PERM_WRITE_UNCHANGED;
3184}
3185
3186static void vvfat_close(BlockDriverState *bs)
3187{
3188    BDRVVVFATState *s = bs->opaque;
3189
3190    vvfat_close_current_file(s);
3191    array_free(&(s->fat));
3192    array_free(&(s->directory));
3193    array_free(&(s->mapping));
3194    g_free(s->cluster_buffer);
3195
3196    if (s->qcow) {
3197        migrate_del_blocker(s->migration_blocker);
3198        error_free(s->migration_blocker);
3199    }
3200}
3201
3202static const char *const vvfat_strong_runtime_opts[] = {
3203    "dir",
3204    "fat-type",
3205    "floppy",
3206    "label",
3207    "rw",
3208
3209    NULL
3210};
3211
3212static BlockDriver bdrv_vvfat = {
3213    .format_name            = "vvfat",
3214    .protocol_name          = "fat",
3215    .instance_size          = sizeof(BDRVVVFATState),
3216
3217    .bdrv_parse_filename    = vvfat_parse_filename,
3218    .bdrv_file_open         = vvfat_open,
3219    .bdrv_refresh_limits    = vvfat_refresh_limits,
3220    .bdrv_close             = vvfat_close,
3221    .bdrv_child_perm        = vvfat_child_perm,
3222
3223    .bdrv_co_preadv         = vvfat_co_preadv,
3224    .bdrv_co_pwritev        = vvfat_co_pwritev,
3225    .bdrv_co_block_status   = vvfat_co_block_status,
3226
3227    .strong_runtime_opts    = vvfat_strong_runtime_opts,
3228};
3229
3230static void bdrv_vvfat_init(void)
3231{
3232    child_vvfat_qcow = child_of_bds;
3233    child_vvfat_qcow.inherit_options = vvfat_qcow_options;
3234    bdrv_register(&bdrv_vvfat);
3235}
3236
3237block_init(bdrv_vvfat_init);
3238
3239#ifdef DEBUG
3240static void checkpoint(void)
3241{
3242    assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
3243    check1(vvv);
3244    check2(vvv);
3245    assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
3246}
3247#endif
3248