OSDN Git Service

Erase whole clusters instead of sectors. This fixes write performance regression...
authorresver <resver@60bc1c72-a15a-11de-b98f-4500b42dc123>
Sat, 12 Nov 2011 21:27:00 +0000 (21:27 +0000)
committerresver <resver@60bc1c72-a15a-11de-b98f-4500b42dc123>
Sat, 12 Nov 2011 21:27:00 +0000 (21:27 +0000)
git-svn-id: http://exfat.googlecode.com/svn/trunk@231 60bc1c72-a15a-11de-b98f-4500b42dc123

libexfat/cluster.c
libexfat/exfat.h
libexfat/mount.c

index 8bea507..7251c31 100644 (file)
@@ -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;
 }
index 84673dc..b7ee139 100644 (file)
@@ -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;
index 4240f63..17e6c16 100644 (file)
@@ -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)