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