/* vim:set shiftwidth=4 ts=4: */
/*
 * QEMU Block driver for virtual VFAT (shadows a local directory)
 *
 * Copyright (c) 2004,2005 Johannes E. Schindelin
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <sys/stat.h>
#include <dirent.h>
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/module.h"
#include "migration/migration.h"
#include "qapi/qmp/qint.h"
#include "qapi/qmp/qbool.h"

#ifndef S_IWGRP
#define S_IWGRP 0
#endif
#ifndef S_IWOTH
#define S_IWOTH 0
#endif

/* TODO: add ":bootsector=blabla.img:" */
/* LATER TODO: add automatic boot sector generation from
    BOOTEASY.ASM and Ranish Partition Manager
    Note that DOS assumes the system files to be the first files in the
    file system (test if the boot sector still relies on that fact)! */
/* MAYBE TODO: write block-visofs.c */
/* TODO: call try_commit() only after a timeout */

/* #define DEBUG */

#ifdef DEBUG

#define DLOG(a) a

#undef stderr
#define stderr STDERR
FILE* stderr = NULL;

static void checkpoint(void);

#ifdef __MINGW32__
void nonono(const char* file, int line, const char* msg) {
    fprintf(stderr, "Nonono! %s:%d %s\n", file, line, msg);
    exit(-5);
}
#undef assert
#define assert(a) do {if (!(a)) nonono(__FILE__, __LINE__, #a);}while(0)
#endif

#else

#define DLOG(a)

#endif

/* dynamic array functions */
typedef struct array_t {
    char* pointer;
    unsigned int size,next,item_size;
} array_t;

static inline void array_init(array_t* array,unsigned int item_size)
{
    array->pointer = NULL;
    array->size=0;
    array->next=0;
    array->item_size=item_size;
}

static inline void array_free(array_t* array)
{
    g_free(array->pointer);
    array->size=array->next=0;
}

/* does not automatically grow */
static inline void* array_get(array_t* array,unsigned int index) {
    assert(index < array->next);
    return array->pointer + index * array->item_size;
}

static inline int array_ensure_allocated(array_t* array, int index)
{
    if((index + 1) * array->item_size > array->size) {
	int new_size = (index + 32) * array->item_size;
	array->pointer = g_realloc(array->pointer, new_size);
	if (!array->pointer)
	    return -1;
	array->size = new_size;
	array->next = index + 1;
    }

    return 0;
}

static inline void* array_get_next(array_t* array) {
    unsigned int next = array->next;
    void* result;

    if (array_ensure_allocated(array, next) < 0)
	return NULL;

    array->next = next + 1;
    result = array_get(array, next);

    return result;
}

static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
    if((array->next+count)*array->item_size>array->size) {
	int increment=count*array->item_size;
	array->pointer=g_realloc(array->pointer,array->size+increment);
	if(!array->pointer)
            return NULL;
	array->size+=increment;
    }
    memmove(array->pointer+(index+count)*array->item_size,
		array->pointer+index*array->item_size,
		(array->next-index)*array->item_size);
    array->next+=count;
    return array->pointer+index*array->item_size;
}

/* this performs a "roll", so that the element which was at index_from becomes
 * index_to, but the order of all other elements is preserved. */
static inline int array_roll(array_t* array,int index_to,int index_from,int count)
{
    char* buf;
    char* from;
    char* to;
    int is;

    if(!array ||
	    index_to<0 || index_to>=array->next ||
	    index_from<0 || index_from>=array->next)
	return -1;

    if(index_to==index_from)
	return 0;

    is=array->item_size;
    from=array->pointer+index_from*is;
    to=array->pointer+index_to*is;
    buf=g_malloc(is*count);
    memcpy(buf,from,is*count);

    if(index_to<index_from)
	memmove(to+is*count,to,from-to);
    else
	memmove(from,from+is*count,to-from);

    memcpy(to,buf,is*count);

    g_free(buf);

    return 0;
}

static inline int array_remove_slice(array_t* array,int index, int count)
{
    assert(index >=0);
    assert(count > 0);
    assert(index + count <= array->next);
    if(array_roll(array,array->next-1,index,count))
	return -1;
    array->next -= count;
    return 0;
}

static int array_remove(array_t* array,int index)
{
    return array_remove_slice(array, index, 1);
}

/* return the index for a given member */
static int array_index(array_t* array, void* pointer)
{
    size_t offset = (char*)pointer - array->pointer;
    assert((offset % array->item_size) == 0);
    assert(offset/array->item_size < array->next);
    return offset/array->item_size;
}

/* These structures are used to fake a disk and the VFAT filesystem.
 * For this reason we need to use QEMU_PACKED. */

typedef struct bootsector_t {
    uint8_t jump[3];
    uint8_t name[8];
    uint16_t sector_size;
    uint8_t sectors_per_cluster;
    uint16_t reserved_sectors;
    uint8_t number_of_fats;
    uint16_t root_entries;
    uint16_t total_sectors16;
    uint8_t media_type;
    uint16_t sectors_per_fat;
    uint16_t sectors_per_track;
    uint16_t number_of_heads;
    uint32_t hidden_sectors;
    uint32_t total_sectors;
    union {
        struct {
	    uint8_t drive_number;
	    uint8_t current_head;
	    uint8_t signature;
	    uint32_t id;
	    uint8_t volume_label[11];
	} QEMU_PACKED fat16;
	struct {
	    uint32_t sectors_per_fat;
	    uint16_t flags;
	    uint8_t major,minor;
	    uint32_t first_cluster_of_root_directory;
	    uint16_t info_sector;
	    uint16_t backup_boot_sector;
	    uint16_t ignored;
	} QEMU_PACKED fat32;
    } u;
    uint8_t fat_type[8];
    uint8_t ignored[0x1c0];
    uint8_t magic[2];
} QEMU_PACKED bootsector_t;

typedef struct {
    uint8_t head;
    uint8_t sector;
    uint8_t cylinder;
} mbr_chs_t;

typedef struct partition_t {
    uint8_t attributes; /* 0x80 = bootable */
    mbr_chs_t start_CHS;
    uint8_t   fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xe = FAT16_LBA, 0xb = FAT32, 0xc = FAT32_LBA */
    mbr_chs_t end_CHS;
    uint32_t start_sector_long;
    uint32_t length_sector_long;
} QEMU_PACKED partition_t;

typedef struct mbr_t {
    uint8_t ignored[0x1b8];
    uint32_t nt_id;
    uint8_t ignored2[2];
    partition_t partition[4];
    uint8_t magic[2];
} QEMU_PACKED mbr_t;

typedef struct direntry_t {
    uint8_t name[8];
    uint8_t extension[3];
    uint8_t attributes;
    uint8_t reserved[2];
    uint16_t ctime;
    uint16_t cdate;
    uint16_t adate;
    uint16_t begin_hi;
    uint16_t mtime;
    uint16_t mdate;
    uint16_t begin;
    uint32_t size;
} QEMU_PACKED direntry_t;

/* this structure are used to transparently access the files */

typedef struct mapping_t {
    /* begin is the first cluster, end is the last+1 */
    uint32_t begin,end;
    /* as s->directory is growable, no pointer may be used here */
    unsigned int dir_index;
    /* the clusters of a file may be in any order; this points to the first */
    int first_mapping_index;
    union {
	/* offset is
	 * - the offset in the file (in clusters) for a file, or
	 * - the next cluster of the directory for a directory, and
	 * - the address of the buffer for a faked entry
	 */
	struct {
	    uint32_t offset;
	} file;
	struct {
	    int parent_mapping_index;
	    int first_dir_index;
	} dir;
    } info;
    /* path contains the full path, i.e. it always starts with s->path */
    char* path;

    enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
	MODE_DIRECTORY = 4, MODE_FAKED = 8,
	MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
    int read_only;
} mapping_t;

#ifdef DEBUG
static void print_direntry(const struct direntry_t*);
static void print_mapping(const struct mapping_t* mapping);
#endif

/* here begins the real VVFAT driver */

typedef struct BDRVVVFATState {
    CoMutex lock;
    BlockDriverState* bs; /* pointer to parent */
    unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
    unsigned char first_sectors[0x40*0x200];

    int fat_type; /* 16 or 32 */
    array_t fat,directory,mapping;

    unsigned int cluster_size;
    unsigned int sectors_per_cluster;
    unsigned int sectors_per_fat;
    unsigned int sectors_of_root_directory;
    uint32_t last_cluster_of_root_directory;
    unsigned int faked_sectors; /* how many sectors are faked before file data */
    uint32_t sector_count; /* total number of sectors of the partition */
    uint32_t cluster_count; /* total number of clusters of this partition */
    uint32_t max_fat_value;

    int current_fd;
    mapping_t* current_mapping;
    unsigned char* cluster; /* points to current cluster */
    unsigned char* cluster_buffer; /* points to a buffer to hold temp data */
    unsigned int current_cluster;

    /* write support */
    BlockDriverState* write_target;
    char* qcow_filename;
    BlockDriverState* qcow;
    void* fat2;
    char* used_clusters;
    array_t commits;
    const char* path;
    int downcase_short_names;

    Error *migration_blocker;
} BDRVVVFATState;

/* take the sector position spos and convert it to Cylinder/Head/Sector position
 * if the position is outside the specified geometry, fill maximum value for CHS
 * and return 1 to signal overflow.
 */
static int sector2CHS(mbr_chs_t *chs, int spos, int cyls, int heads, int secs)
{
    int head,sector;
    sector   = spos % secs;  spos /= secs;
    head     = spos % heads; spos /= heads;
    if (spos >= cyls) {
        /* Overflow,
        it happens if 32bit sector positions are used, while CHS is only 24bit.
        Windows/Dos is said to take 1023/255/63 as nonrepresentable CHS */
        chs->head     = 0xFF;
        chs->sector   = 0xFF;
        chs->cylinder = 0xFF;
        return 1;
    }
    chs->head     = (uint8_t)head;
    chs->sector   = (uint8_t)( (sector+1) | ((spos>>8)<<6) );
    chs->cylinder = (uint8_t)spos;
    return 0;
}

