From: relan Date: Tue, 26 Feb 2013 18:58:36 +0000 (+0000) Subject: Avoid extra erase on writes to the end of a file. X-Git-Tag: android-x86-6.0-r1~108 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=36a79d4309268cf7f5b2871e6a6c6b0e1c78839f;p=android-x86%2Fexternal-exfat.git Avoid extra erase on writes to the end of a file. --- diff --git a/fuse/main.c b/fuse/main.c index 53bafc1..cd02599 100644 --- a/fuse/main.c +++ b/fuse/main.c @@ -80,7 +80,7 @@ static int fuse_exfat_truncate(const char* path, off_t size) if (rc != 0) return rc; - rc = exfat_truncate(&ef, node, size); + rc = exfat_truncate(&ef, node, size, true); exfat_put_node(&ef, node); return rc; } diff --git a/libexfat/cluster.c b/libexfat/cluster.c index c462fc3..bd413bd 100644 --- a/libexfat/cluster.c +++ b/libexfat/cluster.c @@ -344,7 +344,8 @@ static int erase_range(struct exfat* ef, struct exfat_node* node, return 0; } -int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size) +int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size, + bool erase) { uint32_t c1 = bytes2clusters(ef, node->size); uint32_t c2 = bytes2clusters(ef, size); @@ -364,9 +365,12 @@ int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size) if (rc != 0) return rc; - rc = erase_range(ef, node, node->size, size); - if (rc != 0) - return rc; + if (erase) + { + rc = erase_range(ef, node, node->size, size); + if (rc != 0) + return rc; + } exfat_update_mtime(node); node->size = size; diff --git a/libexfat/exfat.h b/libexfat/exfat.h index e5fe625..8596efd 100644 --- a/libexfat/exfat.h +++ b/libexfat/exfat.h @@ -164,7 +164,8 @@ cluster_t exfat_next_cluster(const struct exfat* ef, cluster_t exfat_advance_cluster(const struct exfat* ef, struct exfat_node* node, uint32_t count); void exfat_flush_cmap(struct exfat* ef); -int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size); +int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size, + bool erase); uint32_t exfat_count_free_clusters(const struct exfat* ef); int exfat_find_used_sectors(const struct exfat* ef, off_t* a, off_t* b); diff --git a/libexfat/io.c b/libexfat/io.c index 4413aaa..fea3562 100644 --- a/libexfat/io.c +++ b/libexfat/io.c @@ -351,9 +351,12 @@ ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, const char* bufp = buffer; off_t lsize, loffset, remainder; - if (offset + size > node->size) - if (exfat_truncate(ef, node, offset + size) != 0) - return -1; + if (offset > node->size) + if (exfat_truncate(ef, node, offset, true) != 0) + return -1; + if (offset + size > node->size) + if (exfat_truncate(ef, node, offset + size, false) != 0) + return -1; if (size == 0) return 0; diff --git a/libexfat/node.c b/libexfat/node.c index 1f12b5f..2a855dd 100644 --- a/libexfat/node.c +++ b/libexfat/node.c @@ -56,7 +56,7 @@ void exfat_put_node(struct exfat* ef, struct exfat_node* node) if (node->flags & EXFAT_ATTRIB_UNLINKED) { /* free all clusters and node structure itself */ - exfat_truncate(ef, node, 0); + exfat_truncate(ef, node, 0, true); free(node); } if (ef->cmap.dirty) @@ -627,7 +627,7 @@ static int shrink_directory(struct exfat* ef, struct exfat_node* dir, new_size = CLUSTER_SIZE(*ef->sb); if (new_size == dir->size) return 0; - rc = exfat_truncate(ef, dir, new_size); + rc = exfat_truncate(ef, dir, new_size, true); if (rc != 0) return rc; return 0; @@ -673,7 +673,7 @@ static int grow_directory(struct exfat* ef, struct exfat_node* dir, { return exfat_truncate(ef, dir, DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb)) - * CLUSTER_SIZE(*ef->sb)); + * CLUSTER_SIZE(*ef->sb), true); } static int find_slot(struct exfat* ef, struct exfat_node* dir, @@ -826,7 +826,7 @@ int exfat_mkdir(struct exfat* ef, const char* path) if (rc != 0) return 0; /* directories always have at least one cluster */ - rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb)); + rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb), true); if (rc != 0) { delete(ef, node);