OSDN Git Service

Avoid extra erase on writes to the end of a file.
authorresver@gmail.com <resver@gmail.com@60bc1c72-a15a-11de-b98f-4500b42dc123>
Tue, 26 Feb 2013 18:58:36 +0000 (18:58 +0000)
committerresver@gmail.com <resver@gmail.com@60bc1c72-a15a-11de-b98f-4500b42dc123>
Tue, 26 Feb 2013 18:58:36 +0000 (18:58 +0000)
git-svn-id: http://exfat.googlecode.com/svn/trunk@345 60bc1c72-a15a-11de-b98f-4500b42dc123

fuse/main.c
libexfat/cluster.c
libexfat/exfat.h
libexfat/io.c
libexfat/node.c

index 53bafc1..cd02599 100644 (file)
@@ -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;
 }
index c462fc3..bd413bd 100644 (file)
@@ -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;
index e5fe625..8596efd 100644 (file)
@@ -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);
 
index 4413aaa..fea3562 100644 (file)
@@ -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;
 
index 1f12b5f..2a855dd 100644 (file)
@@ -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);