static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
{
    /* TODO: if the files mbr.img and bootsect.img exist, use them */
    mbr_t* real_mbr=(mbr_t*)s->first_sectors;
    partition_t* partition = &(real_mbr->partition[0]);
    int lba;

    memset(s->first_sectors,0,512);

    /* Win NT Disk Signature */
    real_mbr->nt_id= cpu_to_le32(0xbe1afdfa);

    partition->attributes=0x80; /* bootable */

    /* LBA is used when partition is outside the CHS geometry */
    lba  = sector2CHS(&partition->start_CHS, s->first_sectors_number - 1,
                     cyls, heads, secs);
    lba |= sector2CHS(&partition->end_CHS,   s->bs->total_sectors - 1,
                     cyls, heads, secs);

    /*LBA partitions are identified only by start/length_sector_long not by CHS*/
    partition->start_sector_long  = cpu_to_le32(s->first_sectors_number - 1);
    partition->length_sector_long = cpu_to_le32(s->bs->total_sectors
                                                - s->first_sectors_number + 1);

    /* FAT12/FAT16/FAT32 */
    /* DOS uses different types when partition is LBA,
       probably to prevent older versions from using CHS on them */
    partition->fs_type= s->fat_type==12 ? 0x1:
                        s->fat_type==16 ? (lba?0xe:0x06):
                         /*fat_tyoe==32*/ (lba?0xc:0x0b);

    real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
}

/* direntry functions */

/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */
static inline int short2long_name(char* dest,const char* src)
{
    int i;
    int len;
    for(i=0;i<129 && src[i];i++) {
        dest[2*i]=src[i];
	dest[2*i+1]=0;
    }
    len=2*i;
    dest[2*i]=dest[2*i+1]=0;
    for(i=2*i+2;(i%26);i++)
	dest[i]=0xff;
    return len;
}

static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename)
{
    char buffer[258];
    int length=short2long_name(buffer,filename),
        number_of_entries=(length+25)/26,i;
    direntry_t* entry;

    for(i=0;i<number_of_entries;i++) {
	entry=array_get_next(&(s->directory));
	entry->attributes=0xf;
	entry->reserved[0]=0;
	entry->begin=0;
	entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
    }
    for(i=0;i<26*number_of_entries;i++) {
	int offset=(i%26);
	if(offset<10) offset=1+offset;
	else if(offset<22) offset=14+offset-10;
	else offset=28+offset-22;
	entry=array_get(&(s->directory),s->directory.next-1-(i/26));
	entry->name[offset]=buffer[i];
    }
    return array_get(&(s->directory),s->directory.next-number_of_entries);
}

static char is_free(const direntry_t* direntry)
{
    return direntry->name[0]==0xe5 || direntry->name[0]==0x00;
}

static char is_volume_label(const direntry_t* direntry)
{
    return direntry->attributes == 0x28;
}

static char is_long_name(const direntry_t* direntry)
{
    return direntry->attributes == 0xf;
}

static char is_short_name(const direntry_t* direntry)
{
    return !is_volume_label(direntry) && !is_long_name(direntry)
	&& !is_free(direntry);
}

static char is_directory(const direntry_t* direntry)
{
    return direntry->attributes & 0x10 && direntry->name[0] != 0xe5;
}

static inline char is_dot(const direntry_t* direntry)
{
    return is_short_name(direntry) && direntry->name[0] == '.';
}

static char is_file(const direntry_t* direntry)
{
    return is_short_name(direntry) && !is_directory(direntry);
}

static inline uint32_t begin_of_direntry(const direntry_t* direntry)
{
    return le16_to_cpu(direntry->begin)|(le16_to_cpu(direntry->begin_hi)<<16);
}

static inline uint32_t filesize_of_direntry(const direntry_t* direntry)
{
    return le32_to_cpu(direntry->size);
}

static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
{
    direntry->begin = cpu_to_le16(begin & 0xffff);
    direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
}

/* fat functions */

static inline uint8_t fat_chksum(const direntry_t* entry)
{
    uint8_t chksum=0;
    int i;

    for(i=0;i<11;i++) {
        unsigned char c;

        c = (i < 8) ? entry->name[i] : entry->extension[i-8];
        chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0)) + c;
    }

    return chksum;
}

/* if return_time==0, this returns the fat_date, else the fat_time */
static uint16_t fat_datetime(time_t time,int return_time) {
    struct tm* t;
    struct tm t1;
    t = &t1;
    localtime_r(&time,t);
    if(return_time)
	return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
    return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
}

static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
{
    if(s->fat_type==32) {
	uint32_t* entry=array_get(&(s->fat),cluster);
	*entry=cpu_to_le32(value);
    } else if(s->fat_type==16) {
	uint16_t* entry=array_get(&(s->fat),cluster);
	*entry=cpu_to_le16(value&0xffff);
    } else {
	int offset = (cluster*3/2);
	unsigned char* p = array_get(&(s->fat), offset);
        switch (cluster&1) {
	case 0:
		p[0] = value&0xff;
		p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
		break;
	case 1:
		p[0] = (p[0]&0xf) | ((value&0xf)<<4);
		p[1] = (value>>4);
		break;
	}
    }
}

static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster)
{
    if(s->fat_type==32) {
	uint32_t* entry=array_get(&(s->fat),cluster);
	return le32_to_cpu(*entry);
    } else if(s->fat_type==16) {
	uint16_t* entry=array_get(&(s->fat),cluster);
	return le16_to_cpu(*entry);
    } else {
	const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
	return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
    }
}

static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry)
{
    if(fat_entry>s->max_fat_value-8)
	return -1;
    return 0;
}

static inline void init_fat(BDRVVVFATState* s)
{
    if (s->fat_type == 12) {
	array_init(&(s->fat),1);
	array_ensure_allocated(&(s->fat),
		s->sectors_per_fat * 0x200 * 3 / 2 - 1);
    } else {
	array_init(&(s->fat),(s->fat_type==32?4:2));
	array_ensure_allocated(&(s->fat),
		s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
    }
    memset(s->fat.pointer,0,s->fat.size);

    switch(s->fat_type) {
	case 12: s->max_fat_value=0xfff; break;
	case 16: s->max_fat_value=0xffff; break;
	case 32: s->max_fat_value=0x0fffffff; break;
	default: s->max_fat_value=0; /* error... */
    }

}

/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
	unsigned int directory_start, const char* filename, int is_dot)
{
    int i,j,long_index=s->directory.next;
    direntry_t* entry = NULL;
    direntry_t* entry_long = NULL;

    if(is_dot) {
	entry=array_get_next(&(s->directory));
	memset(entry->name,0x20,11);
	memcpy(entry->name,filename,strlen(filename));
	return entry;
    }

    entry_long=create_long_filename(s,filename);

    i = strlen(filename);
    for(j = i - 1; j>0  && filename[j]!='.';j--);
    if (j > 0)
	i = (j > 8 ? 8 : j);
    else if (i > 8)
	i = 8;

    entry=array_get_next(&(s->directory));
    memset(entry->name,0x20,11);
    memcpy(entry->name, filename, i);

    if(j > 0)
	for (i = 0; i < 3 && filename[j+1+i]; i++)
	    entry->extension[i] = filename[j+1+i];

    /* upcase & remove unwanted characters */
    for(i=10;i>=0;i--) {
	if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
	if(entry->name[i]<=' ' || entry->name[i]>0x7f
		|| strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
	    entry->name[i]='_';
        else if(entry->name[i]>='a' && entry->name[i]<='z')
            entry->name[i]+='A'-'a';
    }

    /* mangle duplicates */
    while(1) {
	direntry_t* entry1=array_get(&(s->directory),directory_start);
	int j;

	for(;entry1<entry;entry1++)
	    if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
		break; /* found dupe */
	if(entry1==entry) /* no dupe found */
	    break;

	/* use all 8 characters of name */
	if(entry->name[7]==' ') {
	    int j;
	    for(j=6;j>0 && entry->name[j]==' ';j--)
		entry->name[j]='~';
	}

	/* increment number */
	for(j=7;j>0 && entry->name[j]=='9';j--)
	    entry->name[j]='0';
	if(j>0) {
	    if(entry->name[j]<'0' || entry->name[j]>'9')
	        entry->name[j]='0';
	    else
	        entry->name[j]++;
	}
    }

    /* calculate checksum; propagate to long name */
    if(entry_long) {
        uint8_t chksum=fat_chksum(entry);

	/* calculate anew, because realloc could have taken place */
	entry_long=array_get(&(s->directory),long_index);
	while(entry_long<entry && is_long_name(entry_long)) {
	    entry_long->reserved[1]=chksum;
	    entry_long++;
	}
    }

    return entry;
}

/*
 * Read a directory. (the index of the corresponding mapping must be passed).
 */
static int read_directory(BDRVVVFATState* s, int mapping_index)
{
    mapping_t* mapping = array_get(&(s->mapping), mapping_index);
    direntry_t* direntry;
    const char* dirname = mapping->path;
    int first_cluster = mapping->begin;
    int parent_index = mapping->info.dir.parent_mapping_index;
    mapping_t* parent_mapping = (mapping_t*)
        (parent_index >= 0 ? array_get(&(s->mapping), parent_index) : NULL);
    int first_cluster_of_parent = parent_mapping ? parent_mapping->begin : -1;

    DIR* dir=opendir(dirname);
    struct dirent* entry;
    int i;

    assert(mapping->mode & MODE_DIRECTORY);

    if(!dir) {
	mapping->end = mapping->begin;
	return -1;
    }

    i = mapping->info.dir.first_dir_index =
	    first_cluster == 0 ? 0 : s->directory.next;

    /* actually read the directory, and allocate the mappings */
    while((entry=readdir(dir))) {
	unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
        char* buffer;
	direntry_t* direntry;
        struct stat st;
	int is_dot=!strcmp(entry->d_name,".");
	int is_dotdot=!strcmp(entry->d_name,"..");

	if(first_cluster == 0 && (is_dotdot || is_dot))
	    continue;

	buffer=(char*)g_malloc(length);
	snprintf(buffer,length,"%s/%s",dirname,entry->d_name);

	if(stat(buffer,&st)<0) {
            g_free(buffer);
            continue;
	}

	/* create directory entry for this file */
	direntry=create_short_and_long_name(s, i, entry->d_name,
		is_dot || is_dotdot);
	direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
	direntry->reserved[0]=direntry->reserved[1]=0;
	direntry->ctime=fat_datetime(st.st_ctime,1);
	direntry->cdate=fat_datetime(st.st_ctime,0);
	direntry->adate=fat_datetime(st.st_atime,0);
	direntry->begin_hi=0;
	direntry->mtime=fat_datetime(st.st_mtime,1);
	direntry->mdate=fat_datetime(st.st_mtime,0);
	if(is_dotdot)
	    set_begin_of_direntry(direntry, first_cluster_of_parent);
	else if(is_dot)
	    set_begin_of_direntry(direntry, first_cluster);
	else
	    direntry->begin=0; /* do that later */
        if (st.st_size > 0x7fffffff) {
	    fprintf(stderr, "File %s is larger than 2GB\n", buffer);
            g_free(buffer);
            closedir(dir);
	    return -2;
        }
	direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);

	/* create mapping for this file */
	if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
	    s->current_mapping=(mapping_t*)array_get_next(&(s->mapping));
	    s->current_mapping->begin=0;
	    s->current_mapping->end=st.st_size;
	    /*
	     * we get the direntry of the most recent direntry, which
	     * contains the short name and all the relevant information.
	     */
	    s->current_mapping->dir_index=s->directory.next-1;
	    s->current_mapping->first_mapping_index = -1;
	    if (S_ISDIR(st.st_mode)) {
		s->current_mapping->mode = MODE_DIRECTORY;
		s->current_mapping->info.dir.parent_mapping_index =
		    mapping_index;
	    } else {
		s->current_mapping->mode = MODE_UNDEFINED;
		s->current_mapping->info.file.offset = 0;
	    }
	    s->current_mapping->path=buffer;
	    s->current_mapping->read_only =
		(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
	}
    }
    closedir(dir);

    /* fill with zeroes up to the end of the cluster */
    while(s->directory.next%(0x10*s->sectors_per_cluster)) {
	direntry_t* direntry=array_get_next(&(s->directory));
	memset(direntry,0,sizeof(direntry_t));
    }

/* TODO: if there are more entries, bootsector has to be adjusted! */
#define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster)
    if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) {
	/* root directory */
	int cur = s->directory.next;
	array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
	s->directory.next = ROOT_ENTRIES;
	memset(array_get(&(s->directory), cur), 0,
		(ROOT_ENTRIES - cur) * sizeof(direntry_t));
    }

     /* reget the mapping, since s->mapping was possibly realloc()ed */
    mapping = (mapping_t*)array_get(&(s->mapping), mapping_index);
    first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
	* 0x20 / s->cluster_size;
    mapping->end = first_cluster;

    direntry = (direntry_t*)array_get(&(s->directory), mapping->dir_index);
    set_begin_of_direntry(direntry, mapping->begin);

    return 0;
}

