Add support for atomic open(O_TRUNC)
authorMiklos Szeredi <miklos@szeredi.hu>
Fri, 8 Feb 2008 17:46:57 +0000 (17:46 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Fri, 8 Feb 2008 17:46:57 +0000 (17:46 +0000)
ChangeLog
include/fuse_common.h
lib/fuse.c
lib/fuse_lowlevel.c
lib/helper.c
lib/mount.c
lib/mount_bsd.c

index 7149a0788b36d92efaa2023815647e4d1003164d..f06cf1dfbd189a72c0e37f5d4b1da2c494378edc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,8 @@
        * Allow operations with a NULL path argument, if the filesystem
        supports it
 
+       * Add support for atomic open(O_TRUNC)
+
 2008-02-03  Csaba Henk <csaba.henk@creo.hu>
 
        * lib/mount_bsd.c:
index 5f50d60ee6a921674aef83c28cdcc8c60e31f9d5..103013919d5a7e180d9e09e474a9bc6f157b9a44 100644 (file)
@@ -109,10 +109,15 @@ struct fuse_conn_info {
         */
        unsigned max_readahead;
 
+       /**
+        * Is atomic open+truncate supported
+        */
+       unsigned atomic_o_trunc;
+
        /**
         * For future use.
         */
-       unsigned reserved[27];
+       unsigned reserved[26];
 };
 
 struct fuse_session;
index a15b5c26dceb1cd9c6cac9c413d8bc005e060ed5..3cc57e402c3f928943bb992d1e8ac12fac4dba65 100644 (file)
@@ -2915,21 +2915,21 @@ static const struct fuse_opt fuse_lib_opts[] = {
 static void fuse_lib_help(void)
 {
        fprintf(stderr,
-"    -o hard_remove        immediate removal (don't hide files)\n"
-"    -o use_ino                    let filesystem set inode numbers\n"
-"    -o readdir_ino        try to fill in d_ino in readdir\n"
-"    -o direct_io          use direct I/O\n"
-"    -o kernel_cache       cache files in kernel\n"
-"    -o [no]auto_cache     enable caching based on modification times\n"
-"    -o umask=M                    set file permissions (octal)\n"
-"    -o uid=N              set file owner\n"
-"    -o gid=N              set file group\n"
-"    -o entry_timeout=T            cache timeout for names (1.0s)\n"
+"    -o hard_remove         immediate removal (don't hide files)\n"
+"    -o use_ino             let filesystem set inode numbers\n"
+"    -o readdir_ino         try to fill in d_ino in readdir\n"
+"    -o direct_io           use direct I/O\n"
+"    -o kernel_cache        cache files in kernel\n"
+"    -o [no]auto_cache      enable caching based on modification times\n"
+"    -o umask=M             set file permissions (octal)\n"
+"    -o uid=N               set file owner\n"
+"    -o gid=N               set file group\n"
+"    -o entry_timeout=T     cache timeout for names (1.0s)\n"
 "    -o negative_timeout=T  cache timeout for deleted names (0.0s)\n"
-"    -o attr_timeout=T     cache timeout for attributes (1.0s)\n"
+"    -o attr_timeout=T      cache timeout for attributes (1.0s)\n"
 "    -o ac_attr_timeout=T   auto cache timeout for attributes (attr_timeout)\n"
-"    -o intr               allow requests to be interrupted\n"
-"    -o intr_signal=NUM            signal to send on interrupt (%i)\n"
+"    -o intr                allow requests to be interrupted\n"
+"    -o intr_signal=NUM     signal to send on interrupt (%i)\n"
 "    -o modules=M1[:M2...]  names of modules to push onto filesystem stack\n"
 "\n", FUSE_DEFAULT_INTR_SIGNAL);
 }
index d1ef7b247e87472f95999be718b3993d4f7135c6..75906b9efa082958266a217d0834e76ffd822aa4 100644 (file)
@@ -1008,9 +1008,12 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
                        f->conn.async_read = arg->flags & FUSE_ASYNC_READ;
                if (arg->max_readahead < f->conn.max_readahead)
                        f->conn.max_readahead = arg->max_readahead;
+               if (f->conn.atomic_o_trunc)
+                       f->conn.atomic_o_trunc = arg->flags & FUSE_ATOMIC_O_TRUNC;
        } else {
                f->conn.async_read = 0;
                f->conn.max_readahead = 0;
+               f->conn.atomic_o_trunc = 0;
        }
 
        if (bufsize < FUSE_MIN_READ_BUFFER) {
@@ -1034,6 +1037,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
                outarg.flags |= FUSE_ASYNC_READ;
        if (f->op.getlk && f->op.setlk)
                outarg.flags |= FUSE_POSIX_LOCKS;
+       if (f->conn.atomic_o_trunc)
+               outarg.flags |= FUSE_ATOMIC_O_TRUNC;
        outarg.max_readahead = f->conn.max_readahead;
        outarg.max_write = f->conn.max_write;
 
@@ -1214,6 +1219,7 @@ static struct fuse_opt fuse_ll_opts[] = {
        { "max_readahead=%u", offsetof(struct fuse_ll, conn.max_readahead), 0 },
        { "async_read", offsetof(struct fuse_ll, conn.async_read), 1 },
        { "sync_read", offsetof(struct fuse_ll, conn.async_read), 0 },
+       { "atomic_o_trunc", offsetof(struct fuse_ll, conn.atomic_o_trunc), 1},
        FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD),
        FUSE_OPT_KEY("-h", KEY_HELP),
        FUSE_OPT_KEY("--help", KEY_HELP),
@@ -1231,10 +1237,11 @@ static void fuse_ll_version(void)
 static void fuse_ll_help(void)
 {
        fprintf(stderr,
-"    -o max_write=N        set maximum size of write requests\n"
-"    -o max_readahead=N            set maximum readahead\n"
-"    -o async_read         perform reads asynchronously (default)\n"
-"    -o sync_read          perform reads synchronously\n");
+"    -o max_write=N         set maximum size of write requests\n"
+"    -o max_readahead=N     set maximum readahead\n"
+"    -o async_read          perform reads asynchronously (default)\n"
+"    -o sync_read           perform reads synchronously\n"
+"    -o atomic_o_trunc      enable atomic open+truncate support\n");
 }
 
 static int fuse_ll_opt_proc(void *data, const char *arg, int key,
@@ -1306,6 +1313,7 @@ struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,
        f->conn.async_read = 1;
        f->conn.max_write = UINT_MAX;
        f->conn.max_readahead = UINT_MAX;
+       f->conn.atomic_o_trunc = 0;
        list_init_req(&f->list);
        list_init_req(&f->interrupts);
        fuse_mutex_init(&f->lock);
index a175ee902952e7a09c8f40a6109c99cf57a37a78..4e7945c78467e15983a2ae1a6f04f373e94c5d55 100644 (file)
@@ -37,22 +37,22 @@ struct helper_opts {
 #define FUSE_HELPER_OPT(t, p) { t, offsetof(struct helper_opts, p), 1 }
 
 static const struct fuse_opt fuse_helper_opts[] = {
-       FUSE_HELPER_OPT("-d",          foreground),
-       FUSE_HELPER_OPT("debug",       foreground),
-       FUSE_HELPER_OPT("-f",          foreground),
-       FUSE_HELPER_OPT("-s",          singlethread),
-       FUSE_HELPER_OPT("fsname=",     nodefault_subtype),
-       FUSE_HELPER_OPT("subtype=",    nodefault_subtype),
-
-       FUSE_OPT_KEY("-h",          KEY_HELP),
-       FUSE_OPT_KEY("--help",      KEY_HELP),
-       FUSE_OPT_KEY("-ho",         KEY_HELP_NOHEADER),
-       FUSE_OPT_KEY("-V",          KEY_VERSION),
-       FUSE_OPT_KEY("--version",   KEY_VERSION),
-       FUSE_OPT_KEY("-d",          FUSE_OPT_KEY_KEEP),
-       FUSE_OPT_KEY("debug",       FUSE_OPT_KEY_KEEP),
-       FUSE_OPT_KEY("fsname=",     FUSE_OPT_KEY_KEEP),
-       FUSE_OPT_KEY("subtype=",    FUSE_OPT_KEY_KEEP),
+       FUSE_HELPER_OPT("-d",           foreground),
+       FUSE_HELPER_OPT("debug",        foreground),
+       FUSE_HELPER_OPT("-f",           foreground),
+       FUSE_HELPER_OPT("-s",           singlethread),
+       FUSE_HELPER_OPT("fsname=",      nodefault_subtype),
+       FUSE_HELPER_OPT("subtype=",     nodefault_subtype),
+
+       FUSE_OPT_KEY("-h",              KEY_HELP),
+       FUSE_OPT_KEY("--help",          KEY_HELP),
+       FUSE_OPT_KEY("-ho",             KEY_HELP_NOHEADER),
+       FUSE_OPT_KEY("-V",              KEY_VERSION),
+       FUSE_OPT_KEY("--version",       KEY_VERSION),
+       FUSE_OPT_KEY("-d",              FUSE_OPT_KEY_KEEP),
+       FUSE_OPT_KEY("debug",           FUSE_OPT_KEY_KEEP),
+       FUSE_OPT_KEY("fsname=",         FUSE_OPT_KEY_KEEP),
+       FUSE_OPT_KEY("subtype=",        FUSE_OPT_KEY_KEEP),
        FUSE_OPT_END
 };
 
@@ -62,9 +62,9 @@ static void usage(const char *progname)
                "usage: %s mountpoint [options]\n\n", progname);
        fprintf(stderr,
                "general options:\n"
-               "    -o opt,[opt...]        mount options\n"
-               "    -h   --help            print help\n"
-               "    -V   --version         print version\n"
+               "    -o opt,[opt...]        mount options\n"
+               "    -h   --help            print help\n"
+               "    -V   --version         print version\n"
                "\n");
 }
 
@@ -72,9 +72,9 @@ static void helper_help(void)
 {
        fprintf(stderr,
                "FUSE options:\n"
-               "    -d   -o debug          enable debug output (implies -f)\n"
-               "    -f                     foreground operation\n"
-               "    -s                     disable multi-threaded operation\n"
+               "    -d   -o debug          enable debug output (implies -f)\n"
+               "    -f                     foreground operation\n"
+               "    -s                     disable multi-threaded operation\n"
                "\n"
                );
 }
index 14fbfb511fe9f36d3dbf5300d6ff60e52f24f98c..ed5f56d2778e3b4ebe4cd6c615fa124f2e691144 100644 (file)
@@ -66,56 +66,56 @@ struct mount_opts {
 #define FUSE_MOUNT_OPT(t, p) { t, offsetof(struct mount_opts, p), 1 }
 
 static const struct fuse_opt fuse_mount_opts[] = {
-       FUSE_MOUNT_OPT("allow_other",       allow_other),
-       FUSE_MOUNT_OPT("allow_root",        allow_root),
-       FUSE_MOUNT_OPT("nonempty",          nonempty),
-       FUSE_MOUNT_OPT("blkdev",            blkdev),
-       FUSE_MOUNT_OPT("fsname=%s",         fsname),
-       FUSE_MOUNT_OPT("subtype=%s",        subtype),
-       FUSE_OPT_KEY("allow_other",         KEY_KERN_OPT),
-       FUSE_OPT_KEY("allow_root",          KEY_ALLOW_ROOT),
-       FUSE_OPT_KEY("nonempty",            KEY_FUSERMOUNT_OPT),
-       FUSE_OPT_KEY("blkdev",              KEY_FUSERMOUNT_OPT),
-       FUSE_OPT_KEY("fsname=",             KEY_FUSERMOUNT_OPT),
-       FUSE_OPT_KEY("subtype=",            KEY_SUBTYPE_OPT),
-       FUSE_OPT_KEY("large_read",          KEY_KERN_OPT),
-       FUSE_OPT_KEY("blksize=",            KEY_KERN_OPT),
-       FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
-       FUSE_OPT_KEY("max_read=",           KEY_KERN_OPT),
-       FUSE_OPT_KEY("max_read=",           FUSE_OPT_KEY_KEEP),
-       FUSE_OPT_KEY("user=",               KEY_MTAB_OPT),
-       FUSE_OPT_KEY("-r",                  KEY_RO),
-       FUSE_OPT_KEY("ro",                  KEY_KERN_FLAG),
-       FUSE_OPT_KEY("rw",                  KEY_KERN_FLAG),
-       FUSE_OPT_KEY("suid",                KEY_KERN_FLAG),
-       FUSE_OPT_KEY("nosuid",              KEY_KERN_FLAG),
-       FUSE_OPT_KEY("dev",                 KEY_KERN_FLAG),
-       FUSE_OPT_KEY("nodev",               KEY_KERN_FLAG),
-       FUSE_OPT_KEY("exec",                KEY_KERN_FLAG),
-       FUSE_OPT_KEY("noexec",              KEY_KERN_FLAG),
-       FUSE_OPT_KEY("async",               KEY_KERN_FLAG),
-       FUSE_OPT_KEY("sync",                KEY_KERN_FLAG),
-       FUSE_OPT_KEY("dirsync",             KEY_KERN_FLAG),
-       FUSE_OPT_KEY("atime",               KEY_KERN_FLAG),
-       FUSE_OPT_KEY("noatime",             KEY_KERN_FLAG),
-       FUSE_OPT_KEY("-h",                  KEY_HELP),
-       FUSE_OPT_KEY("--help",              KEY_HELP),
-       FUSE_OPT_KEY("-V",                  KEY_VERSION),
-       FUSE_OPT_KEY("--version",           KEY_VERSION),
+       FUSE_MOUNT_OPT("allow_other",           allow_other),
+       FUSE_MOUNT_OPT("allow_root",            allow_root),
+       FUSE_MOUNT_OPT("nonempty",              nonempty),
+       FUSE_MOUNT_OPT("blkdev",                blkdev),
+       FUSE_MOUNT_OPT("fsname=%s",             fsname),
+       FUSE_MOUNT_OPT("subtype=%s",            subtype),
+       FUSE_OPT_KEY("allow_other",             KEY_KERN_OPT),
+       FUSE_OPT_KEY("allow_root",              KEY_ALLOW_ROOT),
+       FUSE_OPT_KEY("nonempty",                KEY_FUSERMOUNT_OPT),
+       FUSE_OPT_KEY("blkdev",                  KEY_FUSERMOUNT_OPT),
+       FUSE_OPT_KEY("fsname=",                 KEY_FUSERMOUNT_OPT),
+       FUSE_OPT_KEY("subtype=",                KEY_SUBTYPE_OPT),
+       FUSE_OPT_KEY("large_read",              KEY_KERN_OPT),
+       FUSE_OPT_KEY("blksize=",                KEY_KERN_OPT),
+       FUSE_OPT_KEY("default_permissions",     KEY_KERN_OPT),
+       FUSE_OPT_KEY("max_read=",               KEY_KERN_OPT),
+       FUSE_OPT_KEY("max_read=",               FUSE_OPT_KEY_KEEP),
+       FUSE_OPT_KEY("user=",                   KEY_MTAB_OPT),
+       FUSE_OPT_KEY("-r",                      KEY_RO),
+       FUSE_OPT_KEY("ro",                      KEY_KERN_FLAG),
+       FUSE_OPT_KEY("rw",                      KEY_KERN_FLAG),
+       FUSE_OPT_KEY("suid",                    KEY_KERN_FLAG),
+       FUSE_OPT_KEY("nosuid",                  KEY_KERN_FLAG),
+       FUSE_OPT_KEY("dev",                     KEY_KERN_FLAG),
+       FUSE_OPT_KEY("nodev",                   KEY_KERN_FLAG),
+       FUSE_OPT_KEY("exec",                    KEY_KERN_FLAG),
+       FUSE_OPT_KEY("noexec",                  KEY_KERN_FLAG),
+       FUSE_OPT_KEY("async",                   KEY_KERN_FLAG),
+       FUSE_OPT_KEY("sync",                    KEY_KERN_FLAG),
+       FUSE_OPT_KEY("dirsync",                 KEY_KERN_FLAG),
+       FUSE_OPT_KEY("atime",                   KEY_KERN_FLAG),
+       FUSE_OPT_KEY("noatime",                 KEY_KERN_FLAG),
+       FUSE_OPT_KEY("-h",                      KEY_HELP),
+       FUSE_OPT_KEY("--help",                  KEY_HELP),
+       FUSE_OPT_KEY("-V",                      KEY_VERSION),
+       FUSE_OPT_KEY("--version",               KEY_VERSION),
        FUSE_OPT_END
 };
 
 static void mount_help(void)
 {
        fprintf(stderr,
-"    -o allow_other        allow access to other users\n"
-"    -o allow_root         allow access to root\n"
-"    -o nonempty           allow mounts over non-empty file/dir\n"
+"    -o allow_other         allow access to other users\n"
+"    -o allow_root          allow access to root\n"
+"    -o nonempty            allow mounts over non-empty file/dir\n"
 "    -o default_permissions enable permission checking by kernel\n"
-"    -o fsname=NAME        set filesystem name\n"
-"    -o subtype=NAME       set filesystem type\n"
-"    -o large_read         issue large read requests (2.4 only)\n"
-"    -o max_read=N         set maximum size of read requests\n"
+"    -o fsname=NAME         set filesystem name\n"
+"    -o subtype=NAME        set filesystem type\n"
+"    -o large_read          issue large read requests (2.4 only)\n"
+"    -o max_read=N          set maximum size of read requests\n"
 "\n");
 }
 
index cf19a7b2a9caf1c00fd9efdd6beb493ea1637321..62443ac25f99d4a83d7c1748a8049f12faee76c0 100644 (file)
@@ -102,7 +102,7 @@ static const struct fuse_opt fuse_mount_opts[] = {
 static void mount_help(void)
 {
        fprintf(stderr,
-               "    -o allow_root          allow access to root\n"
+               "    -o allow_root          allow access to root\n"
                );
        system(FUSERMOUNT_PROG " --help");
        fputc('\n', stderr);
@@ -156,7 +156,7 @@ void fuse_unmount_compat22(const char *mountpoint)
                "exec 2>/dev/null; "
                "/usr/bin/fstat " FUSE_DEV_TRUNK "* | "
                "/usr/bin/awk 'BEGIN{ getline; if (! ($3 == \"PID\" && $10 == \"NAME\")) exit 1; }; "
-               "              { if ($3 == %d) print $10; }' | "
+               "              { if ($3 == %d) print $10; }' | "
                "/usr/bin/sort | "
                "/usr/bin/uniq | "
                "/usr/bin/awk '{ i += 1; if (i > 1){ exit 1; }; printf; }; END{ if (i == 0) exit 1; }'";