From 1688f2775f1468ed5be0b01bd8518f2d7144b808 Mon Sep 17 00:00:00 2001 From: relan Date: Mon, 22 Jul 2013 18:04:26 +0000 Subject: [PATCH] Implement fsync() and fsyncdir(). --- fuse/main.c | 11 +++++++++++ libexfat/cluster.c | 11 +++++++---- libexfat/exfat.h | 2 +- libexfat/node.c | 9 +++++---- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/fuse/main.c b/fuse/main.c index 6e16f3a..4bf553e 100644 --- a/fuse/main.c +++ b/fuse/main.c @@ -154,6 +154,15 @@ static int fuse_exfat_release(const char* path, struct fuse_file_info* fi) return 0; } +static int fuse_exfat_fsync(const char* path, int datasync, + struct fuse_file_info *fi) +{ + exfat_debug("[%s] %s", __func__, path); + exfat_flush_node(&ef, get_node(fi)); + exfat_flush(&ef); + return exfat_fsync(ef.dev); +} + static int fuse_exfat_read(const char* path, char* buffer, size_t size, off_t offset, struct fuse_file_info* fi) { @@ -315,6 +324,8 @@ static struct fuse_operations fuse_exfat_ops = .readdir = fuse_exfat_readdir, .open = fuse_exfat_open, .release = fuse_exfat_release, + .fsync = fuse_exfat_fsync, + .fsyncdir = fuse_exfat_fsync, .read = fuse_exfat_read, .write = fuse_exfat_write, .unlink = fuse_exfat_unlink, diff --git a/libexfat/cluster.c b/libexfat/cluster.c index d020d36..5a13d23 100644 --- a/libexfat/cluster.c +++ b/libexfat/cluster.c @@ -129,11 +129,14 @@ static cluster_t find_bit_and_set(uint8_t* bitmap, size_t start, size_t end) return EXFAT_CLUSTER_END; } -void exfat_flush_cmap(struct exfat* ef) +void exfat_flush(struct exfat* ef) { - exfat_pwrite(ef->dev, ef->cmap.chunk, (ef->cmap.chunk_size + 7) / 8, - exfat_c2o(ef, ef->cmap.start_cluster)); - ef->cmap.dirty = false; + if (ef->cmap.dirty) + { + exfat_pwrite(ef->dev, ef->cmap.chunk, (ef->cmap.chunk_size + 7) / 8, + exfat_c2o(ef, ef->cmap.start_cluster)); + ef->cmap.dirty = false; + } } static void set_next_cluster(const struct exfat* ef, bool contiguous, diff --git a/libexfat/exfat.h b/libexfat/exfat.h index e2539b9..f7825d3 100644 --- a/libexfat/exfat.h +++ b/libexfat/exfat.h @@ -162,7 +162,7 @@ cluster_t exfat_next_cluster(const struct exfat* ef, const struct exfat_node* node, cluster_t cluster); cluster_t exfat_advance_cluster(const struct exfat* ef, struct exfat_node* node, uint32_t count); -void exfat_flush_cmap(struct exfat* ef); +void exfat_flush(struct exfat* ef); 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); diff --git a/libexfat/node.c b/libexfat/node.c index 0c6800d..58ec3db 100644 --- a/libexfat/node.c +++ b/libexfat/node.c @@ -53,16 +53,14 @@ void exfat_put_node(struct exfat* ef, struct exfat_node* node) if (node->references == 0) { - if (node->flags & EXFAT_ATTRIB_DIRTY) - exfat_flush_node(ef, node); + exfat_flush_node(ef, node); if (node->flags & EXFAT_ATTRIB_UNLINKED) { /* free all clusters and node structure itself */ exfat_truncate(ef, node, 0, true); free(node); } - if (ef->cmap.dirty) - exfat_flush_cmap(ef); + exfat_flush(ef); } } @@ -526,6 +524,9 @@ void exfat_flush_node(struct exfat* ef, struct exfat_node* node) struct exfat_entry_meta1 meta1; struct exfat_entry_meta2 meta2; + if (!(node->flags & EXFAT_ATTRIB_DIRTY)) + return; /* no need to flush */ + if (ef->ro) exfat_bug("unable to flush node to read-only FS"); -- 2.11.0