From da077510ef8e57f84f199e9845c912806de53b74 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 8 Feb 2008 17:46:57 +0000 Subject: [PATCH] Add support for atomic open(O_TRUNC) --- ChangeLog | 2 + include/fuse_common.h | 7 +++- lib/fuse.c | 26 ++++++------- lib/fuse_lowlevel.c | 16 ++++++-- lib/helper.c | 44 +++++++++++----------- lib/mount.c | 86 +++++++++++++++++++++---------------------- lib/mount_bsd.c | 4 +- 7 files changed, 100 insertions(+), 85 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7149a07..f06cf1d 100644 --- 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 * lib/mount_bsd.c: diff --git a/include/fuse_common.h b/include/fuse_common.h index 5f50d60..1030139 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -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; diff --git a/lib/fuse.c b/lib/fuse.c index a15b5c2..3cc57e4 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -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); } diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index d1ef7b2..75906b9 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -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); diff --git a/lib/helper.c b/lib/helper.c index a175ee9..4e7945c 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -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" ); } diff --git a/lib/mount.c b/lib/mount.c index 14fbfb5..ed5f56d 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -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"); } diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c index cf19a7b..62443ac 100644 --- a/lib/mount_bsd.c +++ b/lib/mount_bsd.c @@ -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; }'"; -- 2.30.2