]> git.sven.stormbind.net Git - sven/fuse-exfat.git/blobdiff - fuse/main.c
New upstream version 1.3.0+git20220115
[sven/fuse-exfat.git] / fuse / main.c
index c645390d3f3b5594122ece7ae05192151967670e..3143693cb6048324ba4f196d1d269b445e9fd64b 100644 (file)
@@ -35,7 +35,7 @@
 #include <unistd.h>
 
 #ifndef DEBUG
-       #define exfat_debug(format, ...)
+       #define exfat_debug(format, ...) do {} while (0)
 #endif
 
 #if !defined(FUSE_VERSION) || (FUSE_VERSION < 26)
@@ -95,7 +95,8 @@ static int fuse_exfat_truncate(const char* path, off_t size)
 }
 
 static int fuse_exfat_readdir(const char* path, void* buffer,
-               fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* fi)
+               fuse_fill_dir_t filler, UNUSED off_t offset,
+               UNUSED struct fuse_file_info* fi)
 {
        struct exfat_node* parent;
        struct exfat_node* node;
@@ -155,7 +156,7 @@ static int fuse_exfat_open(const char* path, struct fuse_file_info* fi)
        return 0;
 }
 
-static int fuse_exfat_create(const char* path, mode_t mode,
+static int fuse_exfat_create(const char* path, UNUSED mode_t mode,
                struct fuse_file_info* fi)
 {
        struct exfat_node* node;
@@ -173,7 +174,8 @@ static int fuse_exfat_create(const char* path, mode_t mode,
        return 0;
 }
 
-static int fuse_exfat_release(const char* path, struct fuse_file_info* fi)
+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
@@ -187,7 +189,7 @@ static int fuse_exfat_release(const char* path, struct fuse_file_info* fi)
        return 0; /* FUSE ignores this return value */
 }
 
-static int fuse_exfat_flush(const char* path, struct fuse_file_info* fi)
+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
@@ -199,8 +201,8 @@ static int fuse_exfat_flush(const char* path, struct fuse_file_info* fi)
        return exfat_flush_node(&ef, get_node(fi));
 }
 
