* 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:
*/
unsigned max_readahead;
+ /**
+ * Is atomic open+truncate supported
+ */
+ unsigned atomic_o_trunc;
+
/**
* For future use.
*/
- unsigned reserved[27];
+ unsigned reserved[26];
};
struct fuse_session;
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);
}
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) {
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;
{ "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),
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,
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);
#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
};
"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");
}
{
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"
);
}
#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");
}
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);
"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; }'";