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