From: resver Date: Sat, 12 Nov 2011 21:27:00 +0000 (+0000) Subject: Erase whole clusters instead of sectors. This fixes write performance regression... X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=4ba683be8ebb02c5eb4d3a574cc14dab4f177216;p=android-x86%2Fexternal-exfat.git Erase whole clusters instead of sectors. This fixes write performance regression caused by r207. git-svn-id: http://exfat.googlecode.com/svn/trunk@231 60bc1c72-a15a-11de-b98f-4500b42dc123 --- diff --git a/libexfat/cluster.c b/libexfat/cluster.c index 8bea507..7251c31 100644 --- a/libexfat/cluster.c +++ b/libexfat/cluster.c @@ -325,37 +325,38 @@ static int shrink_file(struct exfat* ef, struct exfat_node* node, static void erase_raw(struct exfat* ef, size_t size, off_t offset) { - exfat_write_raw(ef->zero_sector, size, offset, ef->fd); + exfat_write_raw(ef->zero_cluster, size, offset, ef->fd); } static int erase_range(struct exfat* ef, struct exfat_node* node, uint64_t begin, uint64_t end) { - uint64_t sector_boundary; + uint64_t cluster_boundary; cluster_t cluster; if (begin >= end) return 0; - sector_boundary = (node->size | (SECTOR_SIZE(*ef->sb) - 1)) + 1; + cluster_boundary = (begin | (CLUSTER_SIZE(*ef->sb) - 1)) + 1; cluster = exfat_advance_cluster(ef, node, - node->size / CLUSTER_SIZE(*ef->sb)); + begin / CLUSTER_SIZE(*ef->sb)); if (CLUSTER_INVALID(cluster)) { exfat_error("invalid cluster in file"); return -EIO; } - /* erase from the beginning to the closest sector boundary */ - erase_raw(ef, MIN(sector_boundary, end) - node->size, - exfat_c2o(ef, cluster) + node->size % CLUSTER_SIZE(*ef->sb)); - /* erase whole sectors */ - while (sector_boundary < end) + /* erase from the beginning to the closest cluster boundary */ + erase_raw(ef, MIN(cluster_boundary, end) - begin, + exfat_c2o(ef, cluster) + begin % CLUSTER_SIZE(*ef->sb)); + /* erase whole clusters */ + while (cluster_boundary < end) { - if (sector_boundary % CLUSTER_SIZE(*ef->sb) == 0) - cluster = exfat_next_cluster(ef, node, cluster); - erase_raw(ef, SECTOR_SIZE(*ef->sb), - exfat_c2o(ef, cluster) + sector_boundary % CLUSTER_SIZE(*ef->sb)); - sector_boundary += SECTOR_SIZE(*ef->sb); + cluster = exfat_next_cluster(ef, node, cluster); + /* the cluster cannot be invalid because we have just allocated it */ + if (CLUSTER_INVALID(cluster)) + exfat_bug("invalid cluster in file"); + erase_raw(ef, CLUSTER_SIZE(*ef->sb), exfat_c2o(ef, cluster)); + cluster_boundary += CLUSTER_SIZE(*ef->sb); } return 0; } diff --git a/libexfat/exfat.h b/libexfat/exfat.h index 84673dc..b7ee139 100644 --- a/libexfat/exfat.h +++ b/libexfat/exfat.h @@ -87,7 +87,7 @@ struct exfat cmap; char label[EXFAT_ENAME_MAX * 6 + 1]; /* a character can occupy up to 6 bytes in UTF-8 */ - void* zero_sector; + void* zero_cluster; int dmask, fmask; uid_t uid; gid_t gid; diff --git a/libexfat/mount.c b/libexfat/mount.c index 4240f63..17e6c16 100644 --- a/libexfat/mount.c +++ b/libexfat/mount.c @@ -173,28 +173,29 @@ int exfat_mount(struct exfat* ef, const char* spec, const char* options) return -EIO; } - ef->zero_sector = malloc(SECTOR_SIZE(*ef->sb)); - if (ef->zero_sector == NULL) + ef->zero_cluster = malloc(CLUSTER_SIZE(*ef->sb)); + if (ef->zero_cluster == NULL) { close(ef->fd); free(ef->sb); exfat_error("failed to allocate zero sector"); return -ENOMEM; } - /* use zero_sector as a temporary buffer for VBR checksum verification */ - if (verify_vbr_checksum(ef->zero_sector, SECTOR_SIZE(*ef->sb), ef->fd) != 0) + /* use zero_cluster as a temporary buffer for VBR checksum verification */ + if (verify_vbr_checksum(ef->zero_cluster, SECTOR_SIZE(*ef->sb), + ef->fd) != 0) { - free(ef->zero_sector); + free(ef->zero_cluster); close(ef->fd); free(ef->sb); return -EIO; } - memset(ef->zero_sector, 0, SECTOR_SIZE(*ef->sb)); + memset(ef->zero_cluster, 0, CLUSTER_SIZE(*ef->sb)); ef->root = malloc(sizeof(struct exfat_node)); if (ef->root == NULL) { - free(ef->zero_sector); + free(ef->zero_cluster); close(ef->fd); free(ef->sb); exfat_error("failed to allocate root node"); @@ -232,7 +233,7 @@ error: exfat_put_node(ef, ef->root); exfat_reset_cache(ef); free(ef->root); - free(ef->zero_sector); + free(ef->zero_cluster); close(ef->fd); free(ef->sb); return -EIO; @@ -244,8 +245,8 @@ void exfat_unmount(struct exfat* ef) exfat_reset_cache(ef); free(ef->root); ef->root = NULL; - free(ef->zero_sector); - ef->zero_sector = NULL; + free(ef->zero_cluster); + ef->zero_cluster = NULL; free(ef->cmap.chunk); ef->cmap.chunk = NULL; if (fsync(ef->fd) < 0)