-static int fuse_exfat_fsync(const char* path, int datasync,
-               struct fuse_file_info *fi)
+static int fuse_exfat_fsync(UNUSED const char* path, UNUSED int datasync,
+               UNUSED struct fuse_file_info *fi)
 {
        int rc;
 
@@ -214,15 +216,15 @@ static int fuse_exfat_fsync(const char* path, int datasync,
        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)
+static int fuse_exfat_read(UNUSED const char* path, char* buffer,
+               size_t size, off_t offset, struct fuse_file_info* fi)
 {
        exfat_debug("[%s] %s (%zu bytes)", __func__, path, size);
        return exfat_generic_pread(&ef, get_node(fi), buffer, size, offset);
 }
 
-static int fuse_exfat_write(const char* path, const char* buffer, size_t size,
-               off_t offset, struct fuse_file_info* fi)
+static int fuse_exfat_write(UNUSED const char* path, const char* buffer,
+               size_t size, off_t offset, struct fuse_file_info* fi)
 {
        exfat_debug("[%s] %s (%zu bytes)", __func__, path, size);
        return exfat_generic_pwrite(&ef, get_node(fi), buffer, size, offset);
@@ -264,13 +266,14 @@ static int fuse_exfat_rmdir(const char* path)
        return exfat_cleanup_node(&ef, node);
 }
 
-static int fuse_exfat_mknod(const char* path, mode_t mode, dev_t dev)
+static int fuse_exfat_mknod(const char* path, UNUSED mode_t mode,
+               UNUSED dev_t dev)
 {
        exfat_debug("[%s] %s 0%ho", __func__, path, mode);
        return exfat_mknod(&ef, path);
 }
 
-static int fuse_exfat_mkdir(const char* path, mode_t mode)
+static int fuse_exfat_mkdir(const char* path, UNUSED mode_t mode)
 {
        exfat_debug("[%s] %s 0%ho", __func__, path, mode);
        return exfat_mkdir(&ef, path);
@@ -299,7 +302,7 @@ static int fuse_exfat_utimens(const char* path, const struct timespec tv[2])
        return rc;
 }
 
-static int fuse_exfat_chmod(const char* path, mode_t mode)
+static int fuse_exfat_chmod(UNUSED const char* path, mode_t mode)
 {
        const mode_t VALID_MODE_MASK = S_IFREG | S_IFDIR |
                        S_IRWXU | S_IRWXG | S_IRWXO;
@@ -310,7 +313,7 @@ static int fuse_exfat_chmod(const char* path, mode_t mode)
        return 0;
 }
 
-static int fuse_exfat_chown(const char* path, uid_t uid, gid_t gid)
+static int fuse_exfat_chown(UNUSED const char* path, uid_t uid, gid_t gid)
 {
        exfat_debug("[%s] %s %u:%u", __func__, path, uid, gid);
        if (uid != ef.uid || gid != ef.gid)
@@ -318,7 +321,7 @@ static int fuse_exfat_chown(const char* path, uid_t uid, gid_t gid)
        return 0;
 }
 
-static int fuse_exfat_statfs(const char* path, struct statvfs* sfs)
+static int fuse_exfat_statfs(UNUSED const char* path, struct statvfs* sfs)
 {
        exfat_debug("[%s]", __func__);
 
@@ -348,10 +351,14 @@ static void* fuse_exfat_init(struct fuse_conn_info* fci)
 #ifdef FUSE_CAP_BIG_WRITES
        fci->want |= FUSE_CAP_BIG_WRITES;
 #endif
+
+       /* mark super block as dirty; failure isn't a big deal */
+       exfat_soil_super_block(&ef);
+
        return NULL;
 }
 
-static void fuse_exfat_destroy(void* unused)
+static void fuse_exfat_destroy(UNUSED void* unused)
 {
        exfat_debug("[%s]", __func__);
        exfat_unmount(&ef);
@@ -451,7 +458,7 @@ static char* add_ro_option(char* options, bool ro)
        return ro ? add_option(options, "ro", NULL) : options;
 }
 
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__)
 static char* add_user_option(char* options)
 {
        struct passwd* pw;
@@ -492,12 +499,10 @@ static char* add_fuse_options(char* options, const char* spec, bool ro)
        options = add_ro_option(options, ro);
        if (options == NULL)
                return NULL;
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__)
        options = add_user_option(options);
        if (options == NULL)
                return NULL;
-#endif
-#if defined(__linux__)
        options = add_blksize_option(options, CLUSTER_SIZE(*ef.sb));
        if (options == NULL)
                return NULL;
@@ -505,6 +510,30 @@ static char* add_fuse_options(char* options, const char* spec, bool ro)
        return options;
 }
 
+static char* add_passthrough_fuse_options(char* fuse_options,
+               const char* options)
+{
+       const char* passthrough_list[] =
+       {
+#if defined(__FreeBSD__)
+               "automounted",
+#endif
+               "nonempty",
+               NULL
+       };
+       int i;
+
+       for (i = 0; passthrough_list[i] != NULL; i++)
+               if (exfat_match_option(options, passthrough_list[i]))
+               {
+                       fuse_options = add_option(fuse_options, passthrough_list[i], NULL);
+                       if (fuse_options == NULL)
+                               return NULL;
+               }
+
+       return fuse_options;
+}
+
 static int fuse_exfat_main(char* mount_options, char* mount_point)
 {
        char* argv[] = {"exfat", "-s", "-o", mount_options, mount_point, NULL};
@@ -534,6 +563,8 @@ int main(int argc, char* argv[])
        exfat_options = strdup("ro_fallback");
        if (fuse_options == NULL || exfat_options == NULL)
        {
+               free(fuse_options);
+               free(exfat_options);
                exfat_error("failed to allocate options string");
                return 1;
        }
@@ -559,6 +590,12 @@ int main(int argc, char* argv[])
                                free(fuse_options);
                                return 1;
                        }
+                       fuse_options = add_passthrough_fuse_options(fuse_options, optarg);
+                       if (fuse_options == NULL)
+                       {
+                               free(exfat_options);
+                               return 1;
+                       }
                        break;
                case 'V':
                        free(exfat_options);