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