static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
{
    return (sector_num-s->faked_sectors)/s->sectors_per_cluster;
}

static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
{
    return s->faked_sectors + s->sectors_per_cluster * cluster_num;
}

static int init_directories(BDRVVVFATState* s,
                            const char *dirname, int heads, int secs)
{
    bootsector_t* bootsector;
    mapping_t* mapping;
    unsigned int i;
    unsigned int cluster;

    memset(&(s->first_sectors[0]),0,0x40*0x200);

    s->cluster_size=s->sectors_per_cluster*0x200;
    s->cluster_buffer=g_malloc(s->cluster_size);

    /*
     * The formula: sc = spf+1+spf*spc*(512*8/fat_type),
     * where sc is sector_count,
     * spf is sectors_per_fat,
     * spc is sectors_per_clusters, and
     * fat_type = 12, 16 or 32.
     */
    i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
    s->sectors_per_fat=(s->sector_count+i)/i; /* round up */

    array_init(&(s->mapping),sizeof(mapping_t));
    array_init(&(s->directory),sizeof(direntry_t));

    /* add volume label */
    {
	direntry_t* entry=array_get_next(&(s->directory));
	entry->attributes=0x28; /* archive | volume label */
	memcpy(entry->name,"QEMU VVF",8);
	memcpy(entry->extension,"AT ",3);
    }

    /* Now build FAT, and write back information into directory */
    init_fat(s);

    s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;
    s->cluster_count=sector2cluster(s, s->sector_count);

    mapping = array_get_next(&(s->mapping));
    mapping->begin = 0;
    mapping->dir_index = 0;
    mapping->info.dir.parent_mapping_index = -1;
    mapping->first_mapping_index = -1;
    mapping->path = g_strdup(dirname);
    i = strlen(mapping->path);
    if (i > 0 && mapping->path[i - 1] == '/')
	mapping->path[i - 1] = '\0';
    mapping->mode = MODE_DIRECTORY;
    mapping->read_only = 0;
    s->path = mapping->path;

    for (i = 0, cluster = 0; i < s->mapping.next; i++) {
	/* MS-DOS expects the FAT to be 0 for the root directory
	 * (except for the media byte). */
	/* LATER TODO: still true for FAT32? */
	int fix_fat = (i != 0);
	mapping = array_get(&(s->mapping), i);

        if (mapping->mode & MODE_DIRECTORY) {
	    mapping->begin = cluster;
	    if(read_directory(s, i)) {
		fprintf(stderr, "Could not read directory %s\n",
			mapping->path);
		return -1;
	    }
	    mapping = array_get(&(s->mapping), i);
	} else {
	    assert(mapping->mode == MODE_UNDEFINED);
	    mapping->mode=MODE_NORMAL;
	    mapping->begin = cluster;
	    if (mapping->end > 0) {
		direntry_t* direntry = array_get(&(s->directory),
			mapping->dir_index);

		mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
		set_begin_of_direntry(direntry, mapping->begin);
	    } else {
		mapping->end = cluster + 1;
		fix_fat = 0;
	    }
	}

	assert(mapping->begin < mapping->end);

	/* next free cluster */
	cluster = mapping->end;

	if(cluster > s->cluster_count) {
	    fprintf(stderr,"Directory does not fit in FAT%d (capacity %.2f MB)\n",
		    s->fat_type, s->sector_count / 2000.0);
	    return -EINVAL;
	}

	/* fix fat for entry */
	if (fix_fat) {
	    int j;
	    for(j = mapping->begin; j < mapping->end - 1; j++)
		fat_set(s, j, j+1);
	    fat_set(s, mapping->end - 1, s->max_fat_value);
	}
    }

    mapping = array_get(&(s->mapping), 0);
    s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster;
    s->last_cluster_of_root_directory = mapping->end;

    /* the FAT signature */
    fat_set(s,0,s->max_fat_value);
    fat_set(s,1,s->max_fat_value);

    s->current_mapping = NULL;

    bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);
    bootsector->jump[0]=0xeb;
    bootsector->jump[1]=0x3e;
    bootsector->jump[2]=0x90;
    memcpy(bootsector->name,"QEMU    ",8);
    bootsector->sector_size=cpu_to_le16(0x200);
    bootsector->sectors_per_cluster=s->sectors_per_cluster;
    bootsector->reserved_sectors=cpu_to_le16(1);
    bootsector->number_of_fats=0x2; /* number of FATs */
    bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
    bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
    bootsector->media_type=(s->first_sectors_number>1?0xf8:0xf0); /* media descriptor (f8=hd, f0=3.5 fd)*/
    s->fat.pointer[0] = bootsector->media_type;
    bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
    bootsector->sectors_per_track = cpu_to_le16(secs);
    bootsector->number_of_heads = cpu_to_le16(heads);
    bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);
    bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);

    /* LATER TODO: if FAT32, this is wrong */
    bootsector->u.fat16.drive_number=s->first_sectors_number==1?0:0x80; /* fda=0, hda=0x80 */
    bootsector->u.fat16.current_head=0;
    bootsector->u.fat16.signature=0x29;
    bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);

    memcpy(bootsector->u.fat16.volume_label,"QEMU VVFAT ",11);
    memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12   ":s->fat_type==16?"FAT16   ":"FAT32   "),8);
    bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;

    return 0;
}

#ifdef DEBUG
static BDRVVVFATState *vvv = NULL;
#endif

static int enable_write_target(BDRVVVFATState *s);
static int is_consistent(BDRVVVFATState *s);

static void vvfat_rebind(BlockDriverState *bs)
{
    BDRVVVFATState *s = bs->opaque;
    s->bs = bs;
}

static QemuOptsList runtime_opts = {
    .name = "vvfat",
    .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
    .desc = {
        {
            .name = "dir",
            .type = QEMU_OPT_STRING,
            .help = "Host directory to map to the vvfat device",
        },
        {
            .name = "fat-type",
            .type = QEMU_OPT_NUMBER,
            .help = "FAT type (12, 16 or 32)",
        },
        {
            .name = "floppy",
            .type = QEMU_OPT_BOOL,
            .help = "Create a floppy rather than a hard disk image",
        },
        {
            .name = "rw",
            .type = QEMU_OPT_BOOL,
            .help = "Make the image writable",
        },
        { /* end of list */ }
    },
};

static void vvfat_parse_filename(const char *filename, QDict *options,
                                 Error **errp)
{
    int fat_type = 0;
    bool floppy = false;
    bool rw = false;
    int i;

    if (!strstart(filename, "fat:", NULL)) {
        error_setg(errp, "File name string must start with 'fat:'");
        return;
    }

    /* Parse options */
    if (strstr(filename, ":32:")) {
        fat_type = 32;
    } else if (strstr(filename, ":16:")) {
        fat_type = 16;
    } else if (strstr(filename, ":12:")) {
        fat_type = 12;
    }

    if (strstr(filename, ":floppy:")) {
        floppy = true;
    }

    if (strstr(filename, ":rw:")) {
        rw = true;
    }

    /* Get the directory name without options */
    i = strrchr(filename, ':') - filename;
    assert(i >= 3);
    if (filename[i - 2] == ':' && qemu_isalpha(filename[i - 1])) {
        /* workaround for DOS drive names */
        filename += i - 1;
    } else {
        filename += i + 1;
    }

    /* Fill in the options QDict */
    qdict_put(options, "dir", qstring_from_str(filename));
    qdict_put(options, "fat-type", qint_from_int(fat_type));
    qdict_put(options, "floppy", qbool_from_int(floppy));
    qdict_put(options, "rw", qbool_from_int(rw));
}

