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;

}

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;



    

    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;

}

	assert(!strncmp(s->directory.pointer, "QEMU", 4));
static int FUNC_0(BDRVVVFATState* VAR_0,

	int VAR_1, int VAR_2)

{

    direntry_t* direntry = array_get(&(VAR_0->directory), VAR_1);

    uint32_t first_cluster = VAR_1 == 0 ? 0 : begin_of_direntry(direntry);

    mapping_t* mapping = find_mapping_for_cluster(VAR_0, first_cluster);



    int VAR_3 = 0x10 * VAR_0->sectors_per_cluster;

    int VAR_4, VAR_5;

    int VAR_6 = mapping->info.dir.VAR_7;

    int VAR_7 = VAR_6;

    int VAR_8, VAR_9;

    uint32_t c;



DLOG(fprintf(stderr, "FUNC_0 for %VAR_0, VAR_2 %d\n", mapping->path, VAR_2));



    assert(direntry);

    assert(mapping);

    assert(mapping->begin == first_cluster);

    assert(mapping->info.dir.VAR_7 < VAR_0->directory.next);

    assert(mapping->mode & MODE_DIRECTORY);

    assert(VAR_1 == 0 || is_directory(direntry));



    mapping->info.dir.VAR_2 = VAR_2;



    if (first_cluster == 0) {

	VAR_4 = VAR_5 =

	    VAR_0->last_cluster_of_root_directory;

    } else {

	for (VAR_4 = 0, c = first_cluster; !fat_eof(VAR_0, c);

		c = fat_get(VAR_0, c))

	    VAR_4++;



	for (VAR_5 = 0, c = first_cluster; !fat_eof(VAR_0, c);

		c = modified_fat_get(VAR_0, c))

	    VAR_5++;

    }



    if (VAR_5 > VAR_4) {

	if (insert_direntries(VAR_0,

		VAR_6 + VAR_3 * VAR_4,

		VAR_3 * (VAR_5 - VAR_4)) == NULL)

	    return -1;

    } else if (VAR_5 < VAR_4)

	remove_direntries(VAR_0,

		VAR_6 + VAR_3 * VAR_5,

		VAR_3 * (VAR_4 - VAR_5));



    for (c = first_cluster; !fat_eof(VAR_0, c); c = modified_fat_get(VAR_0, c)) {

	void* direntry = array_get(&(VAR_0->directory), VAR_6);

	int VAR_8 = vvfat_read(VAR_0->bs, cluster2sector(VAR_0, c), direntry,

		VAR_0->sectors_per_cluster);

	if (VAR_8)

	    return VAR_8;

	assert(!strncmp(VAR_0->directory.pointer, "QEMU", 4));

	VAR_6 += VAR_3;

    }



    VAR_8 = commit_mappings(VAR_0, first_cluster, VAR_1);

    if (VAR_8)

	return VAR_8;



    

    for (VAR_9 = 0; VAR_9 < VAR_3 * VAR_5; VAR_9++) {

	direntry = array_get(&(VAR_0->directory), VAR_7 + VAR_9);

	if (is_directory(direntry) && !is_dot(direntry)) {

	    mapping = find_mapping_for_cluster(VAR_0, first_cluster);

	    assert(mapping->mode & MODE_DIRECTORY);

	    VAR_8 = FUNC_0(VAR_0, VAR_7 + VAR_9,

		array_index(&(VAR_0->mapping), mapping));

	    if (VAR_8)

		return VAR_8;

	}

    }



    return 0;

}

static int FUNC_0(BDRVVVFATState* VAR_0,
int VAR_1, int VAR_2)
{ direntry_t* direntry = array_get(&(VAR_0->directory), VAR_1); uint32_t first_cluster = VAR_1 == 0 ? 0 : begin_of_direntry(direntry); mapping_t* mapping = find_mapping_for_cluster(VAR_0, first_cluster); int VAR_3 = 0x10 * VAR_0->sectors_per_cluster; int VAR_4, VAR_5; int VAR_6 = mapping->info.dir.VAR_7; int VAR_7 = VAR_6; int VAR_8, VAR_9; uint32_t c; DLOG(fprintf(stderr, "FUNC_0 for %VAR_0, VAR_2 %d\n", mapping->path, VAR_2)); assert(direntry); assert(mapping); assert(mapping->begin == first_cluster); assert(mapping->info.dir.VAR_7 < VAR_0->directory.next); assert(mapping->mode & MODE_DIRECTORY); assert(VAR_1 == 0 || is_directory(direntry)); mapping->info.dir.VAR_2 = VAR_2; if (first_cluster == 0) { VAR_4 = VAR_5 =
VAR_0->last_cluster_of_root_directory; } else { for (VAR_4 = 0, c = first_cluster; !fat_eof(VAR_0, c); c = fat_get(VAR_0, c))
VAR_4++; for (VAR_5 = 0, c = first_cluster; !fat_eof(VAR_0, c); c = modified_fat_get(VAR_0, c))
VAR_5++; } if (VAR_5 > VAR_4) { if (insert_direntries(VAR_0,
VAR_6 + VAR_3 * VAR_4,
VAR_3 * (VAR_5 - VAR_4)) == NULL)
return -1; } else if (VAR_5 < VAR_4) remove_direntries(VAR_0,
VAR_6 + VAR_3 * VAR_5,
VAR_3 * (VAR_4 - VAR_5)); for (c = first_cluster; !fat_eof(VAR_0, c); c = modified_fat_get(VAR_0, c)) { void* direntry = array_get(&(VAR_0->directory), VAR_6); int VAR_8 = vvfat_read(VAR_0->bs, cluster2sector(VAR_0, c), direntry,
VAR_0->sectors_per_cluster); if (VAR_8)
return VAR_8; assert(!strncmp(VAR_0->directory.pointer, "QEMU", 4)); VAR_6 += VAR_3; } VAR_8 = commit_mappings(VAR_0, first_cluster, VAR_1); if (VAR_8)
return VAR_8; for (VAR_9 = 0; VAR_9 < VAR_3 * VAR_5; VAR_9++) { direntry = array_get(&(VAR_0->directory), VAR_7 + VAR_9); if (is_directory(direntry) && !is_dot(direntry)) { mapping = find_mapping_for_cluster(VAR_0, first_cluster); assert(mapping->mode & MODE_DIRECTORY); VAR_8 = FUNC_0(VAR_0, VAR_7 + VAR_9,
array_index(&(VAR_0->mapping), mapping)); if (VAR_8)
return VAR_8; } } return 0; }