+static int fuse_exfat_release(UNUSED const char* path,
+ struct fuse_file_info* fi)
+{
+ /*
+ This handler is called by FUSE on close() syscall. If the FUSE
+ implementation does not call flush handler, we will flush node here.
+ But in this case we will not be able to return an error to the caller.
+ See fuse_exfat_flush() below.
+ */
+ exfat_debug("[%s] %s", __func__, path);
+ exfat_flush_node(&ef, get_node(fi));
+ exfat_put_node(&ef, get_node(fi));
+ return 0; /* FUSE ignores this return value */
+}
+
+static int fuse_exfat_flush(UNUSED const char* path, struct fuse_file_info* fi)
+{
+ /*
+ This handler may be called by FUSE on close() syscall. FUSE also deals
+ with removals of open files, so we don't free clusters on close but
+ only on rmdir and unlink. If the FUSE implementation does not call this
+ handler we will flush node on release. See fuse_exfat_relase() above.
+ */
+ exfat_debug("[%s] %s", __func__, path);
+ return exfat_flush_node(&ef, get_node(fi));
+}
+
+static int fuse_exfat_fsync(UNUSED const char* path, UNUSED int datasync,
+ UNUSED struct fuse_file_info *fi)
+{
+ int rc;
+
+ exfat_debug("[%s] %s", __func__, path);
+ rc = exfat_flush_nodes(&ef);
+ if (rc != 0)
+ return rc;
+ rc = exfat_flush(&ef);
+ if (rc != 0)
+ return rc;
+ return exfat_fsync(ef.dev);
+}
+
+static int fuse_exfat_read(UNUSED const char* path, char* buffer,
+ size_t size, off_t offset, struct fuse_file_info* fi)