static int vvfat_open(BlockDriverState *bs, QDict *options, int flags)
{
    BDRVVVFATState *s = bs->opaque;
    int cyls, heads, secs;
    bool floppy;
    const char *dirname;
    QemuOpts *opts;
    Error *local_err = NULL;
    int ret;

#ifdef DEBUG
    vvv = s;
#endif

DLOG(if (stderr == NULL) {
    stderr = fopen("vvfat.log", "a");
    setbuf(stderr, NULL);
})

    opts = qemu_opts_create_nofail(&runtime_opts);
    qemu_opts_absorb_qdict(opts, options, &local_err);
    if (error_is_set(&local_err)) {
        qerror_report_err(local_err);
        error_free(local_err);
        ret = -EINVAL;
        goto fail;
    }

    dirname = qemu_opt_get(opts, "dir");
    if (!dirname) {
        qerror_report(ERROR_CLASS_GENERIC_ERROR, "vvfat block driver requires "
                      "a 'dir' option");
        ret = -EINVAL;
        goto fail;
    }

    s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);
    floppy = qemu_opt_get_bool(opts, "floppy", false);

    if (floppy) {
        /* 1.44MB or 2.88MB floppy.  2.88MB can be FAT12 (default) or FAT16. */
        if (!s->fat_type) {
            s->fat_type = 12;
            secs = 36;
            s->sectors_per_cluster = 2;
        } else {
            secs = s->fat_type == 12 ? 18 : 36;
            s->sectors_per_cluster = 1;
        }
        s->first_sectors_number = 1;
        cyls = 80;
        heads = 2;
    } else {
        /* 32MB or 504MB disk*/
        if (!s->fat_type) {
            s->fat_type = 16;
        }
        cyls = s->fat_type == 12 ? 64 : 1024;
        heads = 16;
        secs = 63;
    }

    switch (s->fat_type) {
    case 32:
	    fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. "
                "You are welcome to do so!\n");
        break;
    case 16:
    case 12:
        break;
    default:
        qerror_report(ERROR_CLASS_GENERIC_ERROR, "Valid FAT types are only "
                      "12, 16 and 32");
        ret = -EINVAL;
        goto fail;
    }


    s->bs = bs;

    /* LATER TODO: if FAT32, adjust */
    s->sectors_per_cluster=0x10;

    s->current_cluster=0xffffffff;

    s->first_sectors_number=0x40;
    /* read only is the default for safety */
    bs->read_only = 1;
    s->qcow = s->write_target = NULL;
    s->qcow_filename = NULL;
    s->fat2 = NULL;
    s->downcase_short_names = 1;

    fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
            dirname, cyls, heads, secs);

    s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);

    if (qemu_opt_get_bool(opts, "rw", false)) {
        if (enable_write_target(s)) {
            ret = -EIO;
            goto fail;
        }
        bs->read_only = 0;
    }

    bs->total_sectors = cyls * heads * secs;

    if (init_directories(s, dirname, heads, secs)) {
        ret = -EIO;
        goto fail;
    }

    s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;

    if (s->first_sectors_number == 0x40) {
        init_mbr(s, cyls, heads, secs);
    }

    //    assert(is_consistent(s));
    qemu_co_mutex_init(&s->lock);

    /* Disable migration when vvfat is used rw */
    if (s->qcow) {
        error_set(&s->migration_blocker,
                  QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
                  "vvfat (rw)", bs->device_name, "live migration");
        migrate_add_blocker(s->migration_blocker);
    }

    ret = 0;
fail:
    qemu_opts_del(opts);
    return ret;
}

static inline void vvfat_close_current_file(BDRVVVFATState *s)
{
    if(s->current_mapping) {
	s->current_mapping = NULL;
	if (s->current_fd) {
		qemu_close(s->current_fd);
		s->current_fd = 0;
	}
    }
    s->current_cluster = -1;
}

/* mappings between index1 and index2-1 are supposed to be ordered
 * return value is the index of the last mapping for which end>cluster_num
 */
static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
{
    while(1) {
        int index3;
	mapping_t* mapping;
	index3=(index1+index2)/2;
	mapping=array_get(&(s->mapping),index3);
	assert(mapping->begin < mapping->end);
	if(mapping->begin>=cluster_num) {
	    assert(index2!=index3 || index2==0);
	    if(index2==index3)
		return index1;
	    index2=index3;
	} else {
	    if(index1==index3)
		return mapping->end<=cluster_num ? index2 : index1;
	    index1=index3;
	}
	assert(index1<=index2);
	DLOG(mapping=array_get(&(s->mapping),index1);
	assert(mapping->begin<=cluster_num);
	assert(index2 >= s->mapping.next ||
		((mapping = array_get(&(s->mapping),index2)) &&
		mapping->end>cluster_num)));
    }
}

static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
{
    int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
    mapping_t* mapping;
    if(index>=s->mapping.next)
        return NULL;
    mapping=array_get(&(s->mapping),index);
    if(mapping->begin>cluster_num)
        return NULL;
    assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
    return mapping;
}

static int open_file(BDRVVVFATState* s,mapping_t* mapping)
{
    if(!mapping)
	return -1;
    if(!s->current_mapping ||
	    strcmp(s->current_mapping->path,mapping->path)) {
	/* open file */
	int fd = qemu_open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
	if(fd<0)
	    return -1;
	vvfat_close_current_file(s);
	s->current_fd = fd;
	s->current_mapping = mapping;
    }
    return 0;
}

static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
{
    if(s->current_cluster != cluster_num) {
	int result=0;
	off_t offset;
	assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
	if(!s->current_mapping
		|| s->current_mapping->begin>cluster_num
		|| s->current_mapping->end<=cluster_num) {
	    /* binary search of mappings for file */
	    mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);

	    assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));

	    if (mapping && mapping->mode & MODE_DIRECTORY) {
		vvfat_close_current_file(s);
		s->current_mapping = mapping;
read_cluster_directory:
		offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
		s->cluster = (unsigned char*)s->directory.pointer+offset
			+ 0x20*s->current_mapping->info.dir.first_dir_index;
		assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
		assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
		s->current_cluster = cluster_num;
		return 0;
	    }

	    if(open_file(s,mapping))
		return -2;
	} else if (s->current_mapping->mode & MODE_DIRECTORY)
	    goto read_cluster_directory;

	assert(s->current_fd);

	offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
	if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
	    return -3;
	s->cluster=s->cluster_buffer;
	result=read(s->current_fd,s->cluster,s->cluster_size);
	if(result<0) {
	    s->current_cluster = -1;
	    return -1;
	}
	s->current_cluster = cluster_num;
    }
    return 0;
}

#ifdef DEBUG
static void print_direntry(const direntry_t* direntry)
{
    int j = 0;
    char buffer[1024];

    fprintf(stderr, "direntry %p: ", direntry);
    if(!direntry)
	return;
    if(is_long_name(direntry)) {
	unsigned char* c=(unsigned char*)direntry;
	int i;
	for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
	    ADD_CHAR(c[i]);
	for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
	    ADD_CHAR(c[i]);
	for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
	    ADD_CHAR(c[i]);
	buffer[j] = 0;
	fprintf(stderr, "%s\n", buffer);
    } else {
	int i;
	for(i=0;i<11;i++)
	    ADD_CHAR(direntry->name[i]);
	buffer[j] = 0;
	fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
		buffer,
		direntry->attributes,
		begin_of_direntry(direntry),le32_to_cpu(direntry->size));
    }
}

static void print_mapping(const mapping_t* mapping)
{
    fprintf(stderr, "mapping (%p): begin, end = %d, %d, dir_index = %d, "
        "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
        mapping, mapping->begin, mapping->end, mapping->dir_index,
        mapping->first_mapping_index, mapping->path, mapping->mode);

    if (mapping->mode & MODE_DIRECTORY)
	fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
    else
	fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
}
#endif

static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
                    uint8_t *buf, int nb_sectors)
{
    BDRVVVFATState *s = bs->opaque;
    int i;

    for(i=0;i<nb_sectors;i++,sector_num++) {
	if (sector_num >= bs->total_sectors)
	   return -1;
	if (s->qcow) {
	    int n;
            if (bdrv_is_allocated(s->qcow, sector_num, nb_sectors-i, &n)) {
DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n));
                if (bdrv_read(s->qcow, sector_num, buf + i*0x200, n)) {
                    return -1;
                }
                i += n - 1;
                sector_num += n - 1;
                continue;
            }
DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
	}
	if(sector_num<s->faked_sectors) {
	    if(sector_num<s->first_sectors_number)
		memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
	    else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
	    else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
	} else {
	    uint32_t sector=sector_num-s->faked_sectors,
	    sector_offset_in_cluster=(sector%s->sectors_per_cluster),
	    cluster_num=sector/s->sectors_per_cluster;
	    if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
		/* LATER TODO: strict: return -1; */
		memset(buf+i*0x200,0,0x200);
		continue;
	    }
	    memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
	}
    }
    return 0;
}

static coroutine_fn int vvfat_co_read(BlockDriverState *bs, int64_t sector_num,
                                      uint8_t *buf, int nb_sectors)
{
    int ret;
    BDRVVVFATState *s = bs->opaque;
    qemu_co_mutex_lock(&s->lock);
    ret = vvfat_read(bs, sector_num, buf, nb_sectors);
    qemu_co_mutex_unlock(&s->lock);
    return ret;
}

/* LATER TODO: statify all functions */

/*
 * Idea of the write support (use snapshot):
 *
 * 1. check if all data is consistent, recording renames, modifications,
 *    new files and directories (in s->commits).
 *
 * 2. if the data is not consistent, stop committing
 *
 * 3. handle renames, and create new files and directories (do not yet
 *    write their contents)
 *
 * 4. walk the directories, fixing the mapping and direntries, and marking
 *    the handled mappings as not deleted
 *
 * 5. commit the contents of the files
 *
 * 6. handle deleted files and directories
 *
 */

typedef struct commit_t {
    char* path;
    union {
	struct { uint32_t cluster; } rename;
	struct { int dir_index; uint32_t modified_offset; } writeout;
	struct { uint32_t first_cluster; } new_file;
	struct { uint32_t cluster; } mkdir;
    } param;
    /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
    enum {
	ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
    } action;
} commit_t;

static void clear_commits(BDRVVVFATState* s)
{
    int i;
DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
    for (i = 0; i < s->commits.next; i++) {
	commit_t* commit = array_get(&(s->commits), i);
	assert(commit->path || commit->action == ACTION_WRITEOUT);
	if (commit->action != ACTION_WRITEOUT) {
	    assert(commit->path);
            g_free(commit->path);
	} else
	    assert(commit->path == NULL);
    }
    s->commits.next = 0;
}

static void schedule_rename(BDRVVVFATState* s,
	uint32_t cluster, char* new_path)
{
    commit_t* commit = array_get_next(&(s->commits));
    commit->path = new_path;
    commit->param.rename.cluster = cluster;
    commit->action = ACTION_RENAME;
}

static void schedule_writeout(BDRVVVFATState* s,
	int dir_index, uint32_t modified_offset)
{
    commit_t* commit = array_get_next(&(s->commits));
    commit->path = NULL;
    commit->param.writeout.dir_index = dir_index;
    commit->param.writeout.modified_offset = modified_offset;
    commit->action = ACTION_WRITEOUT;
}

static void schedule_new_file(BDRVVVFATState* s,
	char* path, uint32_t first_cluster)
{
    commit_t* commit = array_get_next(&(s->commits));
    commit->path = path;
    commit->param.new_file.first_cluster = first_cluster;
    commit->action = ACTION_NEW_FILE;
}

