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