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