static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
{
    commit_t* commit = array_get_next(&(s->commits));
    commit->path = path;
    commit->param.mkdir.cluster = cluster;
    commit->action = ACTION_MKDIR;
}

typedef struct {
    /*
     * Since the sequence number is at most 0x3f, and the filename
     * length is at most 13 times the sequence number, the maximal
     * filename length is 0x3f * 13 bytes.
     */
    unsigned char name[0x3f * 13 + 1];
    int checksum, len;
    int sequence_number;
} long_file_name;

static void lfn_init(long_file_name* lfn)
{
   lfn->sequence_number = lfn->len = 0;
   lfn->checksum = 0x100;
}

/* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
static int parse_long_name(long_file_name* lfn,
	const direntry_t* direntry)
{
    int i, j, offset;
    const unsigned char* pointer = (const unsigned char*)direntry;

    if (!is_long_name(direntry))
	return 1;

    if (pointer[0] & 0x40) {
	lfn->sequence_number = pointer[0] & 0x3f;
	lfn->checksum = pointer[13];
	lfn->name[0] = 0;
	lfn->name[lfn->sequence_number * 13] = 0;
    } else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
	return -1;
    else if (pointer[13] != lfn->checksum)
	return -2;
    else if (pointer[12] || pointer[26] || pointer[27])
	return -3;

    offset = 13 * (lfn->sequence_number - 1);
    for (i = 0, j = 1; i < 13; i++, j+=2) {
	if (j == 11)
	    j = 14;
	else if (j == 26)
	    j = 28;

	if (pointer[j+1] == 0)
	    lfn->name[offset + i] = pointer[j];
	else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
	    return -4;
	else
	    lfn->name[offset + i] = 0;
    }

    if (pointer[0] & 0x40)
	lfn->len = offset + strlen((char*)lfn->name + offset);

    return 0;
}

/* returns 0 if successful, >0 if no short_name, and <0 on error */
static int parse_short_name(BDRVVVFATState* s,
	long_file_name* lfn, direntry_t* direntry)
{
    int i, j;

    if (!is_short_name(direntry))
	return 1;

    for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
    for (i = 0; i <= j; i++) {
	if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
	    return -1;
	else if (s->downcase_short_names)
	    lfn->name[i] = qemu_tolower(direntry->name[i]);
	else
	    lfn->name[i] = direntry->name[i];
    }

    for (j = 2; j >= 0 && direntry->extension[j] == ' '; j--);
    if (j >= 0) {
	lfn->name[i++] = '.';
	lfn->name[i + j + 1] = '\0';
	for (;j >= 0; j--) {
	    if (direntry->extension[j] <= ' ' || direntry->extension[j] > 0x7f)
		return -2;
	    else if (s->downcase_short_names)
		lfn->name[i + j] = qemu_tolower(direntry->extension[j]);
	    else
		lfn->name[i + j] = direntry->extension[j];
	}
    } else
	lfn->name[i + j + 1] = '\0';

    lfn->len = strlen((char*)lfn->name);

    return 0;
}

static inline uint32_t modified_fat_get(BDRVVVFATState* s,
	unsigned int cluster)
{
    if (cluster < s->last_cluster_of_root_directory) {
	if (cluster + 1 == s->last_cluster_of_root_directory)
	    return s->max_fat_value;
	else
	    return cluster + 1;
    }

    if (s->fat_type==32) {
        uint32_t* entry=((uint32_t*)s->fat2)+cluster;
        return le32_to_cpu(*entry);
    } else if (s->fat_type==16) {
        uint16_t* entry=((uint16_t*)s->fat2)+cluster;
        return le16_to_cpu(*entry);
    } else {
        const uint8_t* x=s->fat2+cluster*3/2;
        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
    }
}

static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num)
{
    int was_modified = 0;
    int i, dummy;

    if (s->qcow == NULL)
	return 0;

    for (i = 0; !was_modified && i < s->sectors_per_cluster; i++)
	was_modified = bdrv_is_allocated(s->qcow,
		cluster2sector(s, cluster_num) + i, 1, &dummy);

    return was_modified;
}

static const char* get_basename(const char* path)
{
    char* basename = strrchr(path, '/');
    if (basename == NULL)
	return path;
    else
	return basename + 1; /* strip '/' */
}

/*
 * The array s->used_clusters holds the states of the clusters. If it is
 * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
 * was modified, bit 3 is set.
 * If any cluster is allocated, but not part of a file or directory, this
 * driver refuses to commit.
 */
typedef enum {
     USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
} used_t;

/*
 * get_cluster_count_for_direntry() not only determines how many clusters
 * are occupied by direntry, but also if it was renamed or modified.
 *
 * A file is thought to be renamed *only* if there already was a file with
 * exactly the same first cluster, but a different name.
 *
 * Further, the files/directories handled by this function are
 * assumed to be *not* deleted (and *only* those).
 */
static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
	direntry_t* direntry, const char* path)
{
    /*
     * This is a little bit tricky:
     * IF the guest OS just inserts a cluster into the file chain,
     * and leaves the rest alone, (i.e. the original file had clusters
     * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
     *
     * - do_commit will write the cluster into the file at the given
     *   offset, but
     *
     * - the cluster which is overwritten should be moved to a later
     *   position in the file.
     *
     * I am not aware that any OS does something as braindead, but this
     * situation could happen anyway when not committing for a long time.
     * Just to be sure that this does not bite us, detect it, and copy the
     * contents of the clusters to-be-overwritten into the qcow.
     */
    int copy_it = 0;
    int was_modified = 0;
    int32_t ret = 0;

    uint32_t cluster_num = begin_of_direntry(direntry);
    uint32_t offset = 0;
    int first_mapping_index = -1;
    mapping_t* mapping = NULL;
    const char* basename2 = NULL;

    vvfat_close_current_file(s);

    /* the root directory */
    if (cluster_num == 0)
	return 0;

    /* write support */
    if (s->qcow) {
	basename2 = get_basename(path);

	mapping = find_mapping_for_cluster(s, cluster_num);

	if (mapping) {
	    const char* basename;

	    assert(mapping->mode & MODE_DELETED);
	    mapping->mode &= ~MODE_DELETED;

	    basename = get_basename(mapping->path);

	    assert(mapping->mode & MODE_NORMAL);

	    /* rename */
	    if (strcmp(basename, basename2))
		schedule_rename(s, cluster_num, g_strdup(path));
	} else if (is_file(direntry))
	    /* new file */
	    schedule_new_file(s, g_strdup(path), cluster_num);
	else {
            abort();
	    return 0;
	}
    }

    while(1) {
	if (s->qcow) {
	    if (!copy_it && cluster_was_modified(s, cluster_num)) {
		if (mapping == NULL ||
			mapping->begin > cluster_num ||
			mapping->end <= cluster_num)
		mapping = find_mapping_for_cluster(s, cluster_num);


		if (mapping &&
			(mapping->mode & MODE_DIRECTORY) == 0) {

		    /* was modified in qcow */
		    if (offset != mapping->info.file.offset + s->cluster_size
			    * (cluster_num - mapping->begin)) {
			/* offset of this cluster in file chain has changed */
                        abort();
			copy_it = 1;
		    } else if (offset == 0) {
			const char* basename = get_basename(mapping->path);

			if (strcmp(basename, basename2))
			    copy_it = 1;
			first_mapping_index = array_index(&(s->mapping), mapping);
		    }

		    if (mapping->first_mapping_index != first_mapping_index
			    && mapping->info.file.offset > 0) {
                        abort();
			copy_it = 1;
		    }

		    /* need to write out? */
		    if (!was_modified && is_file(direntry)) {
			was_modified = 1;
			schedule_writeout(s, mapping->dir_index, offset);
		    }
		}
	    }

	    if (copy_it) {
		int i, dummy;
		/*
		 * This is horribly inefficient, but that is okay, since
		 * it is rarely executed, if at all.
		 */
		int64_t offset = cluster2sector(s, cluster_num);

		vvfat_close_current_file(s);
                for (i = 0; i < s->sectors_per_cluster; i++) {
                    if (!bdrv_is_allocated(s->qcow, offset + i, 1, &dummy)) {
                        if (vvfat_read(s->bs, offset, s->cluster_buffer, 1)) {
                            return -1;
                        }
                        if (bdrv_write(s->qcow, offset, s->cluster_buffer, 1)) {
                            return -2;
                        }
                    }
                }
	    }
	}

	ret++;
	if (s->used_clusters[cluster_num] & USED_ANY)
	    return 0;
	s->used_clusters[cluster_num] = USED_FILE;

	cluster_num = modified_fat_get(s, cluster_num);

	if (fat_eof(s, cluster_num))
	    return ret;
	else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
	    return -1;

	offset += s->cluster_size;
    }
}

/*
 * This function looks at the modified data (qcow).
 * It returns 0 upon inconsistency or error, and the number of clusters
 * used by the directory, its subdirectories and their files.
 */
static int check_directory_consistency(BDRVVVFATState *s,
	int cluster_num, const char* path)
{
    int ret = 0;
    unsigned char* cluster = g_malloc(s->cluster_size);
    direntry_t* direntries = (direntry_t*)cluster;
    mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);

    long_file_name lfn;
    int path_len = strlen(path);
    char path2[PATH_MAX + 1];

    assert(path_len < PATH_MAX); /* len was tested before! */
    pstrcpy(path2, sizeof(path2), path);
    path2[path_len] = '/';
    path2[path_len + 1] = '\0';

    if (mapping) {
	const char* basename = get_basename(mapping->path);
	const char* basename2 = get_basename(path);

	assert(mapping->mode & MODE_DIRECTORY);

	assert(mapping->mode & MODE_DELETED);
	mapping->mode &= ~MODE_DELETED;

	if (strcmp(basename, basename2))
	    schedule_rename(s, cluster_num, g_strdup(path));
    } else
	/* new directory */
	schedule_mkdir(s, cluster_num, g_strdup(path));

    lfn_init(&lfn);
    do {
	int i;
	int subret = 0;

	ret++;

	if (s->used_clusters[cluster_num] & USED_ANY) {
	    fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
	    return 0;
	}
	s->used_clusters[cluster_num] = USED_DIRECTORY;

DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
	subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
		s->sectors_per_cluster);
	if (subret) {
	    fprintf(stderr, "Error fetching direntries\n");
	fail:
            g_free(cluster);
	    return 0;
	}

	for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
	    int cluster_count = 0;

DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i));
	    if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
		    is_free(direntries + i))
		continue;

	    subret = parse_long_name(&lfn, direntries + i);
	    if (subret < 0) {
		fprintf(stderr, "Error in long name\n");
		goto fail;
	    }
	    if (subret == 0 || is_free(direntries + i))
		continue;

	    if (fat_chksum(direntries+i) != lfn.checksum) {
		subret = parse_short_name(s, &lfn, direntries + i);
		if (subret < 0) {
		    fprintf(stderr, "Error in short name (%d)\n", subret);
		    goto fail;
		}
		if (subret > 0 || !strcmp((char*)lfn.name, ".")
			|| !strcmp((char*)lfn.name, ".."))
		    continue;
	    }
	    lfn.checksum = 0x100; /* cannot use long name twice */

	    if (path_len + 1 + lfn.len >= PATH_MAX) {
		fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
		goto fail;
	    }
            pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
                    (char*)lfn.name);

	    if (is_directory(direntries + i)) {
		if (begin_of_direntry(direntries + i) == 0) {
		    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
		    goto fail;
		}
		cluster_count = check_directory_consistency(s,
			begin_of_direntry(direntries + i), path2);
		if (cluster_count == 0) {
		    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
		    goto fail;
		}
	    } else if (is_file(direntries + i)) {
		/* check file size with FAT */
		cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
		if (cluster_count !=
			(le32_to_cpu(direntries[i].size) + s->cluster_size
			 - 1) / s->cluster_size) {
		    DLOG(fprintf(stderr, "Cluster count mismatch\n"));
		    goto fail;
		}
	    } else
                abort(); /* cluster_count = 0; */

	    ret += cluster_count;
	}

	cluster_num = modified_fat_get(s, cluster_num);
    } while(!fat_eof(s, cluster_num));

    g_free(cluster);
    return ret;
}

/* returns 1 on success */
static int is_consistent(BDRVVVFATState* s)
{
    int i, check;
    int used_clusters_count = 0;

DLOG(checkpoint());
    /*
     * - get modified FAT
     * - compare the two FATs (TODO)
     * - get buffer for marking used clusters
     * - recurse direntries from root (using bs->bdrv_read to make
     *    sure to get the new data)
     *   - check that the FAT agrees with the size
     *   - count the number of clusters occupied by this directory and
     *     its files
     * - check that the cumulative used cluster count agrees with the
     *   FAT
     * - if all is fine, return number of used clusters
     */
    if (s->fat2 == NULL) {
	int size = 0x200 * s->sectors_per_fat;
	s->fat2 = g_malloc(size);
	memcpy(s->fat2, s->fat.pointer, size);
    }
    check = vvfat_read(s->bs,
	    s->first_sectors_number, s->fat2, s->sectors_per_fat);
    if (check) {
	fprintf(stderr, "Could not copy fat\n");
	return 0;
    }
    assert (s->used_clusters);
    for (i = 0; i < sector2cluster(s, s->sector_count); i++)
	s->used_clusters[i] &= ~USED_ANY;

    clear_commits(s);

    /* mark every mapped file/directory as deleted.
     * (check_directory_consistency() will unmark those still present). */
    if (s->qcow)
	for (i = 0; i < s->mapping.next; i++) {
	    mapping_t* mapping = array_get(&(s->mapping), i);
	    if (mapping->first_mapping_index < 0)
		mapping->mode |= MODE_DELETED;
	}

    used_clusters_count = check_directory_consistency(s, 0, s->path);
    if (used_clusters_count <= 0) {
	DLOG(fprintf(stderr, "problem in directory\n"));
	return 0;
    }

    check = s->last_cluster_of_root_directory;
    for (i = check; i < sector2cluster(s, s->sector_count); i++) {
	if (modified_fat_get(s, i)) {
	    if(!s->used_clusters[i]) {
		DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
		return 0;
	    }
	    check++;
	}

	if (s->used_clusters[i] == USED_ALLOCATED) {
	    /* allocated, but not used... */
	    DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
	    return 0;
	}
    }

    if (check != used_clusters_count)
	return 0;

    return used_clusters_count;
}

static inline void adjust_mapping_indices(BDRVVVFATState* s,
	int offset, int adjust)
{
    int i;

    for (i = 0; i < s->mapping.next; i++) {
	mapping_t* mapping = array_get(&(s->mapping), i);

#define ADJUST_MAPPING_INDEX(name) \
	if (mapping->name >= offset) \
	    mapping->name += adjust

	ADJUST_MAPPING_INDEX(first_mapping_index);
	if (mapping->mode & MODE_DIRECTORY)
	    ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
    }
}

/* insert or update mapping */
static mapping_t* insert_mapping(BDRVVVFATState* s,
	uint32_t begin, uint32_t end)
{
    /*
     * - find mapping where mapping->begin >= begin,
     * - if mapping->begin > begin: insert
     *   - adjust all references to mappings!
     * - else: adjust
     * - replace name
     */
    int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
    mapping_t* mapping = NULL;
    mapping_t* first_mapping = array_get(&(s->mapping), 0);

    if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
	    && mapping->begin < begin) {
	mapping->end = begin;
	index++;
	mapping = array_get(&(s->mapping), index);
    }
    if (index >= s->mapping.next || mapping->begin > begin) {
	mapping = array_insert(&(s->mapping), index, 1);
	mapping->path = NULL;
	adjust_mapping_indices(s, index, +1);
    }

    mapping->begin = begin;
    mapping->end = end;

DLOG(mapping_t* next_mapping;
assert(index + 1 >= s->mapping.next ||
((next_mapping = array_get(&(s->mapping), index + 1)) &&
 next_mapping->begin >= end)));

    if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
	s->current_mapping = array_get(&(s->mapping),
		s->current_mapping - first_mapping);

    return mapping;
}

static int remove_mapping(BDRVVVFATState* s, int mapping_index)
{
    mapping_t* mapping = array_get(&(s->mapping), mapping_index);
    mapping_t* first_mapping = array_get(&(s->mapping), 0);

    /* free mapping */
    if (mapping->first_mapping_index < 0) {
        g_free(mapping->path);
    }

    /* remove from s->mapping */
    array_remove(&(s->mapping), mapping_index);

    /* adjust all references to mappings */
    adjust_mapping_indices(s, mapping_index, -1);

    if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
	s->current_mapping = array_get(&(s->mapping),
		s->current_mapping - first_mapping);

    return 0;
}

static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
{
    int i;
    for (i = 0; i < s->mapping.next; i++) {
	mapping_t* mapping = array_get(&(s->mapping), i);
	if (mapping->dir_index >= offset)
	    mapping->dir_index += adjust;
	if ((mapping->mode & MODE_DIRECTORY) &&
		mapping->info.dir.first_dir_index >= offset)
	    mapping->info.dir.first_dir_index += adjust;
    }
}

static direntry_t* insert_direntries(BDRVVVFATState* s,
	int dir_index, int count)
{
    /*
     * make room in s->directory,
     * adjust_dirindices
     */
    direntry_t* result = array_insert(&(s->directory), dir_index, count);
    if (result == NULL)
	return NULL;
    adjust_dirindices(s, dir_index, count);
    return result;
}

static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
{
    int ret = array_remove_slice(&(s->directory), dir_index, count);
    if (ret)
	return ret;
    adjust_dirindices(s, dir_index, -count);
    return 0;
}

/*
 * Adapt the mappings of the cluster chain starting at first cluster
 * (i.e. if a file starts at first_cluster, the chain is followed according
 * to the modified fat, and the corresponding entries in s->mapping are
 * adjusted)
 */
static int commit_mappings(BDRVVVFATState* s,
	uint32_t first_cluster, int dir_index)
{
    mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
    direntry_t* direntry = array_get(&(s->directory), dir_index);
    uint32_t cluster = first_cluster;

    vvfat_close_current_file(s);

    assert(mapping);
    assert(mapping->begin == first_cluster);
    mapping->first_mapping_index = -1;
    mapping->dir_index = dir_index;
    mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
	MODE_DIRECTORY : MODE_NORMAL;

    while (!fat_eof(s, cluster)) {
	uint32_t c, c1;

	for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
		c = c1, c1 = modified_fat_get(s, c1));

	c++;
	if (c > mapping->end) {
	    int index = array_index(&(s->mapping), mapping);
	    int i, max_i = s->mapping.next - index;
	    for (i = 1; i < max_i && mapping[i].begin < c; i++);
	    while (--i > 0)
		remove_mapping(s, index + 1);
	}
	assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
		|| mapping[1].begin >= c);
	mapping->end = c;

	if (!fat_eof(s, c1)) {
	    int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
	    mapping_t* next_mapping = i >= s->mapping.next ? NULL :
		array_get(&(s->mapping), i);

	    if (next_mapping == NULL || next_mapping->begin > c1) {
		int i1 = array_index(&(s->mapping), mapping);

		next_mapping = insert_mapping(s, c1, c1+1);

		if (c1 < c)
		    i1++;
		mapping = array_get(&(s->mapping), i1);
	    }

	    next_mapping->dir_index = mapping->dir_index;
	    next_mapping->first_mapping_index =
		mapping->first_mapping_index < 0 ?
		array_index(&(s->mapping), mapping) :
		mapping->first_mapping_index;
	    next_mapping->path = mapping->path;
	    next_mapping->mode = mapping->mode;
	    next_mapping->read_only = mapping->read_only;
	    if (mapping->mode & MODE_DIRECTORY) {
		next_mapping->info.dir.parent_mapping_index =
			mapping->info.dir.parent_mapping_index;
		next_mapping->info.dir.first_dir_index =
			mapping->info.dir.first_dir_index +
			0x10 * s->sectors_per_cluster *
			(mapping->end - mapping->begin);
	    } else
		next_mapping->info.file.offset = mapping->info.file.offset +
			mapping->end - mapping->begin;

	    mapping = next_mapping;
	}

	cluster = c1;
    }

    return 0;
}

static int commit_direntries(BDRVVVFATState* s,
	int dir_index, int parent_mapping_index)
{
    direntry_t* direntry = array_get(&(s->directory), dir_index);
    uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
    mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);

    int factor = 0x10 * s->sectors_per_cluster;
    int old_cluster_count, new_cluster_count;
    int current_dir_index = mapping->info.dir.first_dir_index;
    int first_dir_index = current_dir_index;
    int ret, i;
    uint32_t c;

DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapping->path, parent_mapping_index));

    assert(direntry);
    assert(mapping);
    assert(mapping->begin == first_cluster);
    assert(mapping->info.dir.first_dir_index < s->directory.next);
    assert(mapping->mode & MODE_DIRECTORY);
    assert(dir_index == 0 || is_directory(direntry));

    mapping->info.dir.parent_mapping_index = parent_mapping_index;

    if (first_cluster == 0) {
	old_cluster_count = new_cluster_count =
	    s->last_cluster_of_root_directory;
    } else {
	for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
		c = fat_get(s, c))
	    old_cluster_count++;

	for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
		c = modified_fat_get(s, c))
	    new_cluster_count++;
    }

    if (new_cluster_count > old_cluster_count) {
	if (insert_direntries(s,
		current_dir_index + factor * old_cluster_count,
		factor * (new_cluster_count - old_cluster_count)) == NULL)
	    return -1;
    } else if (new_cluster_count < old_cluster_count)
	remove_direntries(s,
		current_dir_index + factor * new_cluster_count,
		factor * (old_cluster_count - new_cluster_count));

    for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
	void* direntry = array_get(&(s->directory), current_dir_index);
	int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
		s->sectors_per_cluster);
	if (ret)
	    return ret;
	assert(!strncmp(s->directory.pointer, "QEMU", 4));
	current_dir_index += factor;
    }

    ret = commit_mappings(s, first_cluster, dir_index);
    if (ret)
	return ret;

    /* recurse */
    for (i = 0; i < factor * new_cluster_count; i++) {
	direntry = array_get(&(s->directory), first_dir_index + i);
	if (is_directory(direntry) && !is_dot(direntry)) {
	    mapping = find_mapping_for_cluster(s, first_cluster);
	    assert(mapping->mode & MODE_DIRECTORY);
	    ret = commit_direntries(s, first_dir_index + i,
		array_index(&(s->mapping), mapping));
	    if (ret)
		return ret;
	}
    }

    return 0;
}

/* commit one file (adjust contents, adjust mapping),
   return first_mapping_index */
static int commit_one_file(BDRVVVFATState* s,
	int dir_index, uint32_t offset)
{
    direntry_t* direntry = array_get(&(s->directory), dir_index);
    uint32_t c = begin_of_direntry(direntry);
    uint32_t first_cluster = c;
    mapping_t* mapping = find_mapping_for_cluster(s, c);
    uint32_t size = filesize_of_direntry(direntry);
    char* cluster = g_malloc(s->cluster_size);
    uint32_t i;
    int fd = 0;

    assert(offset < size);
    assert((offset % s->cluster_size) == 0);

    for (i = s->cluster_size; i < offset; i += s->cluster_size)
	c = modified_fat_get(s, c);

    fd = qemu_open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
    if (fd < 0) {
	fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
		strerror(errno), errno);
        g_free(cluster);
	return fd;
    }
    if (offset > 0) {
        if (lseek(fd, offset, SEEK_SET) != offset) {
            qemu_close(fd);
            g_free(cluster);
            return -3;
        }
    }

    while (offset < size) {
	uint32_t c1;
	int rest_size = (size - offset > s->cluster_size ?
		s->cluster_size : size - offset);
	int ret;

	c1 = modified_fat_get(s, c);

	assert((size - offset == 0 && fat_eof(s, c)) ||
		(size > offset && c >=2 && !fat_eof(s, c)));

	ret = vvfat_read(s->bs, cluster2sector(s, c),
	    (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);

        if (ret < 0) {
            qemu_close(fd);
            g_free(cluster);
            return ret;
        }

        if (write(fd, cluster, rest_size) < 0) {
            qemu_close(fd);
            g_free(cluster);
            return -2;
        }

	offset += rest_size;
	c = c1;
    }

    if (ftruncate(fd, size)) {
        perror("ftruncate()");
        qemu_close(fd);
        g_free(cluster);
        return -4;
    }
    qemu_close(fd);
    g_free(cluster);

    return commit_mappings(s, first_cluster, dir_index);
}

#ifdef DEBUG
/* test, if all mappings point to valid direntries */
static void check1(BDRVVVFATState* s)
{
    int i;
    for (i = 0; i < s->mapping.next; i++) {
	mapping_t* mapping = array_get(&(s->mapping), i);
	if (mapping->mode & MODE_DELETED) {
	    fprintf(stderr, "deleted\n");
	    continue;
	}
	assert(mapping->dir_index < s->directory.next);
	direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
	assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
	if (mapping->mode & MODE_DIRECTORY) {
	    assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
	    assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
	}
    }
}

/* test, if all direntries have mappings */
static void check2(BDRVVVFATState* s)
{
    int i;
    int first_mapping = -1;

    for (i = 0; i < s->directory.next; i++) {
	direntry_t* direntry = array_get(&(s->directory), i);

	if (is_short_name(direntry) && begin_of_direntry(direntry)) {
	    mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
	    assert(mapping);
	    assert(mapping->dir_index == i || is_dot(direntry));
	    assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
	}

	if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
	    /* cluster start */
	    int j, count = 0;

	    for (j = 0; j < s->mapping.next; j++) {
		mapping_t* mapping = array_get(&(s->mapping), j);
		if (mapping->mode & MODE_DELETED)
		    continue;
		if (mapping->mode & MODE_DIRECTORY) {
		    if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
			assert(++count == 1);
			if (mapping->first_mapping_index == -1)
			    first_mapping = array_index(&(s->mapping), mapping);
			else
			    assert(first_mapping == mapping->first_mapping_index);
			if (mapping->info.dir.parent_mapping_index < 0)
			    assert(j == 0);
			else {
			    mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
			    assert(parent->mode & MODE_DIRECTORY);
			    assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
			}
		    }
		}
	    }
	    if (count == 0)
		first_mapping = -1;
	}
    }
}
#endif

static int handle_renames_and_mkdirs(BDRVVVFATState* s)
{
    int i;

#ifdef DEBUG
    fprintf(stderr, "handle_renames\n");
    for (i = 0; i < s->commits.next; i++) {
	commit_t* commit = array_get(&(s->commits), i);
	fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
    }
#endif

    for (i = 0; i < s->commits.next;) {
	commit_t* commit = array_get(&(s->commits), i);
	if (commit->action == ACTION_RENAME) {
	    mapping_t* mapping = find_mapping_for_cluster(s,
		    commit->param.rename.cluster);
	    char* old_path = mapping->path;

	    assert(commit->path);
	    mapping->path = commit->path;
	    if (rename(old_path, mapping->path))
		return -2;

	    if (mapping->mode & MODE_DIRECTORY) {
		int l1 = strlen(mapping->path);
		int l2 = strlen(old_path);
		int diff = l1 - l2;
		direntry_t* direntry = array_get(&(s->directory),
			mapping->info.dir.first_dir_index);
		uint32_t c = mapping->begin;
		int i = 0;

		/* recurse */
		while (!fat_eof(s, c)) {
		    do {
			direntry_t* d = direntry + i;

			if (is_file(d) || (is_directory(d) && !is_dot(d))) {
			    mapping_t* m = find_mapping_for_cluster(s,
				    begin_of_direntry(d));
			    int l = strlen(m->path);
			    char* new_path = g_malloc(l + diff + 1);

			    assert(!strncmp(m->path, mapping->path, l2));

                            pstrcpy(new_path, l + diff + 1, mapping->path);
                            pstrcpy(new_path + l1, l + diff + 1 - l1,
                                    m->path + l2);

			    schedule_rename(s, m->begin, new_path);
			}
			i++;
		    } while((i % (0x10 * s->sectors_per_cluster)) != 0);
		    c = fat_get(s, c);
		}
	    }

            g_free(old_path);
	    array_remove(&(s->commits), i);
	    continue;
	} else if (commit->action == ACTION_MKDIR) {
	    mapping_t* mapping;
	    int j, parent_path_len;

#ifdef __MINGW32__
            if (mkdir(commit->path))
                return -5;
#else
            if (mkdir(commit->path, 0755))
                return -5;
#endif

	    mapping = insert_mapping(s, commit->param.mkdir.cluster,
		    commit->param.mkdir.cluster + 1);
	    if (mapping == NULL)
		return -6;

	    mapping->mode = MODE_DIRECTORY;
	    mapping->read_only = 0;
	    mapping->path = commit->path;
	    j = s->directory.next;
	    assert(j);
	    insert_direntries(s, s->directory.next,
		    0x10 * s->sectors_per_cluster);
	    mapping->info.dir.first_dir_index = j;

	    parent_path_len = strlen(commit->path)
		- strlen(get_basename(commit->path)) - 1;
	    for (j = 0; j < s->mapping.next; j++) {
		mapping_t* m = array_get(&(s->mapping), j);
		if (m->first_mapping_index < 0 && m != mapping &&
			!strncmp(m->path, mapping->path, parent_path_len) &&
			strlen(m->path) == parent_path_len)
		    break;
	    }
	    assert(j < s->mapping.next);
	    mapping->info.dir.parent_mapping_index = j;

	    array_remove(&(s->commits), i);
	    continue;
	}

	i++;
    }
    return 0;
}

/*
 * TODO: make sure that the short name is not matching *another* file
 */
static int handle_commits(BDRVVVFATState* s)
{
    int i, fail = 0;

    vvfat_close_current_file(s);

    for (i = 0; !fail && i < s->commits.next; i++) {
	commit_t* commit = array_get(&(s->commits), i);
	switch(commit->action) {
	case ACTION_RENAME: case ACTION_MKDIR:
            abort();
	    fail = -2;
	    break;
	case ACTION_WRITEOUT: {
#ifndef NDEBUG
            /* these variables are only used by assert() below */
	    direntry_t* entry = array_get(&(s->directory),
		    commit->param.writeout.dir_index);
	    uint32_t begin = begin_of_direntry(entry);
	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
#endif

	    assert(mapping);
	    assert(mapping->begin == begin);
	    assert(commit->path == NULL);

	    if (commit_one_file(s, commit->param.writeout.dir_index,
			commit->param.writeout.modified_offset))
		fail = -3;

	    break;
	}
	case ACTION_NEW_FILE: {
	    int begin = commit->param.new_file.first_cluster;
	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
	    direntry_t* entry;
	    int i;

	    /* find direntry */
	    for (i = 0; i < s->directory.next; i++) {
		entry = array_get(&(s->directory), i);
		if (is_file(entry) && begin_of_direntry(entry) == begin)
		    break;
	    }

	    if (i >= s->directory.next) {
		fail = -6;
		continue;
	    }

	    /* make sure there exists an initial mapping */
	    if (mapping && mapping->begin != begin) {
		mapping->end = begin;
		mapping = NULL;
	    }
	    if (mapping == NULL) {
		mapping = insert_mapping(s, begin, begin+1);
	    }
	    /* most members will be fixed in commit_mappings() */
	    assert(commit->path);
	    mapping->path = commit->path;
	    mapping->read_only = 0;
	    mapping->mode = MODE_NORMAL;
	    mapping->info.file.offset = 0;

	    if (commit_one_file(s, i, 0))
		fail = -7;

	    break;
	}
	default:
            abort();
	}
    }
    if (i > 0 && array_remove_slice(&(s->commits), 0, i))
	return -1;
    return fail;
}

static int handle_deletes(BDRVVVFATState* s)
{
    int i, deferred = 1, deleted = 1;

    /* delete files corresponding to mappings marked as deleted */
    /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
    while (deferred && deleted) {
	deferred = 0;
	deleted = 0;

	for (i = 1; i < s->mapping.next; i++) {
	    mapping_t* mapping = array_get(&(s->mapping), i);
	    if (mapping->mode & MODE_DELETED) {
		direntry_t* entry = array_get(&(s->directory),
			mapping->dir_index);

		if (is_free(entry)) {
		    /* remove file/directory */
		    if (mapping->mode & MODE_DIRECTORY) {
			int j, next_dir_index = s->directory.next,
			first_dir_index = mapping->info.dir.first_dir_index;

			if (rmdir(mapping->path) < 0) {
			    if (errno == ENOTEMPTY) {
				deferred++;
				continue;
			    } else
				return -5;
			}

			for (j = 1; j < s->mapping.next; j++) {
			    mapping_t* m = array_get(&(s->mapping), j);
			    if (m->mode & MODE_DIRECTORY &&
				    m->info.dir.first_dir_index >
				    first_dir_index &&
				    m->info.dir.first_dir_index <
				    next_dir_index)
				next_dir_index =
				    m->info.dir.first_dir_index;
			}
			remove_direntries(s, first_dir_index,
				next_dir_index - first_dir_index);

			deleted++;
		    }
		} else {
		    if (unlink(mapping->path))
			return -4;
		    deleted++;
		}
		DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
		remove_mapping(s, i);
	    }
	}
    }

    return 0;
}

/*
 * synchronize mapping with new state:
 *
 * - copy FAT (with bdrv_read)
 * - mark all filenames corresponding to mappings as deleted
 * - recurse direntries from root (using bs->bdrv_read)
 * - delete files corresponding to mappings marked as deleted
 */
static int do_commit(BDRVVVFATState* s)
{
    int ret = 0;

    /* the real meat are the commits. Nothing to do? Move along! */
    if (s->commits.next == 0)
	return 0;

    vvfat_close_current_file(s);

    ret = handle_renames_and_mkdirs(s);
    if (ret) {
	fprintf(stderr, "Error handling renames (%d)\n", ret);
        abort();
	return ret;
    }

    /* copy FAT (with bdrv_read) */
    memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);

    /* recurse direntries from root (using bs->bdrv_read) */
    ret = commit_direntries(s, 0, -1);
    if (ret) {
	fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
        abort();
	return ret;
    }

    ret = handle_commits(s);
    if (ret) {
	fprintf(stderr, "Error handling commits (%d)\n", ret);
        abort();
	return ret;
    }

    ret = handle_deletes(s);
    if (ret) {
	fprintf(stderr, "Error deleting\n");
        abort();
	return ret;
    }

    if (s->qcow->drv->bdrv_make_empty) {
        s->qcow->drv->bdrv_make_empty(s->qcow);
    }

    memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));

DLOG(checkpoint());
    return 0;
}

static int try_commit(BDRVVVFATState* s)
{
    vvfat_close_current_file(s);
DLOG(checkpoint());
    if(!is_consistent(s))
	return -1;
    return do_commit(s);
}

static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
                    const uint8_t *buf, int nb_sectors)
{
    BDRVVVFATState *s = bs->opaque;
    int i, ret;

DLOG(checkpoint());

    /* Check if we're operating in read-only mode */
    if (s->qcow == NULL) {
        return -EACCES;
    }

    vvfat_close_current_file(s);

    /*
     * Some sanity checks:
     * - do not allow writing to the boot sector
     * - do not allow to write non-ASCII filenames
     */

    if (sector_num < s->first_sectors_number)
	return -1;

    for (i = sector2cluster(s, sector_num);
	    i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
	mapping_t* mapping = find_mapping_for_cluster(s, i);
	if (mapping) {
	    if (mapping->read_only) {
		fprintf(stderr, "Tried to write to write-protected file %s\n",
			mapping->path);
		return -1;
	    }

	    if (mapping->mode & MODE_DIRECTORY) {
		int begin = cluster2sector(s, i);
		int end = begin + s->sectors_per_cluster, k;
		int dir_index;
		const direntry_t* direntries;
		long_file_name lfn;

		lfn_init(&lfn);

		if (begin < sector_num)
		    begin = sector_num;
		if (end > sector_num + nb_sectors)
		    end = sector_num + nb_sectors;
		dir_index  = mapping->dir_index +
		    0x10 * (begin - mapping->begin * s->sectors_per_cluster);
		direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));

		for (k = 0; k < (end - begin) * 0x10; k++) {
		    /* do not allow non-ASCII filenames */
		    if (parse_long_name(&lfn, direntries + k) < 0) {
			fprintf(stderr, "Warning: non-ASCII filename\n");
			return -1;
		    }
		    /* no access to the direntry of a read-only file */
		    else if (is_short_name(direntries+k) &&
			    (direntries[k].attributes & 1)) {
			if (memcmp(direntries + k,
				    array_get(&(s->directory), dir_index + k),
				    sizeof(direntry_t))) {
			    fprintf(stderr, "Warning: tried to write to write-protected file\n");
			    return -1;
			}
		    }
		}
	    }
	    i = mapping->end;
	} else
	    i++;
    }

    /*
     * Use qcow backend. Commit later.
     */
DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
    ret = bdrv_write(s->qcow, sector_num, buf, nb_sectors);
    if (ret < 0) {
	fprintf(stderr, "Error writing to qcow backend\n");
	return ret;
    }

    for (i = sector2cluster(s, sector_num);
	    i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
	if (i >= 0)
	    s->used_clusters[i] |= USED_ALLOCATED;

DLOG(checkpoint());
    /* TODO: add timeout */
    try_commit(s);

DLOG(checkpoint());
    return 0;
}

static coroutine_fn int vvfat_co_write(BlockDriverState *bs, int64_t sector_num,
                                       const uint8_t *buf, int nb_sectors)
{
    int ret;
    BDRVVVFATState *s = bs->opaque;
    qemu_co_mutex_lock(&s->lock);
    ret = vvfat_write(bs, sector_num, buf, nb_sectors);
    qemu_co_mutex_unlock(&s->lock);
    return ret;
}

static int coroutine_fn vvfat_co_is_allocated(BlockDriverState *bs,
	int64_t sector_num, int nb_sectors, int* n)
{
    BDRVVVFATState* s = bs->opaque;
    *n = s->sector_count - sector_num;
    if (*n > nb_sectors)
	*n = nb_sectors;
    else if (*n < 0)
	return 0;
    return 1;
}

static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
	const uint8_t* buffer, int nb_sectors) {
    BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
    return try_commit(s);
}

static void write_target_close(BlockDriverState *bs) {
    BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
    bdrv_delete(s->qcow);
    g_free(s->qcow_filename);
}

static BlockDriver vvfat_write_target = {
    .format_name        = "vvfat_write_target",
    .bdrv_write         = write_target_commit,
    .bdrv_close         = write_target_close,
};

static int enable_write_target(BDRVVVFATState *s)
{
    BlockDriver *bdrv_qcow;
    QEMUOptionParameter *options;
    int ret;
    int size = sector2cluster(s, s->sector_count);
    s->used_clusters = calloc(size, 1);

    array_init(&(s->commits), sizeof(commit_t));

    s->qcow_filename = g_malloc(1024);
    ret = get_tmp_filename(s->qcow_filename, 1024);
    if (ret < 0) {
        g_free(s->qcow_filename);
        s->qcow_filename = NULL;
        return ret;
    }

    bdrv_qcow = bdrv_find_format("qcow");
    options = parse_option_parameters("", bdrv_qcow->create_options, NULL);
    set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
    set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");

    if (bdrv_create(bdrv_qcow, s->qcow_filename, options) < 0)
	return -1;

    s->qcow = bdrv_new("");
    if (s->qcow == NULL) {
        return -1;
    }

    ret = bdrv_open(s->qcow, s->qcow_filename, NULL,
            BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow);
    if (ret < 0) {
	return ret;
    }

#ifndef _WIN32
    unlink(s->qcow_filename);
#endif

    s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1);
    s->bs->backing_hd->drv = &vvfat_write_target;
    s->bs->backing_hd->opaque = g_malloc(sizeof(void*));
    *(void**)s->bs->backing_hd->opaque = s;

    return 0;
}

static void vvfat_close(BlockDriverState *bs)
{
    BDRVVVFATState *s = bs->opaque;

    vvfat_close_current_file(s);
    array_free(&(s->fat));
    array_free(&(s->directory));
    array_free(&(s->mapping));
    g_free(s->cluster_buffer);

    if (s->qcow) {
        migrate_del_blocker(s->migration_blocker);
        error_free(s->migration_blocker);
    }
}

static BlockDriver bdrv_vvfat = {
    .format_name            = "vvfat",
    .protocol_name          = "fat",
    .instance_size          = sizeof(BDRVVVFATState),

    .bdrv_parse_filename    = vvfat_parse_filename,
    .bdrv_file_open         = vvfat_open,
    .bdrv_close             = vvfat_close,
    .bdrv_rebind            = vvfat_rebind,

    .bdrv_read              = vvfat_co_read,
    .bdrv_write             = vvfat_co_write,
    .bdrv_co_is_allocated   = vvfat_co_is_allocated,
};

static void bdrv_vvfat_init(void)
{
    bdrv_register(&bdrv_vvfat);
}

block_init(bdrv_vvfat_init);

#ifdef DEBUG
static void checkpoint(void) {
    assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
    check1(vvv);
    check2(vvv);
    assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
#if 0
    if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)
	fprintf(stderr, "Nonono!\n");
    mapping_t* mapping;
    direntry_t* direntry;
    assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);
    assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);
    if (vvv->mapping.next<47)
	return;
    assert((mapping = array_get(&(vvv->mapping), 47)));
    assert(mapping->dir_index < vvv->directory.next);
    direntry = array_get(&(vvv->directory), mapping->dir_index);
    assert(!memcmp(direntry->name, "USB     H  ", 11) || direntry->name[0]==0);
#endif
}
#endif
