diff 5812a4ad62ca07807ac0bc59f22eb8813e6069bc refs/heads/master
blob - 7f95cb1e3e75bd82aebcee99dcc6813a9ee96827
blob + 36b5edddedc5a9f1e45a3f6042d5d1a770dd5939
--- lib/Makefile
+++ lib/Makefile
@@ -3,7 +3,7 @@
SUBDIR= csu libagentx libarch libc libcbor libcrypto libcurses \
libedit libelf libevent libexpat \
- libfido2 libform libfuse libkeynote libkvm libl libm libmenu \
+ libfido2 libform libkeynote libkvm libl libm libmenu \
libossaudio libpanel libpcap libradius librthread \
librpcsvc libskey libsndio libssl libtls libusbhid \
libutil liby libz
blob - 92cf65b8fc9717c271b18907ad84bf7f44a295cf (mode 644)
blob + /dev/null
--- lib/libfuse/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-# $OpenBSD: Makefile,v 1.17 2018/11/28 21:19:11 mpi Exp $
-
-LIB= fuse
-MAN= fuse_chan_fd.3 fuse_daemonize.3 fuse_destroy.3 fuse_get_context.3 \
- fuse_get_session.3 fuse_loop.3 fuse_main.3 fuse_mount.3 fuse_new.3 \
- fuse_opt.3 fuse_parse_cmdline.3 fuse_set_signal_handlers.3 \
- fuse_setup.3 fuse_teardown.3 fuse_version.3
-
-CFLAGS+= -Wall -Wshadow -Wmissing-prototypes
-CFLAGS+= -Wstrict-prototypes -Wsign-compare
-
-CDIAGFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
-CDIAGFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
-CDIAGFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
-CDIAGFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
-
-# XXX Shouldn't we use a common fuse.h with proper ifdef _KERNEL part?
-CFLAGS+= -I${.CURDIR}
-
-SRCS= debug.c dict.c fuse.c fuse_ops.c fuse_opt.c fuse_subr.c tree.c
-HDRS= fuse.h fuse_opt.h
-
-VERSION_SCRIPT= ${.CURDIR}/Symbols.map
-
-PC_FILES=fuse.pc
-CLEANFILES+=${PC_FILES}
-
-includes:
- @cd ${.CURDIR}; for i in ${HDRS}; do \
- j="cmp -s $$i ${DESTDIR}/usr/include/$$i || \
- ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m 444 \
- $$i ${DESTDIR}/usr/include"; \
- echo $$j; \
- eval "$$j"; \
- done
-
-all: ${PC_FILES}
-${PC_FILES}: fuse_private.h
- /bin/sh ${.CURDIR}/generate_pkgconfig.sh -c ${.CURDIR} -o ${.OBJDIR}
-
-beforeinstall:
- ${INSTALL} ${INSTALL_COPY} -o root -g ${SHAREGRP} \
- -m ${SHAREMODE} ${.OBJDIR}/${PC_FILES} ${DESTDIR}/usr/lib/pkgconfig/
-
-.include <bsd.lib.mk>
blob - 3537e9d0207851a893e6b73a6f7c595df9bb7750 (mode 644)
blob + /dev/null
--- lib/libfuse/Symbols.map
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- global:
- fuse_chan_fd;
- fuse_daemonize;
- fuse_destroy;
- fuse_get_context;
- fuse_get_session;
- fuse_invalidate;
- fuse_is_lib_option;
- fuse_loop;
- fuse_loop_mt;
- fuse_main;
- fuse_mount;
- fuse_new;
- fuse_opt_add_arg;
- fuse_opt_add_opt;
- fuse_opt_add_opt_escaped;
- fuse_opt_free_args;
- fuse_opt_insert_arg;
- fuse_opt_match;
- fuse_opt_parse;
- fuse_parse_cmdline;
- fuse_remove_signal_handlers;
- fuse_set_signal_handlers;
- fuse_setup;
- fuse_teardown;
- fuse_unmount;
- fuse_version;
- local:
- *;
-};
blob - d782911639877c386471e7d45c3c26a442c0054b (mode 644)
blob + /dev/null
--- lib/libfuse/debug.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* $OpenBSD: debug.c,v 1.2 2017/12/13 12:30:18 helg Exp $ */
-/*
- * Copyright (c) 2011 Alexandre Ratchov <alex@caoua.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "debug.h"
-
-/*
- * debug level, -1 means uninitialized
- */
-int ifuse_debug = -1;
-
-void
-ifuse_debug_init(void)
-{
- char *dbg;
-
- /* Default to level 1 unless FUSE_DEBUG environment variable is set. */
- if (ifuse_debug < 0) {
- dbg = issetugid() ? NULL : getenv("FUSE_DEBUG");
- if (!dbg || sscanf(dbg, "%u", &ifuse_debug) != 1)
- ifuse_debug = 1;
- }
-}
blob - 5869e0acf81085f8c78a90ec0a0abc0c379609d2 (mode 644)
blob + /dev/null
--- lib/libfuse/debug.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* $OpenBSD: debug.h,v 1.2 2017/12/13 12:30:18 helg Exp $ */
-/*
- * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef _DEBUG_H_
-#define _DEBUG_H_
-
-#include <stdio.h>
-
-#define DPRINTFN(n, ...) \
- do { \
- if (ifuse_debug >= (n)) \
- fprintf(stderr, __VA_ARGS__); \
- } while(0)
-
-#define DPRINTF(...) \
- do { \
- if (ifuse_debug > 0) \
- fprintf(stderr, __VA_ARGS__); \
- } while(0)
-
-#define DPERROR(s) \
- do { \
- if (ifuse_debug > 0) \
- perror(s); \
- } while(0)
-
-void ifuse_debug_init(void);
-extern int ifuse_debug;
-
-#endif /* _DEBUG_H_ */
blob - dc51c0c2ea6a39685427660981caa0ec05e2e6e7 (mode 644)
blob + /dev/null
--- lib/libfuse/dict.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* $OpenBSD: dict.c,v 1.2 2014/04/28 13:08:34 syl Exp $ */
-
-/*
- * Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
- * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <err.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "fuse_private.h"
-
-#define MAX_DICTKEY_SIZE NAME_MAX
-struct dictentry {
- SPLAY_ENTRY(dictentry) entry;
- char key[MAX_DICTKEY_SIZE + 1];
- void *data;
-};
-
-static int dictentry_cmp(struct dictentry *, struct dictentry *);
-
-SPLAY_PROTOTYPE(dict, dictentry, entry, dictentry_cmp);
-
-int
-dict_check(struct dict *d, const char *k)
-{
- struct dictentry key;
-
- if (strlcpy(key.key, k, sizeof key.key) >= sizeof key.key)
- errx(1, "dict_check(%p, %s): key too large", d, k);
-
- return (SPLAY_FIND(dict, d, &key) != NULL);
-}
-
-void *
-dict_set(struct dict *d, const char *k, void *data)
-{
- struct dictentry *entry, key;
-
- if (strlcpy(key.key, k, sizeof key.key) >= sizeof key.key)
- errx(1, "dict_set(%p, %s): key too large", d, k);
- if ((entry = SPLAY_FIND(dict, d, &key)) == NULL) {
- entry = malloc(sizeof *entry);
- if (entry == NULL)
- return (NULL);
-
- strlcpy(entry->key, k, sizeof entry->key);
- SPLAY_INSERT(dict, d, entry);
- }
-
- entry->data = data;
-
- return (entry);
-}
-
-void *
-dict_get(struct dict *d, const char *k)
-{
- struct dictentry key, *entry;
-
- if (strlcpy(key.key, k, sizeof key.key) >= sizeof key.key)
- errx(1, "dict_get(%p, %s): key too large", d, k);
- if ((entry = SPLAY_FIND(dict, d, &key)) == NULL)
- return (NULL);
-
- return (entry->data);
-}
-
-void *
-dict_pop(struct dict *d, const char *k)
-{
- struct dictentry key, *entry;
- void *data;
-
- if (strlcpy(key.key, k, sizeof key.key) >= sizeof key.key)
- errx(1, "dict_pop(%p, %s): key too large", d, k);
- if ((entry = SPLAY_FIND(dict, d, &key)) == NULL)
- return (NULL);
-
- data = entry->data;
- SPLAY_REMOVE(dict, d, entry);
- free(entry);
-
- return (data);
-}
-
-static int
-dictentry_cmp(struct dictentry *a, struct dictentry *b)
-{
- return strcmp(a->key, b->key);
-}
-
-SPLAY_GENERATE(dict, dictentry, entry, dictentry_cmp);
blob - 2b8c0ebdfc6bf055cc35338221eb338218016db4 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/* $OpenBSD: fuse.c,v 1.51 2019/06/28 13:32:42 deraadt Exp $ */
-/*
- * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-
-#include <miscfs/fuse/fusefs.h>
-
-#include <errno.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "fuse_opt.h"
-#include "fuse_private.h"
-#include "debug.h"
-
-static struct fuse_context *ictx = NULL;
-
-enum {
- KEY_DEBUG,
- KEY_FOREGROUND,
- KEY_HELP,
- KEY_HELP_WITHOUT_HEADER,
- KEY_VERSION,
- KEY_MAXREAD,
- KEY_STUB
-};
-
-/* options supported by fuse_parse_cmdline */
-static struct fuse_opt fuse_core_opts[] = {
- FUSE_OPT_KEY("-d", KEY_DEBUG),
- FUSE_OPT_KEY("debug", KEY_DEBUG),
- FUSE_OPT_KEY("-f", KEY_FOREGROUND),
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-ho", KEY_HELP_WITHOUT_HEADER),
- FUSE_OPT_KEY("-s", KEY_STUB),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
- FUSE_OPT_END
-};
-
-/* options supported by fuse_new */
-#define FUSE_LIB_OPT(o, m) {o, offsetof(struct fuse_config, m), 1}
-static struct fuse_opt fuse_lib_opts[] = {
- FUSE_OPT_KEY("ac_attr_timeout=", KEY_STUB),
- FUSE_OPT_KEY("attr_timeout=", KEY_STUB),
- FUSE_OPT_KEY("auto_cache", KEY_STUB),
- FUSE_OPT_KEY("noauto_cache", KEY_STUB),
- FUSE_OPT_KEY("big_writes", KEY_STUB),
- FUSE_OPT_KEY("debug", KEY_DEBUG),
- FUSE_OPT_KEY("-d", KEY_DEBUG),
- FUSE_OPT_KEY("entry_timeout=", KEY_STUB),
- FUSE_LIB_OPT("gid=", set_gid),
- FUSE_LIB_OPT("gid=%u", gid),
- FUSE_OPT_KEY("hard_remove", KEY_STUB),
- FUSE_OPT_KEY("intr_signal", KEY_STUB),
- FUSE_OPT_KEY("kernel_cache", KEY_STUB),
- FUSE_OPT_KEY("large_read", KEY_STUB),
- FUSE_OPT_KEY("modules=", KEY_STUB),
- FUSE_OPT_KEY("negative_timeout=", KEY_STUB),
- FUSE_OPT_KEY("readdir_ino", KEY_STUB),
- FUSE_OPT_KEY("relatime", KEY_STUB),
- FUSE_OPT_KEY("subtype=", KEY_STUB),
- FUSE_LIB_OPT("uid=", set_uid),
- FUSE_LIB_OPT("uid=%u", uid),
- FUSE_LIB_OPT("use_ino", use_ino),
- FUSE_OPT_KEY("dmask=%o", KEY_STUB),
- FUSE_OPT_KEY("fmask=%o", KEY_STUB),
- FUSE_LIB_OPT("umask=", set_mode),
- FUSE_LIB_OPT("umask=%o", umask),
- FUSE_OPT_END
-};
-
-/* options supported by fuse_mount */
-#define FUSE_MOUNT_OPT(o, m) {o, offsetof(struct fuse_mount_opts, m), 1}
-static struct fuse_opt fuse_mount_opts[] = {
- FUSE_MOUNT_OPT("allow_other", allow_other),
- FUSE_OPT_KEY("allow_root", KEY_STUB),
- FUSE_OPT_KEY("async_read", KEY_STUB),
- FUSE_OPT_KEY("blkdev", KEY_STUB),
- FUSE_OPT_KEY("blksize=", KEY_STUB),
- FUSE_MOUNT_OPT("default_permissions", def_perms),
- FUSE_OPT_KEY("direct_io", KEY_STUB),
- FUSE_MOUNT_OPT("fsname=%s", fsname),
- FUSE_MOUNT_OPT("max_read=%u", max_read),
- FUSE_OPT_KEY("max_readahead", KEY_STUB),
- FUSE_OPT_KEY("max_write", KEY_STUB),
- FUSE_MOUNT_OPT("noatime", noatime),
- FUSE_MOUNT_OPT("nonempty", nonempty),
- FUSE_MOUNT_OPT("-r", rdonly),
- FUSE_MOUNT_OPT("ro", rdonly),
- FUSE_OPT_KEY("ro_fallback", KEY_STUB),
- FUSE_OPT_KEY("sync_read", KEY_STUB),
- FUSE_OPT_END
-};
-
-static void
-ifuse_try_unmount(struct fuse *f)
-{
- pid_t child;
-
- /* unmount in another thread so fuse_loop() doesn't deadlock */
- child = fork();
-
- if (child == -1) {
- DPERROR(__func__);
- return;
- }
-
- if (child == 0) {
- fuse_remove_signal_handlers(fuse_get_session(f));
- errno = 0;
- fuse_unmount(f->fc->dir, f->fc);
- _exit(errno);
- }
-}
-
-static void
-ifuse_child_exit(const struct fuse *f)
-{
- int status;
-
- if (waitpid(WAIT_ANY, &status, WNOHANG) == -1)
- fprintf(stderr, "fuse: %s\n", strerror(errno));
-
- if (WIFEXITED(status) && (WEXITSTATUS(status) != 0))
- fprintf(stderr, "fuse: %s: %s\n",
- f->fc->dir, strerror(WEXITSTATUS(status)));
-
- return;
-}
-
-int
-fuse_loop(struct fuse *fuse)
-{
- struct fusebuf fbuf;
- struct fuse_context ctx;
- struct fb_ioctl_xch ioexch;
- struct kevent event[5];
- struct kevent ev;
- ssize_t n;
- int ret;
-
- if (fuse == NULL)
- return (-1);
-
- fuse->fc->kq = kqueue();
- if (fuse->fc->kq == -1)
- return (-1);
-
- EV_SET(&event[0], fuse->fc->fd, EVFILT_READ, EV_ADD |
- EV_ENABLE, 0, 0, 0);
-
- /* signal events */
- EV_SET(&event[1], SIGCHLD, EVFILT_SIGNAL, EV_ADD |
- EV_ENABLE, 0, 0, 0);
- EV_SET(&event[2], SIGHUP, EVFILT_SIGNAL, EV_ADD |
- EV_ENABLE, 0, 0, 0);
- EV_SET(&event[3], SIGINT, EVFILT_SIGNAL, EV_ADD |
- EV_ENABLE, 0, 0, 0);
- EV_SET(&event[4], SIGTERM, EVFILT_SIGNAL, EV_ADD |
- EV_ENABLE, 0, 0, 0);
-
- while (!fuse->fc->dead) {
- ret = kevent(fuse->fc->kq, &event[0], 5, &ev, 1, NULL);
- if (ret == -1) {
- if (errno != EINTR)
- DPERROR(__func__);
- } else if (ret > 0 && ev.filter == EVFILT_SIGNAL) {
- int signum = ev.ident;
- switch (signum) {
- case SIGCHLD:
- ifuse_child_exit(fuse);
- break;
- case SIGHUP:
- case SIGINT:
- case SIGTERM:
- ifuse_try_unmount(fuse);
- break;
- default:
- fprintf(stderr, "%s: %s\n", __func__,
- strsignal(signum));
- }
- } else if (ret > 0) {
- n = read(fuse->fc->fd, &fbuf, sizeof(fbuf));
- if (n != sizeof(fbuf)) {
- fprintf(stderr, "%s: bad fusebuf read\n",
- __func__);
- return (-1);
- }
-
- /* check if there is data something present */
- if (fbuf.fb_len) {
- fbuf.fb_dat = malloc(fbuf.fb_len);
- if (fbuf.fb_dat == NULL)
- return (-1);
- ioexch.fbxch_uuid = fbuf.fb_uuid;
- ioexch.fbxch_len = fbuf.fb_len;
- ioexch.fbxch_data = fbuf.fb_dat;
-
- if (ioctl(fuse->fc->fd, FIOCGETFBDAT,
- &ioexch) == -1) {
- free(fbuf.fb_dat);
- return (-1);
- }
- }
-
- ctx.fuse = fuse;
- ctx.uid = fbuf.fb_uid;
- ctx.gid = fbuf.fb_gid;
- ctx.pid = fbuf.fb_tid;
- ctx.umask = fbuf.fb_umask;
- ctx.private_data = fuse->private_data;
- ictx = &ctx;
-
- ret = ifuse_exec_opcode(fuse, &fbuf);
- if (ret) {
- ictx = NULL;
- return (-1);
- }
-
- n = write(fuse->fc->fd, &fbuf, sizeof(fbuf));
- if (fbuf.fb_len) {
- if (fbuf.fb_dat == NULL) {
- fprintf(stderr, "%s: fb_dat is Null\n",
- __func__);
- return (-1);
- }
- ioexch.fbxch_uuid = fbuf.fb_uuid;
- ioexch.fbxch_len = fbuf.fb_len;
- ioexch.fbxch_data = fbuf.fb_dat;
-
- if (ioctl(fuse->fc->fd, FIOCSETFBDAT, &ioexch) == -1) {
- free(fbuf.fb_dat);
- return (-1);
- }
- free(fbuf.fb_dat);
- }
- ictx = NULL;
-
- if (n != FUSEBUFSIZE) {
- errno = EINVAL;
- return (-1);
- }
- }
- }
-
- return (0);
-}
-DEF(fuse_loop);
-
-struct fuse_chan *
-fuse_mount(const char *dir, struct fuse_args *args)
-{
- struct fusefs_args fargs;
- struct fuse_mount_opts opts;
- struct fuse_chan *fc;
- const char *errcause;
- int mnt_flags;
-
- if (dir == NULL)
- return (NULL);
-
- fc = calloc(1, sizeof(*fc));
- if (fc == NULL)
- return (NULL);
-
- fc->dir = realpath(dir, NULL);
- if (fc->dir == NULL)
- goto bad;
-
- if ((fc->fd = open("/dev/fuse0", O_RDWR)) == -1) {
- perror(__func__);
- goto bad;
- }
-
- memset(&opts, 0, sizeof(opts));
- if (fuse_opt_parse(args, &opts, fuse_mount_opts, NULL) == -1)
- goto bad;
-
- mnt_flags = 0;
- if (opts.rdonly)
- mnt_flags |= MNT_RDONLY;
- if (opts.noatime)
- mnt_flags |= MNT_NOATIME;
-
- if (opts.max_read > FUSEBUFMAXSIZE) {
- fprintf(stderr, "fuse: invalid max_read (%d > %d)\n",
- opts.max_read, FUSEBUFMAXSIZE);
- goto bad;
- }
-
- memset(&fargs, 0, sizeof(fargs));
- fargs.fd = fc->fd;
- fargs.max_read = opts.max_read;
- fargs.allow_other = opts.allow_other;
-
- if (mount(MOUNT_FUSEFS, fc->dir, mnt_flags, &fargs)) {
- switch (errno) {
- case EMFILE:
- errcause = "mount table full";
- break;
- case EOPNOTSUPP:
- errcause = "filesystem not supported by kernel";
- break;
- default:
- errcause = strerror(errno);
- break;
- }
- fprintf(stderr, "%s on %s: %s\n", __func__, dir, errcause);
- goto bad;
- }
-
- return (fc);
-bad:
- if (fc->fd != -1)
- close(fc->fd);
- free(fc->dir);
- free(fc);
- return (NULL);
-}
-DEF(fuse_mount);
-
-void
-fuse_unmount(const char *dir, struct fuse_chan *ch)
-{
- if (ch == NULL || ch->dead)
- return;
-
- if (unmount(dir, MNT_UPDATE) == -1)
- DPERROR(__func__);
-}
-DEF(fuse_unmount);
-
-int
-fuse_is_lib_option(const char *opt)
-{
- return (fuse_opt_match(fuse_lib_opts, opt));
-}
-
-int
-fuse_chan_fd(struct fuse_chan *ch)
-{
- if (ch == NULL)
- return (-1);
-
- return (ch->fd);
-}
-
-struct fuse_session *
-fuse_get_session(struct fuse *f)
-{
- return (&f->se);
-}
-DEF(fuse_get_session);
-
-int
-fuse_loop_mt(unused struct fuse *fuse)
-{
- return (-1);
-}
-
-static int
-ifuse_lib_opt_proc(void *data, const char *arg, int key,
- unused struct fuse_args *args)
-{
- switch (key) {
- case KEY_STUB:
- return (0);
- case KEY_DEBUG:
- ifuse_debug_init();
- break;
- default:
- fprintf(stderr, "fuse: unrecognised option %s\n", arg);
- return (-1);
- }
-
- /* Keep unknown options. */
- return (1);
-}
-
-struct fuse *
-fuse_new(struct fuse_chan *fc, struct fuse_args *args,
- const struct fuse_operations *ops, unused size_t size,
- void *userdata)
-{
- struct fuse *fuse;
- struct fuse_vnode *root;
-
- if (fc == NULL || ops == NULL)
- return (NULL);
-
- if ((fuse = calloc(1, sizeof(*fuse))) == NULL)
- return (NULL);
-
- /* copy fuse ops to their own structure */
- memcpy(&fuse->op, ops, sizeof(fuse->op));
-
- if (fuse_opt_parse(args, &fuse->conf, fuse_lib_opts,
- ifuse_lib_opt_proc) == -1) {
- free(fuse);
- return (NULL);
- }
-
- fuse->fc = fc;
- fuse->max_ino = FUSE_ROOT_INO;
- fuse->se.args = fuse;
- fuse->private_data = userdata;
-
- if ((root = alloc_vn(fuse, "/", FUSE_ROOT_INO, 0)) == NULL) {
- free(fuse);
- return (NULL);
- }
-
- tree_init(&fuse->vnode_tree);
- tree_init(&fuse->name_tree);
- if (!set_vn(fuse, root)) {
- free(fuse);
- return (NULL);
- }
-
- return (fuse);
-}
-DEF(fuse_new);
-
-int
-fuse_daemonize(int foreground)
-{
- if (foreground)
- return (0);
-
- return (daemon(0, 0));
-}
-DEF(fuse_daemonize);
-
-void
-fuse_destroy(struct fuse *f)
-{
- if (f == NULL)
- return;
-
- /*
- * Even though these were allocated in fuse_mount(), we can't free them
- * in fuse_unmount() since fuse_loop() will not have terminated yet so
- * we free them here.
- */
- close(f->fc->fd);
- free(f->fc->dir);
- free(f->fc);
- free(f);
-}
-DEF(fuse_destroy);
-
-void
-fuse_remove_signal_handlers(unused struct fuse_session *se)
-{
- struct sigaction old_sa;
-
- if (sigaction(SIGHUP, NULL, &old_sa) == 0)
- if (old_sa.sa_handler == SIG_IGN)
- signal(SIGHUP, SIG_DFL);
-
- if (sigaction(SIGINT, NULL, &old_sa) == 0)
- if (old_sa.sa_handler == SIG_IGN)
- signal(SIGINT, SIG_DFL);
-
- if (sigaction(SIGTERM, NULL, &old_sa) == 0)
- if (old_sa.sa_handler == SIG_IGN)
- signal(SIGTERM, SIG_DFL);
-
- if (sigaction(SIGPIPE, NULL, &old_sa) == 0)
- if (old_sa.sa_handler == SIG_IGN)
- signal(SIGPIPE, SIG_DFL);
-
- if (sigaction(SIGCHLD, NULL, &old_sa) == 0)
- if (old_sa.sa_handler == SIG_IGN)
- signal(SIGCHLD, SIG_DFL);
-}
-DEF(fuse_remove_signal_handlers);
-
-int
-fuse_set_signal_handlers(unused struct fuse_session *se)
-{
- struct sigaction old_sa;
-
- if (sigaction(SIGHUP, NULL, &old_sa) == -1)
- return (-1);
- if (old_sa.sa_handler == SIG_DFL)
- signal(SIGHUP, SIG_IGN);
-
- if (sigaction(SIGINT, NULL, &old_sa) == -1)
- return (-1);
- if (old_sa.sa_handler == SIG_DFL)
- signal(SIGINT, SIG_IGN);
-
- if (sigaction(SIGTERM, NULL, &old_sa) == -1)
- return (-1);
- if (old_sa.sa_handler == SIG_DFL)
- signal(SIGTERM, SIG_IGN);
-
- if (sigaction(SIGPIPE, NULL, &old_sa) == -1)
- return (-1);
- if (old_sa.sa_handler == SIG_DFL)
- signal(SIGPIPE, SIG_IGN);
-
- if (sigaction(SIGCHLD, NULL, &old_sa) == -1)
- return (-1);
- if (old_sa.sa_handler == SIG_DFL)
- signal(SIGCHLD, SIG_IGN);
-
- return (0);
-}
-
-static void
-dump_help(void)
-{
- fprintf(stderr, "FUSE options:\n"
- " -d -o debug enable debug output (implies -f)\n"
- " -f run in foreground\n"
- " -V --version print fuse version\n"
- "\n");
-}
-
-static void
-dump_version(void)
-{
- fprintf(stderr, "FUSE library version: %d.%d\n", FUSE_MAJOR_VERSION,
- FUSE_MINOR_VERSION);
-}
-
-static int
-ifuse_process_opt(void *data, const char *arg, int key,
- unused struct fuse_args *args)
-{
- struct fuse_core_opts *opt = data;
- struct stat st;
- int res;
-
- switch (key) {
- case KEY_STUB:
- return (0);
- case KEY_DEBUG:
- ifuse_debug_init();
- /* falls through */
- case KEY_FOREGROUND:
- opt->foreground = 1;
- return (0);
- case KEY_HELP:
- case KEY_HELP_WITHOUT_HEADER:
- dump_help();
- return (-1);
- case KEY_VERSION:
- dump_version();
- return (-1);
- case FUSE_OPT_KEY_NONOPT:
- if (opt->mp == NULL) {
- opt->mp = realpath(arg, opt->mp);
- if (opt->mp == NULL) {
- fprintf(stderr, "fuse: realpath: "
- "%s : %s\n", arg, strerror(errno));
- return (-1);
- }
-
- res = stat(opt->mp, &st);
- if (res == -1) {
- fprintf(stderr, "fuse: bad mount point "
- "%s : %s\n", arg, strerror(errno));
- return (-1);
- }
-
- if (!S_ISDIR(st.st_mode)) {
- fprintf(stderr, "fuse: bad mount point "
- "%s : %s\n", arg, strerror(ENOTDIR));
- return (-1);
- }
- }
- return (0);
- }
-
- /* Pass through unknown options. */
- return (1);
-}
-
-int
-fuse_parse_cmdline(struct fuse_args *args, char **mp, int *mt, int *fg)
-{
- struct fuse_core_opts opt;
-
- memset(&opt, 0, sizeof(opt));
- if (fuse_opt_parse(args, &opt, fuse_core_opts, ifuse_process_opt) == -1)
- return (-1);
-
- if (opt.mp == NULL) {
- fprintf(stderr, "fuse: missing mountpoint parameter\n");
- return (-1);
- }
-
- if (mp != NULL) {
- *mp = strdup(opt.mp);
- if (*mp == NULL)
- return (-1);
- }
-
- if (mt != NULL)
- *mt = 0;
-
- if (fg != NULL)
- *fg = opt.foreground;
-
- return (0);
-}
-DEF(fuse_parse_cmdline);
-
-struct fuse_context *
-fuse_get_context(void)
-{
- return (ictx);
-}
-DEF(fuse_get_context);
-
-int
-fuse_version(void)
-{
- return (FUSE_VERSION);
-}
-
-void
-fuse_teardown(struct fuse *fuse, char *mp)
-{
- if (fuse == NULL || mp == NULL)
- return;
-
- fuse_remove_signal_handlers(fuse_get_session(fuse));
- fuse_unmount(mp, fuse->fc);
- fuse_destroy(fuse);
-}
-
-int
-fuse_invalidate(unused struct fuse *f, unused const char *path)
-{
- return (EINVAL);
-}
-
-struct fuse *
-fuse_setup(int argc, char **argv, const struct fuse_operations *ops,
- size_t size, char **mp, int *mt, void *data)
-{
- struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
- struct fuse_chan *fc;
- struct fuse *fuse;
- char *dir;
- int fg;
-
- dir = NULL;
- if (fuse_parse_cmdline(&args, &dir, mt, &fg))
- goto err;
-
- fuse_daemonize(fg);
-
- if ((fc = fuse_mount(dir, &args)) == NULL)
- goto err;
-
- if ((fuse = fuse_new(fc, &args, ops, size, data)) == NULL) {
- fuse_unmount(dir, fc);
- close(fc->fd);
- free(fc->dir);
- free(fc);
- goto err;
- }
-
- /* args are no longer needed */
- fuse_opt_free_args(&args);
-
- if (fuse_set_signal_handlers(fuse_get_session(fuse)) == -1) {
- fuse_unmount(dir, fc);
- fuse_destroy(fuse);
- goto err;
- }
-
- /* the caller frees dir, but we do it if the caller doesn't want it */
- if (mp == NULL)
- free(dir);
- else
- *mp = dir;
-
- return (fuse);
-err:
- free(dir);
- return (NULL);
-}
-DEF(fuse_setup);
-
-int
-fuse_main(int argc, char **argv, const struct fuse_operations *ops, void *data)
-{
- struct fuse *fuse;
-
- fuse = fuse_setup(argc, argv, ops, sizeof(*ops), NULL, NULL, data);
- if (fuse == NULL)
- return (-1);
-
- return (fuse_loop(fuse));
-}
blob - ee0edaf750aad11655e19b9ca27bdb0025bf9536 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/* $OpenBSD: fuse.h,v 1.14 2018/05/16 13:09:17 helg Exp $ */
-/*
- * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _FUSE_H_
-#define _FUSE_H_
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-
-#include <fcntl.h>
-#include <utime.h>
-
-#include <fuse_opt.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct fuse_chan;
-struct fuse_args;
-struct fuse_session;
-
-struct fuse_file_info {
- int32_t flags; /* open(2) flags */
- uint32_t fh_old; /* old file handle */
- int32_t writepage;
- uint32_t direct_io:1;
- uint32_t keep_cache:1;
- uint32_t flush:1;
- uint32_t nonseekable:1;
- uint32_t __padd:27;
- uint32_t flock_release : 1;
- uint64_t fh; /* file handle */
- uint64_t lock_owner;
-};
-
-/* unused but needed for gvfs compilation */
-#define FUSE_CAP_ASYNC_READ (1 << 0)
-#define FUSE_CAP_POSIX_LOCKS (1 << 1)
-#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
-#define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
-#define FUSE_CAP_BIG_WRITES (1 << 5)
-#define FUSE_CAP_DONT_MASK (1 << 6)
-#define FUSE_CAP_SPLICE_WRITE (1 << 7)
-#define FUSE_CAP_SPLICE_MOVE (1 << 8)
-#define FUSE_CAP_SPLICE_READ (1 << 9)
-#define FUSE_CAP_FLOCK_LOCKS (1 << 10)
-#define FUSE_CAP_IOCTL_DIR (1 << 11)
-
-struct fuse_conn_info {
- uint32_t proto_major;
- uint32_t proto_minor;
- uint32_t async_read;
- uint32_t max_write;
- uint32_t max_readahead;
- uint32_t capable;
- uint32_t want;
- uint32_t max_background;
- uint32_t congestion_threshold;
- uint32_t reserved[23];
-};
-
-struct fuse_context {
- struct fuse * fuse;
- uid_t uid;
- gid_t gid;
- pid_t pid;
- void *private_data;
- mode_t umask;
-};
-
-typedef ino_t fuse_ino_t;
-typedef int (*fuse_fill_dir_t)(void *, const char *, const struct stat *,
- off_t);
-
-typedef struct fuse_dirhandle *fuse_dirh_t;
-typedef int (*fuse_dirfil_t)(fuse_dirh_t, const char *, int, ino_t);
-
-/*
- * Fuse operations work in the same way as their UNIX file system
- * counterparts. A major exception is that these routines return
- * a negated errno value (-errno) on failure.
- */
-struct fuse_operations {
- int (*getattr)(const char *, struct stat *);
- int (*readlink)(const char *, char *, size_t);
- int (*getdir)(const char *, fuse_dirh_t, fuse_dirfil_t);
- int (*mknod)(const char *, mode_t, dev_t);
- int (*mkdir)(const char *, mode_t);
- int (*unlink)(const char *);
- int (*rmdir)(const char *);
- int (*symlink)(const char *, const char *);
- int (*rename)(const char *, const char *);
- int (*link)(const char *, const char *);
- int (*chmod)(const char *, mode_t);
- int (*chown)(const char *, uid_t, gid_t);
- int (*truncate)(const char *, off_t);
- int (*utime)(const char *, struct utimbuf *);
- int (*open)(const char *, struct fuse_file_info *);
- int (*read)(const char *, char *, size_t, off_t,
- struct fuse_file_info *);
- int (*write)(const char *, const char *, size_t, off_t,
- struct fuse_file_info *);
- int (*statfs)(const char *, struct statvfs *);
- int (*flush)(const char *, struct fuse_file_info *);
- int (*release)(const char *, struct fuse_file_info *);
- int (*fsync)(const char *, int, struct fuse_file_info *);
- int (*setxattr)(const char *, const char *, const char *, size_t,
- int);
- int (*getxattr)(const char *, const char *, char *, size_t);
- int (*listxattr)(const char *, char *, size_t);
- int (*removexattr)(const char *, const char *);
- int (*opendir)(const char *, struct fuse_file_info *);
- int (*readdir)(const char *, void *, fuse_fill_dir_t, off_t,
- struct fuse_file_info *);
- int (*releasedir)(const char *, struct fuse_file_info *);
- int (*fsyncdir)(const char *, int, struct fuse_file_info *);
- void *(*init)(struct fuse_conn_info *);
- void (*destroy)(void *);
- int (*access)(const char *, int);
- int (*create)(const char *, mode_t, struct fuse_file_info *);
- int (*ftruncate)(const char *, off_t, struct fuse_file_info *);
- int (*fgetattr)(const char *, struct stat *, struct fuse_file_info *);
- int (*lock)(const char *, struct fuse_file_info *, int, struct flock *);
- int (*utimens)(const char *, const struct timespec *);
- int (*bmap)(const char *, size_t , uint64_t *);
-};
-
-#ifndef FUSE_USE_VERSION
-#define FUSE_USE_VERSION 26
-#endif
-
-#if FUSE_USE_VERSION >= 26
-#define FUSE_VERSION 26
-#else
-#error "Fuse version < 26 not supported"
-#endif
-
-#define FUSE_MAJOR_VERSION 2
-#define FUSE_MINOR_VERSION 6
-
-/*
- * API prototypes
- */
-int fuse_version(void);
-int fuse_main(int, char **, const struct fuse_operations *, void *);
-struct fuse *fuse_new(struct fuse_chan *, struct fuse_args *,
- const struct fuse_operations *, size_t, void *);
-struct fuse *fuse_setup(int, char **, const struct fuse_operations *,
- size_t, char **, int *, void *);
-int fuse_parse_cmdline(struct fuse_args *, char **, int *, int *);
-struct fuse_chan *fuse_mount(const char *, struct fuse_args *);
-void fuse_remove_signal_handlers(struct fuse_session *);
-int fuse_set_signal_handlers(struct fuse_session *);
-struct fuse_session *fuse_get_session(struct fuse *);
-struct fuse_context *fuse_get_context(void);
-int fuse_is_lib_option(const char *);
-int fuse_loop(struct fuse *);
-int fuse_loop_mt(struct fuse *);
-int fuse_chan_fd(struct fuse_chan *);
-void fuse_unmount(const char *, struct fuse_chan *);
-int fuse_daemonize(int);
-void fuse_destroy(struct fuse *);
-void fuse_teardown(struct fuse *, char *);
-int fuse_invalidate(struct fuse *, const char *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FUSE_H_ */
blob - dc00b04ef03698c45270ae527de6c9b530b51b03 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_chan_fd.3
+++ /dev/null
@@ -1,53 +0,0 @@
-.\" $OpenBSD: fuse_chan_fd.3,v 1.2 2018/07/08 06:17:10 jmc Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg.bredow@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: July 8 2018 $
-.Dt FUSE_CHAN_FD 3
-.Os
-.Sh NAME
-.Nm fuse_chan_fd
-.Nd get the file descriptor for an open FUSE device
-.Sh SYNOPSIS
-.In fuse.h
-.Ft int
-.Fn fuse_chan_fd "struct fuse_chan *ch"
-.Sh DESCRIPTION
-.Fn fuse_chan_fd
-will return the file descriptor to the FUSE device opened for reading
-and writing by
-.Xr fuse_mount 3 .
-.Sh RETURN VALUES
-If successful,
-.Fn fuse_chan_fd
-returns a non-negative integer, termed a file descriptor.
-If
-.Fa ch
-is NULL a value of -1 is returned.
-.Sh SEE ALSO
-.Xr fuse_mount 3 ,
-.Xr open 3 ,
-.Xr fuse 4
-.Sh STANDARDS
-The
-.Fn fuse_chan_fd
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_chan_fd
-function first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
blob - dc30a15e232a825c909c045cdc079bcb2ce8fd1c (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_daemonize.3
+++ /dev/null
@@ -1,59 +0,0 @@
-.\" $OpenBSD: fuse_daemonize.3,v 1.3 2018/11/28 21:19:11 mpi Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: November 28 2018 $
-.Dt FUSE_DAEMONIZE 3
-.Os
-.Sh NAME
-.Nm fuse_daemonize
-.Nd run in the background
-.Sh SYNOPSIS
-.In fuse.h
-.Ft int
-.Fn fuse_daemonize "int foreground"
-.Sh DESCRIPTION
-If
-.Fa foreground
-is 1,
-.Fn fuse_daemonize
-will detach from the controlling terminal and run in the background as a
-system daemon.
-Otherwise, the process will continue to run in the foreground.
-.Pp
-The current working directory is changed to the root (/) and standard input;
-standard output and standard error are redirected to /dev/null.
-.Sh RETURN VALUES
-Upon success,
-.Fn fuse_daemonize
-returns 0; otherwise -1 is returned.
-.Sh ERRORS
-.Fn fuse_daemonize
-can fail for the same reasons as
-.Xr daemon 3 .
-.Sh SEE ALSO
-.Xr daemon 3 ,
-.Xr fuse_parse_cmdline 3
-.Sh STANDARDS
-The
-.Fn fuse_daemonize
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_daemonize
-function first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
blob - 3a8b43622b30b9901114ad60ca67bc1b66dc1561 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_destroy.3
+++ /dev/null
@@ -1,52 +0,0 @@
-.\" $OpenBSD: fuse_destroy.3,v 1.2 2018/07/08 06:17:10 jmc Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg.bredow@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: July 8 2018 $
-.Dt FUSE_DESTROY 3
-.Os
-.Sh NAME
-.Nm fuse_destroy
-.Nd free memory associated with a FUSE handle
-.Sh SYNOPSIS
-.In fuse.h
-.Ft void
-.Fn fuse_destroy "struct fuse *f"
-.Sh DESCRIPTION
-.Fn fuse_destroy
-closes the FUSE device and frees memory associated with the FUSE channel
-and FUSE handle specified by
-.Fa f .
-.Pp
-This function does not unmount the file system, which should be done
-with
-.Xr fuse_unmount 3
-before calling this function.
-.Sh SEE ALSO
-.Xr fuse_new 3 ,
-.Xr fuse_teardown 3 ,
-.Xr fuse_unmount 3
-.Sh STANDARDS
-The
-.Fn fuse_destroy
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_destroy
-function first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
-.An Helg Bredow Aq Mt helg@openbsd.org
blob - 9ae67e9aa729e8531a104dd39a3ef67803df4e3e (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_get_context.3
+++ /dev/null
@@ -1,58 +0,0 @@
-.\" $OpenBSD: fuse_get_context.3,v 1.2 2018/08/04 06:10:05 jmc Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: August 4 2018 $
-.Dt FUSE_GET_CONTEXT 3
-.Os
-.Sh NAME
-.Nm fuse_get_context
-.Nd FUSE utility routine
-.Sh SYNOPSIS
-.In fuse.h
-.Ft struct fuse_context *
-.Fn fuse_get_context "void"
-.Sh DESCRIPTION
-.Fn fuse_get_context
-returns a pointer to the structure
-.Fa fuse_context .
-This can be used by file systems to obtain information about the
-thread that is accessing the file system.
-The returned fuse_context is only valid during the lifetime of a FUSE
-operation.
-.Bd -literal
-struct fuse_context {
- struct fuse * fuse;
- uid_t uid; /* effective user id */
- gid_t gid; /* effective group id */
- pid_t pid; /* thread id */
- void *private_data; /* set by file system on mount */
- mode_t umask; /* umask of the thread */
-};
-.Ed
-.Sh SEE ALSO
-.Xr fuse_new 3
-.Sh STANDARDS
-The
-.Fn fuse_get_context
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_get_context
-function
-first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
blob - 99a074af01baf5de698cf083f1ba5830a88de2a7 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_get_session.3
+++ /dev/null
@@ -1,44 +0,0 @@
-.\" $OpenBSD: fuse_get_session.3,v 1.2 2018/07/08 06:17:10 jmc Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg.bredow@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: July 8 2018 $
-.Dt FUSE_GET_SESSION 3
-.Os
-.Sh NAME
-.Nm fuse_get_session
-.Nd get the FUSE session associated with a FUSE handle
-.Sh SYNOPSIS
-.In fuse.h
-.Ft struct fuse_session *
-.Fn fuse_get_session "struct fuse *f"
-.Sh DESCRIPTION
-.Fn fuse_get_session
-returns the FUSE session associated with the FUSE file handle
-.Fa f .
-.Sh SEE ALSO
-.Xr fuse_remove_signal_handlers 3 ,
-.Xr fuse_set_signal_handlers 3
-.Sh STANDARDS
-The
-.Fn fuse_get_session
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_get_session
-function first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
blob - e86b5067a6a7374c80f91b4e6534861f3e5782bf (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_loop.3
+++ /dev/null
@@ -1,83 +0,0 @@
-.\" $OpenBSD: fuse_loop.3,v 1.2 2018/07/08 06:17:10 jmc Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: July 8 2018 $
-.Dt FUSE_LOOP 3
-.Os
-.Sh NAME
-.Nm fuse_loop ,
-.Nm fuse_loop_mt
-.Nd wait for and process FUSE messages
-.Sh SYNOPSIS
-.In fuse.h
-.Ft int
-.Fn fuse_loop "struct fuse *fuse"
-.Ft int
-.Fn fuse_loop_mt "struct fuse *fuse"
-.Sh DESCRIPTION
-.Fn fuse_loop
-reads from the FUSE device and blocks, waiting for the
-kernel to send it fbuf messages.
-Each of these specifies a FUSE file system operation to execute.
-The callbacks to invoke are specified by calling
-.Xr fuse_new 3
-or
-.Xr fuse_setup 3
-prior to calling
-.Fn fuse_loop .
-.Pp
-.Fn fuse_loop
-will return when it reads the FBT_DESTROY message, which indicates that
-the file system is being unmounted.
-.Pp
-If FUSE signaler handlers have been installed and either SIGHUP, SIGINT
-or SIGTERM is received then
-.Fn fuse_loop
-will attempt to unmount the file system.
-See
-.Xr fuse_set_signal_handlers 3 .
-.Pp
-.Fn fuse_loop_mt
-is a multi-threaded variant that allows the file system to process
-multiple file system operations in parallel.
-This is not implemented on
-.Ox .
-.Sh RETURN VALUES
-.Fn fuse_loop
-will return 0 on success and -1 on failure.
-.Pp
-.Fn fuse_loop_mt
-always returns -1.
-.Sh SEE ALSO
-.Xr fuse_main 3 ,
-.Xr fuse_set_signal_handlers 3 ,
-.Xr fb_queue 9
-.Sh STANDARDS
-The
-.Fn fuse_loop
-and
-.Fn fuse_loop_mt
-functions conform to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_loop
-and
-.Fn fuse_loop_mt
-functions first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
-.An Helg Bredow Aq Mt helg@openbsd.org
blob - b2319be80913aa9f7b0632b170adad2e68b12c31 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_main.3
+++ /dev/null
@@ -1,151 +0,0 @@
-.\" $OpenBSD: fuse_main.3,v 1.7 2020/05/25 16:33:03 jmc Exp $
-.\"
-.\" Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
-.\" Copyright (c) 2018 Helg Bredow <helg@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: May 25 2020 $
-.Dt FUSE_MAIN 3
-.Os
-.Sh NAME
-.Nm fuse_main
-.Nd FUSE helper function
-.Sh SYNOPSIS
-.In fuse.h
-.Ft int
-.Fn fuse_main "int argc" "char **argv" "const struct fuse_operations *ops" \
- "void *data"
-.Sh DESCRIPTION
-There are two ways of implementing a FUSE filesystem:
-by calling only
-.Fn fuse_main
-and passing this function the
-.Em ops
-argument containing all the callbacks of the filesystem,
-or by using the other functions,
-as detailed in
-.Xr fuse_loop 3
-.Pp
-.Fa argv
-is the list of arguments supplied to the program's main method and
-must at a minimum specify the directory on which the file system is to
-be mounted.
-The other arguments can be custom arguments specific to the
-file system or those supported by
-.Xr fuse_parse_cmdline 3 ,
-.Xr fuse_new 3
-and
-.Xr fuse_mount 3 .
-.Sh EXAMPLES
-Here is a simple example of a FUSE implementation:
-.Bd -literal
-#include <errno.h>
-#include <fuse.h>
-#include <string.h>
-
-static int
-fs_readdir(const char *path, void *data, fuse_fill_dir_t filler,
- off_t off, struct fuse_file_info *ffi)
-{
- if (strcmp(path, "/") != 0)
- return -ENOENT;
-
- filler(data, ".", NULL, 0);
- filler(data, "..", NULL, 0);
- filler(data, "file", NULL, 0);
- return 0;
-}
-
-static int
-fs_read(const char *path, char *buf, size_t size, off_t off,
- struct fuse_file_info *ffi)
-{
- size_t len;
- const char *file_contents = "fuse filesystem example\\n";
-
- len = strlen(file_contents);
-
- if (off < len) {
- if (off + size > len)
- size = len - off;
- memcpy(buf, file_contents + off, size);
- } else
- size = 0;
-
- return size;
-}
-
-static int
-fs_open(const char *path, struct fuse_file_info *ffi)
-{
- if (strncmp(path, "/file", 10) != 0)
- return -ENOENT;
-
- if ((ffi->flags & 3) != O_RDONLY)
- return -EACCES;
-
- return 0;
-}
-
-static int
-fs_getattr(const char *path, struct stat *st)
-{
- if (strcmp(path, "/") == 0) {
- st->st_blksize = 512;
- st->st_mode = 0755;
- st->st_nlink = 2;
- } else if (strcmp(path, "/file") == 0) {
- st->st_mode = 0644;
- st->st_blksize = 512;
- st->st_nlink = 1;
- st->st_size = 5;
- } else {
- return -ENOENT;
- }
-
- return 0;
-}
-
-struct fuse_operations fsops = {
- .readdir = fs_readdir,
- .read = fs_read,
- .open = fs_open,
- .getattr = fs_getattr,
-};
-
-int
-main(int argc, char **argv)
-{
- return (fuse_main(argc, argv, &fsops, NULL));
-}
-.Ed
-.Sh SEE ALSO
-.Xr fuse_loop 3 ,
-.Xr fuse_mount 3 ,
-.Xr fuse_new 3 ,
-.Xr fuse_parse_cmdline 3 ,
-.Xr fuse_setup 3 ,
-.Xr fuse 4
-.Sh STANDARDS
-The
-.Fn fuse_main
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_main
-function first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
-.An Helg Bredow Aq Mt helg@openbsd.org
blob - 5e8e928c3b8bd7e6544aff86fe8843352f417fca (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_mount.3
+++ /dev/null
@@ -1,123 +0,0 @@
-.\" $OpenBSD: fuse_mount.3,v 1.2 2018/07/08 06:17:10 jmc Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies. .\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: July 8 2018 $
-.Dt FUSE_MOUNT 3
-.Os
-.Sh NAME
-.Nm fuse_mount ,
-.Nm fuse_unmount
-.Nd mount or dismount a FUSE file system
-.Sh SYNOPSIS
-.In fuse.h
-.Ft struct fuse_chan *
-.Fn fuse_mount "const char *dir" "struct fuse_args *args"
-.Ft void
-.Fn fuse_unmount "const char *dir" "struct fuse_chan *ch"
-.Sh DESCRIPTION
-The
-.Fn fuse_mount
-function calls the
-.Xr mount 2
-system call to graft the FUSE file system on to the file system tree
-at the point
-.Fa dir .
-.Fa args
-are FUSE specific mount options as documented by
-.Xr mount 2 .
-.Pp
-The following mount options can be specified by preceding them with
-.Fl o ,
-either individually or together separated by a comma.
-.Bl -tag -width Ds
-.It allow_other
-Allow other users to access the file system.
-By default, FUSE will prevent other users from accessing the file system or to
-.Xr statfs 2
-the file system.
-This security measure is particularly important for
-network file system that may expose private files.
-It also guards against system processes being blocked indefinitely
-if the file system stops responding.
-.It default_permissions
-Request that the kernel enforce file access permissions.
-Alternatively, FUSE file systems can choose to implement access
-checks internally.
-On
-.Ox ,
-this option is always set.
-.It kernel_cache
-Enables buffering of files in the kernel.
-Not recommended for file systems that can be updated external to FUSE,
-such as network file systems.
-Not implemented.
-.It max_read=%u
-Specify the maximum size of read operations.
-Note that the kernel limits this to FUSEBUFMAXSIZE.
-This option should not be specified on the command line.
-The correct (or optimum) value depends on the filesystem implementation
-and should thus be specified by the filesystem internally.
-.It ro
-Mount the file system read-only.
-Can also be specified by itself with
-.Fl r .
-.El
-.Pp
-.Fn fuse_unmount
-will attempt to unmount the file system mounted at
-.Fa dir
-by calling the
-.Xr unmount 2
-system call.
-If this is successful, the kernel will send the
-FBT_DESTROY message to the file system, causing
-.Xr fuse_loop 3
-to terminate.
-There is no way to determine whether this call was successful.
-.Pp
-Only the super user can mount and unmount FUSE file systems.
-.Sh RETURN VALUES
-.Fn fuse_main
-will return NULL if the file system cannot be mounted.
-.Sh ERRORS
-.Fn fuse_mount
-will fail when one of the following occurs:
-.Fa dir
-does not exist or is not a directory.
-The fuse device cannot be opened for reading and writing.
-There was an error parsing the options specified by
-.Fa args .
-The file system could not be mounted.
-.Sh SEE ALSO
-.Xr mount 2 ,
-.Xr fuse_main 3 ,
-.Xr fuse_setup 3 ,
-.Xr fuse 4
-.Sh STANDARDS
-The
-.Fn fuse_mount
-and
-.Fn fuse_unmount
-functions conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_mount
-and
-.Fn fuse_unmount
-functions first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
-.An Helg Bredow Aq Mt helg@openbsd.org
blob - c7e593ccb231874b5f68f2ddcd1fb373bbea359b (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_new.3
+++ /dev/null
@@ -1,243 +0,0 @@
-.\" $OpenBSD: fuse_new.3,v 1.5 2018/08/04 00:08:53 helg Exp $
-.\"
-.\" Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
-.\" Copyright (c) 2018 Helg Bredow <helg@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: August 4 2018 $
-.Dt FUSE_NEW 3
-.Os
-.Sh NAME
-.Nm fuse_new
-.Nd FUSE implementation routine to intialise the FUSE connection
-.Sh SYNOPSIS
-.In fuse.h
-.Ft struct fuse *
-.Fn fuse_new "struct fuse_chan *fc" "struct fuse_args *args" \
- "const struct fuse_operations *ops" "unused size_t size" \
- "void *userdata"
-.Sh DESCRIPTION
-Initialises the FUSE library on the channel returned by
-.Xr fuse_mount 3 .
-.Pp
-FUSE operations work in the same way as their UNIX file system
-counterparts.
-A major exception is that these routines return
-a negated errno value (-errno) on failure.
-.Pp
-All operations are optional but a functional file system will want to
-implement at least statfs, readdir, open, read and getattr.
-FUSE will return ENOSYS if any operation other than flush, fsync or
-fsyncdir is not implemented.
-.Pp
-The first parameter to each of these operations (except for init and
-terminate) is a NULL terminated string representing the full path to
-the file or directory, relative to the root of this file system, that
-is being operated on.
-.Bd -literal
-struct fuse_operations {
- int (*getattr)(const char *, struct stat *);
- int (*readlink)(const char *, char *, size_t);
- int (*getdir)(const char *, fuse_dirh_t, fuse_dirfil_t);
- int (*mknod)(const char *, mode_t, dev_t);
- int (*mkdir)(const char *, mode_t);
- int (*unlink)(const char *);
- int (*rmdir)(const char *);
- int (*symlink)(const char *, const char *);
- int (*rename)(const char *, const char *);
- int (*link)(const char *, const char *);
- int (*chmod)(const char *, mode_t);
- int (*chown)(const char *, uid_t, gid_t);
- int (*truncate)(const char *, off_t);
- int (*utime)(const char *, struct utimbuf *);
- int (*open)(const char *, struct fuse_file_info *);
- int (*read)(const char *, char *, size_t, off_t,
- struct fuse_file_info *);
- int (*write)(const char *, const char *, size_t, off_t,
- struct fuse_file_info *);
- int (*statfs)(const char *, struct statvfs *);
- int (*flush)(const char *, struct fuse_file_info *);
- int (*release)(const char *, struct fuse_file_info *);
- int (*fsync)(const char *, int, struct fuse_file_info *);
- int (*setxattr)(const char *, const char *, const char *,
- size_t int);
- int (*getxattr)(const char *, const char *, char *, size_t);
- int (*listxattr)(const char *, char *, size_t);
- int (*removexattr)(const char *, const char *);
- int (*opendir)(const char *, struct fuse_file_info *);
- int (*readdir)(const char *, void *, fuse_fill_dir_t, off_t,
- struct fuse_file_info *);
- int (*releasedir)(const char *, struct fuse_file_info *);
- int (*fsyncdir)(const char *, int, struct fuse_file_info *);
- void *(*init)(struct fuse_conn_info *);
- void (*destroy)(void *);
- int (*access)(const char *, int);
- int (*create)(const char *, mode_t, struct fuse_file_info *);
- int (*ftruncate)(const char *, off_t, struct fuse_file_info *);
- int (*fgetattr)(const char *, struct stat *, struct
- fuse_file_info *);
- int (*lock)(const char *, struct fuse_file_info *, int,
- struct flock *);
- int (*utimens)(const char *, const struct timespec *);
- int (*bmap)(const char *, size_t , uint64_t *);
-};
-.Ed
-.Pp
-The order of calls is:
-.Bd -literal -offset indent
-init
-\&...
-opendir
-readdir
-releasedir
-open
-read
-write
-\&...
-flush
-release
-\&...
-destroy
-.Ed
-.Bl -tag -width "releasedir"
-.It access
-Not implemented.
-.Ox
-always behaves as if the default_permissions mount option was specified.
-See
-.Xr fuse_mount 3 .
-.It chmod
-Called when file access permissions are changed.
-.It chown
-Called when either the file owner or group is changed.
-.It create
-Not implemented on
-.Ox .
-File systems must implement mknod instead.
-In the reference implementation this is an atomic operation that both
-creates and opens the file.
-There is no equivalent in the
-.Ox
-VFS.
-.It flush
-Called when the file is closed by the
-.Xr close 2
-system call.
-This is the only way for a file system to return an error on close.
-.It fsync
-Optional function that implements
-.Xr fsync 2
-and
-.Xr fdatasync 2 .
-The datasync parameter specifies whether the operation is as a result
-of a call to
-.Xr fdatasync 2
-and is currently always 0 (false).
-ffi.fh_id will contain the file handle returned by the file system when
-the file was opened.
-.It fsyncdir
-Not implemented.
-.It getattr
-Corresponds to the
-.Xr stat 2
-system call.
-Flags and extended attributes are ignored.
-This operation is mandatory.
-.It getxattr
-Not implemented.
-.It getdir
-Deprecated.
-File system should implement readdir instead.
-.It mknod
-Called on
-.Xr open 2
-and
-.Xr mknod 2
-to create regular files, pipes and device special files.
-.It open
-Called on
-.Xr open 2 .
-Due to the difference between FUSE and the
-.Ox
-VFS,
-open will only be called once for each file
-for every different combination of flags provided to
-.Xr open 2 .
-The O_CREAT and O_TRUNC flags are never passed from the kernel to open,
-the mknod and truncate operations are invoked before open instead.
-.It opendir
-Called when a directory is opened for reading.
-.It release
-Called when there are no more references to the file.
-.It releasedir
-Called when there are no more references to the directory.
-.It setattr
-Equivalent to
-.Xr chown 2
-and
-.Xr chmod 2
-system calls.
-Setting file flags is not supported.
-.It setxattr
-Not implemented.
-.El
-.Pp
-Options supported by args are:
-.Bl -tag -width "readdir_ino"
-.It debug, -d
-Print debug information to stdout.
-.It gid=%u
-The GID that will be reported as the group for all files by getattr.
-.It hard_remove
-Immediately delete a file even if it's currently open by a process.
-Otherwise FUSE will temporarily rename the file and only delete it when
-it is no longer referenced.
-This is to avoid the file system having to deal with this situation.
-This is always set on
-.Ox .
-.It readdir_ino
-Similar to use_ino but the file system's inode number is only reported
-for readdir.
-This is always set on
-.Ox
-because it's required by
-.Xr getcwd 3 .
-.It uid=%u
-The UID that will be reported as the owner for all files by getattr.
-.It umask=%o
-The file mode mask applied to the permission for all files by getattr.
-.It use_ino
-By default, FUSE will return an internal inode number for getattr and
-readdir and this will be different every time the file system is
-mounted.
-If this is set the file system's own inode number will be
-reported instead.
-Useful only for file system that have inode numbers.
-.El
-.Sh SEE ALSO
-.Xr fuse_get_context 3 ,
-.Xr fuse_main 3 ,
-.Xr fuse_mount 3
-.Sh STANDARDS
-The
-.Fn fuse_new
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_new
-function first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
-.An Helg Bredow Aq Mt helg@openbsd.org
blob - 5e9ea7bd631521e34758f4b83707847f57195314 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_ops.c
+++ /dev/null
@@ -1,1182 +0,0 @@
-/* $OpenBSD: fuse_ops.c,v 1.35 2018/07/16 13:10:53 helg Exp $ */
-/*
- * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "fuse_private.h"
-#include "debug.h"
-
-#define CHECK_OPT(opname) DPRINTF("Opcode: %s\t", #opname); \
- DPRINTF("Inode: %llu\t", \
- (unsigned long long)fbuf->fb_ino); \
- if (!f->op.opname) { \
- fbuf->fb_err = -ENOSYS; \
- return (0); \
- }
-
-static int
-update_attr(struct fuse *f, struct stat *attr, const char *realname,
- struct fuse_vnode *vn)
-{
- int ret;
-
- memset(attr, 0, sizeof(struct stat));
- ret = f->op.getattr(realname, attr);
-
- if (attr->st_blksize == 0)
- attr->st_blksize = 512;
- if (attr->st_blocks == 0)
- attr->st_blocks = 4;
-
- if (!f->conf.use_ino)
- attr->st_ino = vn->ino;
-
- if (f->conf.set_mode)
- attr->st_mode = (attr->st_mode & S_IFMT) | (0777 & ~f->conf.umask);
-
- if (f->conf.set_uid)
- attr->st_uid = f->conf.uid;
-
- if (f->conf.set_gid)
- attr->st_gid = f->conf.gid;
-
- return (ret);
-}
-
-static int
-ifuse_ops_init(struct fuse *f)
-{
- struct fuse_conn_info fci;
-
- DPRINTF("Opcode: init\t");
-
- if (f->op.init) {
- memset(&fci, 0, sizeof(fci));
- fci.proto_minor = FUSE_MINOR_VERSION;
- fci.proto_major = FUSE_MAJOR_VERSION;
-
- f->op.init(&fci);
- }
- return (0);
-}
-
-static int
-ifuse_ops_getattr(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
-
- DPRINTF("Opcode: getattr\t");
- DPRINTF("Inode: %llu\t", (unsigned long long)fbuf->fb_ino);
-
- memset(&fbuf->fb_attr, 0, sizeof(struct stat));
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- fbuf->fb_err = update_attr(f, &fbuf->fb_attr, realname, vn);
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_access(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
-
- CHECK_OPT(access);
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- fbuf->fb_err = f->op.access(realname, fbuf->fb_io_mode);
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_open(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_file_info ffi;
- struct fuse_vnode *vn;
- char *realname;
-
- CHECK_OPT(open);
-
- memset(&ffi, 0, sizeof(ffi));
- ffi.flags = fbuf->fb_io_flags;
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- fbuf->fb_err = f->op.open(realname, &ffi);
- free(realname);
-
- if (!fbuf->fb_err)
- fbuf->fb_io_fd = ffi.fh;
-
- return (0);
-}
-
-static int
-ifuse_ops_opendir(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_file_info ffi;
- struct fuse_vnode *vn;
- char *realname;
-
- DPRINTF("Opcode: opendir\t");
- DPRINTF("Inode: %llu\t", (unsigned long long)fbuf->fb_ino);
-
- memset(&ffi, 0, sizeof(ffi));
- ffi.flags = fbuf->fb_io_flags;
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- if (f->op.opendir) {
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- fbuf->fb_err = f->op.opendir(realname, &ffi);
- free(realname);
- }
-
- if (!fbuf->fb_err)
- fbuf->fb_io_fd = ffi.fh;
-
- return (0);
-}
-
-#define GENERIC_DIRSIZ(NLEN) \
-((sizeof (struct dirent) - (MAXNAMLEN+1)) + ((NLEN+1 + 7) &~ 7))
-
-/*
- * This function adds one directory entry to the buffer.
- * FUSE file systems can implement readdir in one of two ways.
- *
- * 1. Read all directory entries in one operation. The off parameter
- * will always be 0 and this filler function always returns 0.
- * 2. The file system keeps track of the directory entry offsets and
- * this filler function returns 1 when the buffer is full.
- *
- * OpenBSD currently supports 1. but will still call the file system's
- * readdir function multiple times if either the kernel buffer or the
- * buffer supplied by the calling application is too small to fit all
- * entries. Each call to the file system's readdir function will fill
- * the buffer with the next set of entries.
- */
-static int
-ifuse_fill_readdir(void *dh, const char *name, const struct stat *stbuf,
- off_t off)
-{
- struct fuse *f;
- struct fuse_dirhandle *fd = dh;
- struct fuse_vnode *v;
- struct fusebuf *fbuf;
- struct dirent *dir;
- uint32_t namelen;
- uint32_t len;
-
- f = fd->fuse;
- fbuf = fd->buf;
- namelen = strnlen(name, MAXNAMLEN);
- len = GENERIC_DIRSIZ(namelen);
-
- /* buffer is full so ignore the remaining entries */
- if (fd->full || (fbuf->fb_len + len > fd->size)) {
- fd->full = 1;
- return (0);
- }
-
- /* already returned these entries in a previous call so skip */
- if (fd->start != 0 && fd->idx < fd->start) {
- fd->idx += len;
- return (0);
- }
-
- dir = (struct dirent *) &fbuf->fb_dat[fbuf->fb_len];
-
- if (stbuf != NULL && f->conf.use_ino)
- dir->d_fileno = stbuf->st_ino;
- else {
- /*
- * This always behaves as if readdir_ino option is set so
- * getcwd(3) works.
- */
- v = get_vn_by_name_and_parent(f, (uint8_t *)name, fbuf->fb_ino);
- if (v == NULL) {
- if (strcmp(name, ".") == 0)
- dir->d_fileno = fbuf->fb_ino;
- else
- dir->d_fileno = 0xffffffff;
- } else
- dir->d_fileno = v->ino;
- }
-
- if (stbuf != NULL)
- dir->d_type = IFTODT(stbuf->st_mode);
- else
- dir->d_type = DT_UNKNOWN;
-
- dir->d_reclen = len;
- dir->d_off = off + len; /* XXX */
- strlcpy(dir->d_name, name, sizeof(dir->d_name));
- dir->d_namlen = strlen(dir->d_name);
-
- fbuf->fb_len += len;
- fd->idx += len;
-
- return (0);
-}
-
-static int
-ifuse_fill_getdir(fuse_dirh_t fd, const char *name, int type, ino_t ino)
-{
- struct stat st;
-
- memset(&st, 0, sizeof(st));
- st.st_mode = type << 12;
- if (ino == 0)
- st.st_ino = 0xffffffff;
- else
- st.st_ino = ino;
-
- return (fd->filler(fd, name, &st, 0));
-}
-
-static int
-ifuse_ops_readdir(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_file_info ffi;
- struct fuse_dirhandle fd;
- struct fuse_vnode *vn;
- char *realname;
- uint64_t offset;
- uint32_t size;
-
- DPRINTF("Opcode: readdir\t");
- DPRINTF("Inode: %llu\t", (unsigned long long)fbuf->fb_ino);
- DPRINTF("Offset: %llu\t", fbuf->fb_io_off);
- DPRINTF("Size: %lu\t", fbuf->fb_io_len);
-
- memset(&ffi, 0, sizeof(ffi));
- ffi.fh = fbuf->fb_io_fd;
- offset = fbuf->fb_io_off;
- size = fbuf->fb_io_len;
-
- fbuf->fb_dat = calloc(1, size);
-
- if (fbuf->fb_dat == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- memset(&fd, 0, sizeof(fd));
- fd.filler = ifuse_fill_readdir;
- fd.buf = fbuf;
- fd.full = 0;
- fd.size = size;
- fd.off = offset;
- fd.idx = 0;
- fd.fuse = f;
- fd.start = offset;
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- if (f->op.readdir)
- fbuf->fb_err = f->op.readdir(realname, &fd, ifuse_fill_readdir,
- offset, &ffi);
- else if (f->op.getdir)
- fbuf->fb_err = f->op.getdir(realname, &fd, ifuse_fill_getdir);
- else
- fbuf->fb_err = -ENOSYS;
- free(realname);
-
- if (fbuf->fb_err)
- fbuf->fb_len = 0;
- else if (fd.full && fbuf->fb_len == 0)
- fbuf->fb_err = -ENOBUFS;
-
- if (fbuf->fb_len == 0)
- free(fbuf->fb_dat);
-
- return (0);
-}
-
-static int
-ifuse_ops_releasedir(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_file_info ffi;
- struct fuse_vnode *vn;
- char *realname;
-
- DPRINTF("Opcode: releasedir\t");
- DPRINTF("Inode: %llu\t", (unsigned long long)fbuf->fb_ino);
-
- memset(&ffi, 0, sizeof(ffi));
- ffi.fh = fbuf->fb_io_fd;
- ffi.fh_old = ffi.fh;
- ffi.flags = fbuf->fb_io_flags;
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- if (f->op.releasedir) {
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- fbuf->fb_err = f->op.releasedir(realname, &ffi);
- free(realname);
- }
-
- return (0);
-}
-
-static int
-ifuse_ops_release(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_file_info ffi;
- struct fuse_vnode *vn;
- char *realname;
-
- CHECK_OPT(release);
-
- memset(&ffi, 0, sizeof(ffi));
- ffi.fh = fbuf->fb_io_fd;
- ffi.fh_old = ffi.fh;
- ffi.flags = fbuf->fb_io_flags;
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
- fbuf->fb_err = f->op.release(realname, &ffi);
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_fsync(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_file_info ffi;
- struct fuse_vnode *vn;
- char *realname;
- int datasync;
-
- CHECK_OPT(fsync);
-
- memset(&ffi, 0, sizeof(ffi));
- ffi.fh = fbuf->fb_io_fd;
-
- /*
- * fdatasync(2) is just a wrapper around fsync(2) so datasync
- * is always false.
- */
- datasync = 0;
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
- fbuf->fb_err = f->op.fsync(realname, datasync, &ffi);
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_flush(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_file_info ffi;
- struct fuse_vnode *vn;
- char *realname;
-
- CHECK_OPT(flush);
-
- memset(&ffi, 0, sizeof(ffi));
- ffi.fh = fbuf->fb_io_fd;
- ffi.fh_old = ffi.fh;
- ffi.flush = 1;
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
- fbuf->fb_err = f->op.flush(realname, &ffi);
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_lookup(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
-
- DPRINTF("Opcode: lookup\t");
- DPRINTF("Inode: %llu\t", (unsigned long long)fbuf->fb_ino);
-
- if (strcmp((const char *)fbuf->fb_dat, "..") == 0) {
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL || vn->parent == NULL) {
- fbuf->fb_err = -ENOENT;
- return (0);
- }
- vn = vn->parent;
- if (vn->ino != FUSE_ROOT_INO)
- ref_vn(vn);
- } else {
- vn = get_vn_by_name_and_parent(f, fbuf->fb_dat, fbuf->fb_ino);
- if (vn == NULL) {
- vn = alloc_vn(f, (const char *)fbuf->fb_dat, -1,
- fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
- set_vn(f, vn); /*XXX*/
- } else if (vn->ino != FUSE_ROOT_INO)
- ref_vn(vn);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- fbuf->fb_err = update_attr(f, &fbuf->fb_attr, realname, vn);
- fbuf->fb_ino = vn->ino;
- free(fbuf->fb_dat);
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_read(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_file_info ffi;
- struct fuse_vnode *vn;
- char *realname;
- uint64_t offset;
- uint32_t size;
- int ret;
-
- CHECK_OPT(read);
-
- memset(&ffi, 0, sizeof(ffi));
- ffi.fh = fbuf->fb_io_fd;
- size = fbuf->fb_io_len;
- offset = fbuf->fb_io_off;
-
- fbuf->fb_dat = malloc(size);
- if (fbuf->fb_dat == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- ret = f->op.read(realname, (char *)fbuf->fb_dat, size, offset, &ffi);
- free(realname);
- if (ret >= 0)
- fbuf->fb_len = ret;
- else
- fbuf->fb_err = ret;
-
- if (fbuf->fb_len == 0)
- free(fbuf->fb_dat);
-
- return (0);
-}
-
-static int
-ifuse_ops_write(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_file_info ffi;
- struct fuse_vnode *vn;
- char *realname;
- uint64_t offset;
- uint32_t size;
- int ret;
-
- CHECK_OPT(write);
-
- memset(&ffi, 0, sizeof(ffi));
- ffi.fh = fbuf->fb_io_fd;
- ffi.fh_old = ffi.fh;
- ffi.writepage = fbuf->fb_io_flags & 1;
- size = fbuf->fb_io_len;
- offset = fbuf->fb_io_off;
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- ret = f->op.write(realname, (char *)fbuf->fb_dat, size, offset, &ffi);
- free(realname);
- free(fbuf->fb_dat);
-
- if (ret >= 0)
- fbuf->fb_io_len = ret;
- else
- fbuf->fb_err = ret;
-
- return (0);
-}
-
-static int
-ifuse_ops_mkdir(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
- uint32_t mode;
-
- CHECK_OPT(mkdir);
-
- mode = fbuf->fb_io_mode;
- vn = get_vn_by_name_and_parent(f, fbuf->fb_dat, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- free(fbuf->fb_dat);
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- fbuf->fb_err = f->op.mkdir(realname, mode);
-
- if (!fbuf->fb_err) {
- fbuf->fb_err = update_attr(f, &fbuf->fb_attr, realname, vn);
- fbuf->fb_io_mode = fbuf->fb_attr.st_mode;
- fbuf->fb_ino = vn->ino;
- }
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_rmdir(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
-
- CHECK_OPT(rmdir);
- vn = get_vn_by_name_and_parent(f, fbuf->fb_dat, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- free(fbuf->fb_dat);
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- fbuf->fb_err = f->op.rmdir(realname);
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_readlink(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
- char name[PATH_MAX + 1];
- int len, ret;
-
- DPRINTF("Opcode: readlink\t");
- DPRINTF("Inode: %llu\t", (unsigned long long)fbuf->fb_ino);
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- if (f->op.readlink)
- ret = f->op.readlink(realname, name, sizeof(name));
- else
- ret = -ENOSYS;
- free(realname);
-
- fbuf->fb_err = ret;
- if (!ret) {
- len = strnlen(name, PATH_MAX);
- fbuf->fb_len = len;
- fbuf->fb_dat = malloc(fbuf->fb_len);
- if (fbuf->fb_dat == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
- memcpy(fbuf->fb_dat, name, len);
- } else
- fbuf->fb_len = 0;
-
- return (0);
-}
-
-static int
-ifuse_ops_unlink(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
-
- CHECK_OPT(unlink);
-
- vn = get_vn_by_name_and_parent(f, fbuf->fb_dat, fbuf->fb_ino);
- if (vn == NULL) {
- free(fbuf->fb_dat);
- fbuf->fb_err = -errno;
- return (0);
- }
-
- free(fbuf->fb_dat);
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- fbuf->fb_err = f->op.unlink(realname);
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_statfs(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
-
- memset(&fbuf->fb_stat, 0, sizeof(fbuf->fb_stat));
-
- CHECK_OPT(statfs);
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- fbuf->fb_err = f->op.statfs(realname, &fbuf->fb_stat);
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_link(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
- char *realname_ln;
- ino_t oldnodeid;
-
- CHECK_OPT(link);
- oldnodeid = fbuf->fb_io_ino;
- vn = get_vn_by_name_and_parent(f, fbuf->fb_dat, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- free(fbuf->fb_dat);
- realname = build_realname(f, oldnodeid);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- realname_ln = build_realname(f, vn->ino);
- if (realname_ln == NULL) {
- fbuf->fb_err = -errno;
- free(realname);
- return (0);
- }
-
- fbuf->fb_err = f->op.link(realname, realname_ln);
- free(realname);
- free(realname_ln);
-
- return (0);
-}
-
-static int
-ifuse_ops_setattr(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- struct timespec ts[2];
- struct utimbuf tbuf;
- struct fb_io *io;
- char *realname;
- uid_t uid;
- gid_t gid;
-
- DPRINTF("Opcode: setattr\t");
- DPRINTF("Inode: %llu\t", (unsigned long long)fbuf->fb_ino);
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
- io = fbtod(fbuf, struct fb_io *);
-
- if (io->fi_flags & FUSE_FATTR_MODE) {
- if (f->op.chmod)
- fbuf->fb_err = f->op.chmod(realname,
- fbuf->fb_attr.st_mode);
- else
- fbuf->fb_err = -ENOSYS;
- }
-
- if (!fbuf->fb_err && (io->fi_flags & FUSE_FATTR_UID ||
- io->fi_flags & FUSE_FATTR_GID) ) {
- uid = (io->fi_flags & FUSE_FATTR_UID) ?
- fbuf->fb_attr.st_uid : (uid_t)-1;
- gid = (io->fi_flags & FUSE_FATTR_GID) ?
- fbuf->fb_attr.st_gid : (gid_t)-1;
- if (f->op.chown)
- fbuf->fb_err = f->op.chown(realname, uid, gid);
- else
- fbuf->fb_err = -ENOSYS;
- }
-
- if (!fbuf->fb_err && ( io->fi_flags & FUSE_FATTR_MTIME ||
- io->fi_flags & FUSE_FATTR_ATIME)) {
-
- if (f->op.utimens) {
- ts[0] = fbuf->fb_attr.st_atim;
- ts[1] = fbuf->fb_attr.st_mtim;
- fbuf->fb_err = f->op.utimens(realname, ts);
- } else if (f->op.utime) {
- tbuf.actime = fbuf->fb_attr.st_atim.tv_sec;
- tbuf.modtime = fbuf->fb_attr.st_mtim.tv_sec;
- fbuf->fb_err = f->op.utime(realname, &tbuf);
- } else
- fbuf->fb_err = -ENOSYS;
- }
-
- if (!fbuf->fb_err && (io->fi_flags & FUSE_FATTR_SIZE)) {
- if (f->op.truncate)
- fbuf->fb_err = f->op.truncate(realname,
- fbuf->fb_attr.st_size);
- else
- fbuf->fb_err = -ENOSYS;
- }
-
- memset(&fbuf->fb_attr, 0, sizeof(struct stat));
-
- if (!fbuf->fb_err)
- fbuf->fb_err = update_attr(f, &fbuf->fb_attr, realname, vn);
- free(realname);
- free(fbuf->fb_dat);
-
- return (0);
-}
-
-static int
-ifuse_ops_symlink(unused struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
- int len;
-
- CHECK_OPT(symlink);
-
- vn = get_vn_by_name_and_parent(f, fbuf->fb_dat, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- len = strlen((char *)fbuf->fb_dat);
-
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- /* fuse invert the symlink params */
- fbuf->fb_err = f->op.symlink((const char *)&fbuf->fb_dat[len + 1],
- realname);
- fbuf->fb_ino = vn->ino;
- free(fbuf->fb_dat);
- free(realname);
-
- return (0);
-}
-
-static int
-ifuse_ops_rename(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vnt;
- struct fuse_vnode *vnf;
- char *realnamef;
- char *realnamet;
- int len;
-
- CHECK_OPT(rename);
-
- len = strlen((char *)fbuf->fb_dat);
- vnf = get_vn_by_name_and_parent(f, fbuf->fb_dat, fbuf->fb_ino);
- if (vnf == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- vnt = get_vn_by_name_and_parent(f, &fbuf->fb_dat[len + 1],
- fbuf->fb_io_ino);
- if (vnt == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- free(fbuf->fb_dat);
-
- realnamef = build_realname(f, vnf->ino);
- if (realnamef == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- realnamet = build_realname(f, vnt->ino);
- if (realnamet == NULL) {
- fbuf->fb_err = -errno;
- free(realnamef);
- return (0);
- }
-
- fbuf->fb_err = f->op.rename(realnamef, realnamet);
- free(realnamef);
- free(realnamet);
-
- return (0);
-}
-
-static int
-ifuse_ops_destroy(struct fuse *f)
-{
- struct fuse_context *ctx;
-
- DPRINTF("Opcode: destroy\n");
-
- if (f->op.destroy) {
- ctx = fuse_get_context();
-
- f->op.destroy((ctx)?ctx->private_data:NULL);
- }
-
- f->fc->dead = 1;
-
- return (0);
-}
-
-static int
-ifuse_ops_reclaim(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
-
- DPRINTF("Opcode: reclaim\t");
- DPRINTF("Inode: %llu\t", (unsigned long long)fbuf->fb_ino);
-
- vn = tree_get(&f->vnode_tree, fbuf->fb_ino);
- if (vn != NULL)
- unref_vn(f, vn);
-
- return (0);
-}
-
-static int
-ifuse_ops_mknod(struct fuse *f, struct fusebuf *fbuf)
-{
- struct fuse_vnode *vn;
- char *realname;
- uint32_t mode;
- dev_t dev;
-
- CHECK_OPT(mknod);
-
- mode = fbuf->fb_io_mode;
- dev = fbuf->fb_io_rdev;
- vn = get_vn_by_name_and_parent(f, fbuf->fb_dat, fbuf->fb_ino);
- if (vn == NULL) {
- fbuf->fb_err = -errno;
- free(fbuf->fb_dat);
- return (0);
- }
-
- free(fbuf->fb_dat);
- realname = build_realname(f, vn->ino);
- if (realname == NULL) {
- fbuf->fb_err = -errno;
- return (0);
- }
-
- fbuf->fb_err = f->op.mknod(realname, mode, dev);
-
- if (!fbuf->fb_err) {
- fbuf->fb_err = update_attr(f, &fbuf->fb_attr, realname, vn);
- fbuf->fb_io_mode = fbuf->fb_attr.st_mode;
- fbuf->fb_ino = vn->ino;
- }
- free(realname);
-
- return (0);
-}
-
-int
-ifuse_exec_opcode(struct fuse *f, struct fusebuf *fbuf)
-{
- int ret = 0;
-
- fbuf->fb_len = 0;
- fbuf->fb_err = 0;
-
- switch (fbuf->fb_type) {
- case FBT_LOOKUP:
- ret = ifuse_ops_lookup(f, fbuf);
- break;
- case FBT_GETATTR:
- ret = ifuse_ops_getattr(f, fbuf);
- break;
- case FBT_SETATTR:
- ret = ifuse_ops_setattr(f, fbuf);
- break;
- case FBT_READLINK:
- ret = ifuse_ops_readlink(f, fbuf);
- break;
- case FBT_MKDIR:
- ret = ifuse_ops_mkdir(f, fbuf);
- break;
- case FBT_UNLINK:
- ret = ifuse_ops_unlink(f, fbuf);
- break;
- case FBT_RMDIR:
- ret = ifuse_ops_rmdir(f, fbuf);
- break;
- case FBT_LINK:
- ret = ifuse_ops_link(f, fbuf);
- break;
- case FBT_OPEN:
- ret = ifuse_ops_open(f, fbuf);
- break;
- case FBT_READ:
- ret = ifuse_ops_read(f, fbuf);
- break;
- case FBT_WRITE:
- ret = ifuse_ops_write(f, fbuf);
- break;
- case FBT_STATFS:
- ret = ifuse_ops_statfs(f, fbuf);
- break;
- case FBT_RELEASE:
- ret = ifuse_ops_release(f, fbuf);
- break;
- case FBT_FSYNC:
- ret = ifuse_ops_fsync(f, fbuf);
- break;
- case FBT_FLUSH:
- ret = ifuse_ops_flush(f, fbuf);
- break;
- case FBT_INIT:
- ret = ifuse_ops_init(f);
- break;
- case FBT_OPENDIR:
- ret = ifuse_ops_opendir(f, fbuf);
- break;
- case FBT_READDIR:
- ret = ifuse_ops_readdir(f, fbuf);
- break;
- case FBT_RELEASEDIR:
- ret = ifuse_ops_releasedir(f, fbuf);
- break;
- case FBT_ACCESS:
- ret = ifuse_ops_access(f, fbuf);
- break;
- case FBT_SYMLINK:
- ret = ifuse_ops_symlink(f, fbuf);
- break;
- case FBT_RENAME:
- ret = ifuse_ops_rename(f, fbuf);
- break;
- case FBT_DESTROY:
- ret = ifuse_ops_destroy(f);
- break;
- case FBT_RECLAIM:
- ret = ifuse_ops_reclaim(f, fbuf);
- break;
- case FBT_MKNOD:
- ret = ifuse_ops_mknod(f, fbuf);
- break;
- default:
- DPRINTF("Opcode: %i not supported\t", fbuf->fb_type);
- DPRINTF("Inode: %llu\t", (unsigned long long)fbuf->fb_ino);
-
- fbuf->fb_err = -ENOSYS;
- fbuf->fb_len = 0;
- }
- DPRINTF("\n");
-
- /* fuse api use negative errno */
- fbuf->fb_err = -fbuf->fb_err;
- return (ret);
-}
blob - dc781dafe687762bc50f7b3f640273e99750384a (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_opt.3
+++ /dev/null
@@ -1,297 +0,0 @@
-.\" $OpenBSD: fuse_opt.3,v 1.3 2018/11/30 18:19:12 mpi Exp $
-.\"
-.\" Copyright (c) Ray Lai <ray@raylai.com>
-.\" Copyright (c) Helg Bredow <helg@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: November 30 2018 $
-.Dt FUSE_OPT 3
-.Os
-.Sh NAME
-.Nm FUSE_ARGS_INIT ,
-.Nm FUSE_OPT_IS_OPT_KEY ,
-.Nm FUSE_OPT_KEY ,
-.Nm fuse_opt_add_arg ,
-.Nm fuse_opt_insert_arg ,
-.Nm fuse_opt_add_opt ,
-.Nm fuse_opt_add_opt_escaped ,
-.Nm fuse_opt_free_args ,
-.Nm fuse_opt_match ,
-.Nm fuse_opt_parse
-.Nd FUSE argument and option parser
-.Sh SYNOPSIS
-.In fuse_opt.h
-.Ft struct fuse_args
-.Fo FUSE_ARGS_INIT
-.Fa "int argc"
-.Fa "char argv**"
-.Fc
-.Ft int
-.Fo FUSE_OPT_IS_OPT_KEY
-.Fa "fuse_opt *t"
-.Fc
-.Ft struct fuse_opt
-.Fo FUSE_OPT_KEY
-.Fa "const char *templ"
-.Fa "int key"
-.Fc
-.Ft int
-.Fo fuse_opt_add_arg
-.Fa "struct fuse_args *args"
-.Fa "const char *arg"
-.Fc
-.Ft int
-.Fo fuse_opt_insert_arg
-.Fa "struct fuse_args *args"
-.Fa "int pos"
-.Fa "const char *opt"
-.Fc
-.Ft int
-.Fo fuse_opt_add_opt
-.Fa "char **opts"
-.Fa "const char *opt"
-.Fc
-.Ft int
-.Fo fuse_opt_add_opt_escaped
-.Fa "char **opts"
-.Fa "const char *opt"
-.Fc
-.Ft void
-.Fo fuse_opt_free_args
-.Fa "struct fuse_args *args"
-.Fc
-.Ft int
-.Fo fuse_opt_match
-.Fa "const struct fuse_opt *opts"
-.Fa "const char *opt"
-.Fc
-.Ft int
-.Fo fuse_opt_parse
-.Fa "struct fuse_args *args"
-.Fa "void *data"
-.Fa "const struct fuse_opt *opts"
-.Fa "fuse_opt_proc_t proc"
-.Fc
-.Sh DESCRIPTION
-These FUSE library functions and macros provide support for complex
-argument and option parsing.
-These are typically entered on the command line
-but may also be passed by file systems to the
-.Xr fuse_mount 3
-and
-.Xr fuse_new 3
-functions.
-.Ft struct fuse_args
-holds string options in an array:
-.Bd -literal -offset indent
-struct fuse_args {
- int argc; /* argument count */
- char **argv; /* NULL-terminated array of arguments */
- int allocated; /* argv was allocated and must be freed */
-};
-.Ed
-.Pp
-.Bl -tag -width Ds -compact
-.It Fn FUSE_OPT_KEY templ key
-returns a
-.Fa struct fuse_opt
-template that matches an argument or option
-.Fa templ
-with option key
-.Fa key .
-This macro is used as an element in
-.Fa struct fuse_opt
-arrays to create a template that is processed by a fuse_opt_proc_t.
-The special constants FUSE_OPT_KEEP and FUSE_OPT_DISCARD can be specified if
-proc does not need to handle this option or argument; proc is not called in
-this case.
-.Pp
-.It Fn FUSE_OPT_IS_OPT_KEY templ
-checks if
-.Fa templ
-is an option key.
-.Pp
-The last element of the
-.Fa opts
-.Ft struct fuse_opt
-option array must be
-.Dv FUSE_OPT_END .
-.Pp
-.Fa proc
-points to a function with the following signature:
-.Ft int (*fuse_opt_proc_t)
-.Fo proc
-.Fa "void *data"
-.Fa "const char *arg"
-.Fa "int key"
-.Fa "struct fuse_args *outargs"
-.Fc
-.Pp
-Special key values:
-.Bd -literal -offset indent
-FUSE_OPT_KEY_OPT /* no match */
-FUSE_OPT_KEY_NONOPT /* non-option */
-FUSE_OPT_KEY_KEEP /* don't process; return 1 */
-FUSE_OPT_KEY_DISCARD /* don't process; return 0 */
-.Ed
-.Pp
-.It Fn FUSE_ARGS_INIT
-initializes a
-.Ft struct fuse_args
-with
-.Fa argc
-and
-.Fa argv ,
-which are usually obtained from
-.Fn main .
-.Fa argv
-is NULL-terminated, and is suitable for use with
-.Xr execvp 3 .
-.Fa argv
-is used directly and
-.Fa allocated
-is set to 0.
-.Pp
-.It Fn fuse_opt_add_arg
-adds a single option to the end of
-.Fa args .
-If
-.Fa args->allocated
-is 0,
-.Fa args->argv
-is copied to the heap and
-.Fa args->allocated
-is set to a non-zero value.
-.Pp
-.It Fn fuse_opt_insert_arg
-inserts a single argument at position
-.Fa pos
-into
-.Fa args ,
-shifting
-.Fa args->argv
-as needed.
-.Pp
-.It Fn fuse_opt_add_opt
-adds an option
-.Fa opt
-to a comma-separated string of options
-.Fa opts .
-.Fa *opts
-can be NULL, which is typically used when adding the first option.
-.Pp
-.It Fn fuse_opt_add_opt_escaped
-escapes any
-.Sq ","
-and
-.Sq "\\"
-characters in
-.Fa opt
-before adding it to
-.Fa opts .
-.Pp
-.It Fn fuse_opt_free_args
-frees
-.Fa args->argv
-if it was allocated
-.Fa args
-and initializes everything to 0.
-.Pp
-.It Fn fuse_opt_match
-tests if the argument or option
-.Fa opt
-appears in the list of templates
-.Fa opts .
-If
-.Fa opt
-is an option then it must not include the -o prefix.
-.Pp
-.It Fn fuse_opt_parse
-parses options, setting any members of
-.Fa data
-automatically depending on the format of the template.
-If
-.Fa proc
-is not NULL, then this is called for any argument that matches a template
-that has
-.Fa val
-= FUSE_OPT_KEY.
-.Fa opts
-is an array of
-.Ft struct fuse_opt ,
-each of which describes actions for each option:
-.Bd -literal -offset indent
-struct fuse_opt {
- const char *templ; /* template for option */
- unsigned long off; /* data offset */
- int val; /* key value */
-};
-.Ed
-.Pp
-The following templates are supported.
-foo=
-.Pp
-foo=%u %u can be any format that can be parsed by
-.Fn sscanf 3 .
-If this is %s then a copy of the string is allocated.
-foo=bar matches the option exactly (treated the same as if it didn't have an =).
-.Pp
-foo matches exactly
-.Pp
--b or --bar matches the argument
-"-b " or "--bar " (trailing space) argument expects a value, that is passed to
-.Fa proc
-.Pp
--b %u or:w
- --bar %u Treated the same as foo=%u above
-.Pp
-Each argument or option is matched against every template.
-This allows more than one member of
-.Fa data
-to be set by a single argument or option (see example for gid below).
-.El
-.Sh RETURN VALUES
-.Fn fuse_opt_add_arg ,
-.Fn fuse_opt_insert_arg ,
-.Fn fuse_opt_add_opt ,
-.Fn fuse_opt_add_opt_escaped ,
-and
-.Fn fuse_opt_parse
-return 0 on success, -1 on error.
-.Pp
-.Fn fuse_opt_match
-returns 1 on match, 0 if no match.
-.Sh ERRORS
-.Fn fuse_opt_add_arg ,
-.Fn fuse_opt_insert_arg ,
-.Fn fuse_opt_add_opt ,
-and
-.Fn fuse_opt_add_opt_escaped
-can run out of memory and set
-.Va errno .
-.Sh SEE ALSO
-.Xr fuse_main 3
-.Sh STANDARDS
-These library functions conform to FUSE 2.6.
-.Sh HISTORY
-These functions first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
-.An Helg Bredow Aq Mt xx404@msn.com
-.Pp
-This manual was written by
-.An Ray Lai Aq Mt ray@raylai.com
-and updated by
-.An Helg Bredow Aq Mt xx404@msn.com
blob - 38bf34a7d157a543ee47f18bf350cb9183ab9803 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_opt.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/* $OpenBSD: fuse_opt.c,v 1.26 2018/05/15 11:57:32 helg Exp $ */
-/*
- * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
- * Copyright (c) 2013 Stefan Sperling <stsp@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "debug.h"
-#include "fuse_opt.h"
-#include "fuse_private.h"
-
-#define IFUSE_OPT_DISCARD 0
-#define IFUSE_OPT_KEEP 1
-#define IFUSE_OPT_NEED_ANOTHER_ARG 2
-
-static void
-free_argv(char **argv, int argc)
-{
- int i;
-
- for (i = 0; i < argc; i++)
- free(argv[i]);
- free(argv);
-}
-
-static int
-alloc_argv(struct fuse_args *args)
-{
- char **argv;
- int i;
-
- assert(!args->allocated);
-
- argv = calloc(args->argc, sizeof(*argv));
- if (argv == NULL)
- return (-1);
-
- if (args->argv) {
- for (i = 0; i < args->argc; i++) {
- argv[i] = strdup(args->argv[i]);
- if (argv[i] == NULL) {
- free_argv(argv, i + 1);
- return (-1);
- }
- }
- }
-
- args->allocated = 1;
- args->argv = argv;
-
- return (0);
-}
-
-/*
- * Returns the number of characters that matched for bounds checking later.
- */
-static size_t
-match_opt(const char *templ, const char *opt)
-{
- size_t sep, len;
-
- len = strlen(templ);
- sep = strcspn(templ, "=");
-
- if (sep == len)
- sep = strcspn(templ, " ");
-
- /* key=, key=%, "-k ", -k % */
- if (sep < len && (templ[sep + 1] == '\0' || templ[sep + 1] == '%')) {
- if (strncmp(opt, templ, sep) == 0)
- return (sep);
- else
- return (0);
- }
-
- if (strcmp(opt, templ) == 0)
- return (len);
-
- return (0);
-}
-
-static int
-add_opt(char **opts, const char *opt)
-{
- char *new_opts;
-
- if (*opts == NULL) {
- *opts = strdup(opt);
- if (*opts == NULL)
- return (-1);
- return (0);
- }
-
- if (asprintf(&new_opts, "%s,%s", *opts, opt) == -1)
- return (-1);
-
- free(*opts);
- *opts = new_opts;
- return (0);
-}
-
-int
-fuse_opt_add_opt(char **opts, const char *opt)
-{
- int ret;
-
- if (opt == NULL || opt[0] == '\0')
- return (-1);
-
- ret = add_opt(opts, opt);
- return (ret);
-}
-
-int
-fuse_opt_add_opt_escaped(char **opts, const char *opt)
-{
- size_t size = 0, escaped = 0;
- const char *s = opt;
- char *escaped_opt, *p;
- int ret;
-
- if (opt == NULL || opt[0] == '\0')
- return (-1);
-
- while (*s) {
- /* malloc(size + escaped) overflow check */
- if (size >= (SIZE_MAX / 2))
- return (-1);
-
- if (*s == ',' || *s == '\\')
- escaped++;
- s++;
- size++;
- }
- size++; /* trailing NUL */
-
- if (escaped > 0) {
- escaped_opt = malloc(size + escaped);
- if (escaped_opt == NULL)
- return (-1);
- s = opt;
- p = escaped_opt;
- while (*s) {
- switch (*s) {
- case ',':
- case '\\':
- *p++ = '\\';
- /* FALLTHROUGH */
- default:
- *p++ = *s++;
- }
- }
- *p = '\0';
- } else {
- escaped_opt = strdup(opt);
- if (escaped_opt == NULL)
- return (-1);
- }
-
- ret = add_opt(opts, escaped_opt);
- free(escaped_opt);
- return (ret);
-}
-
-int
-fuse_opt_add_arg(struct fuse_args *args, const char *name)
-{
- return (fuse_opt_insert_arg(args, args->argc, name));
-}
-DEF(fuse_opt_add_arg);
-
-static int
-parse_opt(const struct fuse_opt *o, const char *opt, void *data,
- fuse_opt_proc_t f, struct fuse_args *arg)
-{
- const char *val;
- int keyval, ret, found;
- size_t sep;
-
- keyval = 0;
- found = 0;
-
- for(; o != NULL && o->templ; o++) {
- sep = match_opt(o->templ, opt);
- if (sep == 0)
- continue;
-
- found = 1;
- val = opt;
-
- /* check key=value or -p n */
- if (o->templ[sep] == '=') {
- keyval = 1;
- val = &opt[sep + 1];
- } else if (o->templ[sep] == ' ') {
- keyval = 1;
- if (sep == strlen(opt)) {
- /* ask for next arg to be included */
- return (IFUSE_OPT_NEED_ANOTHER_ARG);
- } else if (strchr(o->templ, '%') != NULL) {
- val = &opt[sep];
- }
- }
-
- if (o->val == FUSE_OPT_KEY_DISCARD)
- ret = IFUSE_OPT_DISCARD;
- else if (o->val == FUSE_OPT_KEY_KEEP)
- ret = IFUSE_OPT_KEEP;
- else if (FUSE_OPT_IS_OPT_KEY(o)) {
- if (f == NULL)
- return (IFUSE_OPT_KEEP);
-
- ret = f(data, val, o->val, arg);
- } else if (data == NULL) {
- return (-1);
- } else if (strchr(o->templ, '%') == NULL) {
- *((int *)(data + o->off)) = o->val;
- ret = IFUSE_OPT_DISCARD;
- } else if (strstr(o->templ, "%s") != NULL) {
- *((char **)(data + o->off)) = strdup(val);
- ret = IFUSE_OPT_DISCARD;
- } else {
- /* All other templates, let sscanf deal with them. */
- if (sscanf(opt, o->templ, data + o->off) != 1) {
- fprintf(stderr, "fuse: Invalid value %s for "
- "option %s\n", val, o->templ);
- return (-1);
- }
- ret = IFUSE_OPT_DISCARD;
- }
- }
-
- if (found)
- return (ret);
-
- if (f != NULL)
- return f(data, opt, FUSE_OPT_KEY_OPT, arg);
-
- return (IFUSE_OPT_KEEP);
-}
-
-/*
- * this code is not very sexy but we are forced to follow
- * the fuse api.
- *
- * when f() returns 1 we need to keep the arg
- * when f() returns 0 we need to discard the arg
- */
-int
-fuse_opt_parse(struct fuse_args *args, void *data,
- const struct fuse_opt *opt, fuse_opt_proc_t f)
-{
- struct fuse_args outargs;
- const char *arg, *ap;
- char *optlist, *tofree;
- int ret;
- int i;
-
- if (!args || !args->argc || !args->argv)
- return (0);
-
- memset(&outargs, 0, sizeof(outargs));
- fuse_opt_add_arg(&outargs, args->argv[0]);
-
- for (i = 1; i < args->argc; i++) {
- arg = args->argv[i];
- ret = 0;
-
- /* not - and not -- */
- if (arg[0] != '-') {
- if (f == NULL)
- ret = IFUSE_OPT_KEEP;
- else
- ret = f(data, arg, FUSE_OPT_KEY_NONOPT, &outargs);
-
- if (ret == IFUSE_OPT_KEEP)
- fuse_opt_add_arg(&outargs, arg);
- if (ret == -1)
- goto err;
- } else if (arg[1] == 'o') {
- if (arg[2])
- arg += 2; /* -ofoo,bar */
- else {
- if (++i >= args->argc)
- goto err;
-
- arg = args->argv[i];
- }
-
- tofree = optlist = strdup(arg);
- if (optlist == NULL)
- goto err;
-
- while ((ap = strsep(&optlist, ",")) != NULL &&
- ret != -1) {
- ret = parse_opt(opt, ap, data, f, &outargs);
- if (ret == IFUSE_OPT_KEEP) {
- fuse_opt_add_arg(&outargs, "-o");
- fuse_opt_add_arg(&outargs, ap);
- }
- }
-
- free(tofree);
-
- if (ret == -1)
- goto err;
- } else {
- ret = parse_opt(opt, arg, data, f, &outargs);
-
- if (ret == IFUSE_OPT_KEEP)
- fuse_opt_add_arg(&outargs, arg);
- else if (ret == IFUSE_OPT_NEED_ANOTHER_ARG) {
- /* arg needs a value */
- if (++i >= args->argc) {
- fprintf(stderr, "fuse: missing argument after %s\n", arg);
- goto err;
- }
-
- if (asprintf(&tofree, "%s%s", arg,
- args->argv[i]) == -1)
- goto err;
-
- ret = parse_opt(opt, tofree, data, f, &outargs);
- if (ret == IFUSE_OPT_KEEP)
- fuse_opt_add_arg(&outargs, tofree);
- free(tofree);
- }
-
- if (ret == -1)
- goto err;
- }
- }
- ret = 0;
-
-err:
- /* Update args */
- fuse_opt_free_args(args);
- args->allocated = outargs.allocated;
- args->argc = outargs.argc;
- args->argv = outargs.argv;
- if (ret != 0)
- ret = -1;
-
- return (ret);
-}
-DEF(fuse_opt_parse);
-
-int
-fuse_opt_insert_arg(struct fuse_args *args, int p, const char *name)
-{
- char **av;
- char *this_arg, *next_arg;
- int i;
-
- if (name == NULL)
- return (-1);
-
- if (!args->allocated && alloc_argv(args))
- return (-1);
-
- if (p < 0 || p > args->argc)
- return (-1);
-
- av = reallocarray(args->argv, args->argc + 2, sizeof(*av));
- if (av == NULL)
- return (-1);
-
- this_arg = strdup(name);
- if (this_arg == NULL) {
- free(av);
- return (-1);
- }
-
- args->argc++;
- args->argv = av;
- args->argv[args->argc] = NULL;
- for (i = p; i < args->argc; i++) {
- next_arg = args->argv[i];
- args->argv[i] = this_arg;
- this_arg = next_arg;
- }
- return (0);
-}
-DEF(fuse_opt_insert_arg);
-
-void
-fuse_opt_free_args(struct fuse_args *args)
-{
- if (!args->allocated)
- return;
-
- free_argv(args->argv, args->argc);
- args->argv = 0;
- args->argc = 0;
- args->allocated = 0;
-}
-DEF(fuse_opt_free_args);
-
-int
-fuse_opt_match(const struct fuse_opt *opts, const char *opt)
-{
- const struct fuse_opt *this_opt = opts;
-
- if (opt == NULL || opt[0] == '\0')
- return (0);
-
- while (this_opt->templ) {
- if (match_opt(this_opt->templ, opt))
- return (1);
- this_opt++;
- }
-
- return (0);
-}
-DEF(fuse_opt_match);
blob - ddf173b19337c178ca2a2565012c16b697b5c5c9 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_opt.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* $OpenBSD: fuse_opt.h,v 1.5 2018/04/08 20:57:28 jca Exp $ */
-/*
- * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _FUSE_OPT_H_
-#define _FUSE_OPT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct fuse_args {
- int argc;
- char **argv;
- int allocated;
-};
-
-struct fuse_opt {
- const char *templ;
- unsigned long off;
- int val;
-};
-
-typedef int (*fuse_opt_proc_t)(void *, const char *, int, struct fuse_args *);
-int fuse_opt_add_arg(struct fuse_args *, const char *);
-int fuse_opt_insert_arg(struct fuse_args *, int, const char *);
-void fuse_opt_free_args(struct fuse_args *);
-int fuse_opt_add_opt(char **, const char *);
-int fuse_opt_add_opt_escaped(char **, const char *);
-int fuse_opt_match(const struct fuse_opt *, const char *);
-int fuse_opt_parse(struct fuse_args *, void *, const struct fuse_opt *,
- fuse_opt_proc_t);
-
-#define FUSE_ARGS_INIT(ac, av) { ac, av, 0 }
-
-#define FUSE_OPT_IS_OPT_KEY(t) (t->off == (unsigned long)-1)
-
-#define FUSE_OPT_KEY(t, k) { t, (unsigned long)-1, k }
-#define FUSE_OPT_END { NULL, 0, 0 }
-#define FUSE_OPT_KEY_OPT -1
-#define FUSE_OPT_KEY_NONOPT -2
-#define FUSE_OPT_KEY_KEEP -3
-#define FUSE_OPT_KEY_DISCARD -4
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FUSE_OPT_H_ */
blob - 562012f125c5a7f3c85656551c5dab8038178e5d (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_parse_cmdline.3
+++ /dev/null
@@ -1,100 +0,0 @@
-.\" $OpenBSD: fuse_parse_cmdline.3,v 1.1 2018/11/28 21:19:11 mpi Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg.bredow@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: November 28 2018 $
-.Dt FUSE_PARSE_CMDLINE 3
-.Os
-.Sh NAME
-.Nm fuse_parse_cmdline
-.Nd FUSE helper function to parse command line arguments
-.Sh SYNOPSIS
-.In fuse.h
-.Ft int
-.Fn fuse_parse_cmdline "struct fuse_args *args" "char **mp" \
- "int *mt" "int *fg"
-.Sh DESCRIPTION
-.Fn fuse_parse_cmdline
-is a helper function to parse standard FUSE arguments.
-.Fa args
-can be constructed using the
-.Xr FUSE_ARGS_INIT 3
-macro.
-.Pp
-.Fn fuse_parse_cmdline
-supports the following arguments.
-.Bl -tag -width Ds
-.It Fl d , Fl odebug
-Causes debug information for subsequent FUSE library calls to be output to
-stderr.
-Implies
-.Fl f .
-.It Fl f
-If this is specified then
-.Fa fg
-will be set to 1 on success.
-This flag indicates that the file system
-should not detach from the controlling terminal and run in the foreground.
-.It Fl h , Fl -help , Fl ho
-Print usage information for the options supported by
-.Fn fuse_parse_cmdline .
-.It Fl s
-If this is specified then
-.Fa mt
-will be set to 0 on success.
-This flag indicates that the file system
-should be run in multi-threaded mode.
-.Fl s
-is currently ignored and
-.Fa mt
-will always be 0.
-.It Fl V , Fl -version
-Print the FUSE library version to stderr.
-.El
-.Pp
-If the first argument not recognised by
-.Fn fuse_parse_cmdline
-is a valid directory then
-.Fa mp
-will be set to the canonicalized absolute pathname of this directory.
-.Sh RETURN VALUES
-The
-.Fn fuse_parse_cmdline
-function will return 0 on success and -1 if
-.Fl h , Fl -help , Fl ho , Fl v
-or
-.Fl -version
-are included in
-.Fa argv
-or
-.Fa mp
-does not exist or is not a directory.
-.Sh SEE ALSO
-.Xr FUSE_ARGS_INIT 3 ,
-.Xr fuse_daemonize 3 ,
-.Xr fuse_main 3 ,
-.Xr fuse_setup 3
-.Sh STANDARDS
-The
-.Fn fuse_parse_cmdline
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_parse_cmdline
-function first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
-.An Helg Bredow Aq Mt helg@openbsd.org
blob - 208c997828a2608d2d8794da26a2bccab416c040 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_private.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* $OpenBSD: fuse_private.h,v 1.22 2018/11/16 02:16:17 tedu Exp $ */
-/*
- * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _FUSE_SUBR_H_
-#define _FUSE_SUBR_H_
-
-#include <sys/dirent.h>
-#include <sys/event.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/tree.h>
-#include <sys/fusebuf.h>
-#include <limits.h>
-
-#include "fuse.h"
-
-struct fuse_args;
-
-struct fuse_vnode {
- ino_t ino;
- struct fuse_vnode *parent;
- unsigned int ref;
-
- char path[NAME_MAX + 1];
-
- SIMPLEQ_ENTRY(fuse_vnode) node; /* for dict */
-};
-
-struct fuse_dirhandle {
- struct fuse *fuse;
- fuse_fill_dir_t filler;
- void *buf;
- int full;
- uint32_t size;
- uint32_t start;
- uint32_t idx;
- off_t off;
-};
-
-SIMPLEQ_HEAD(fuse_vn_head, fuse_vnode);
-SPLAY_HEAD(dict, dictentry);
-SPLAY_HEAD(tree, treeentry);
-
-struct fuse_session {
- void *args;
-};
-
-struct fuse_chan {
- char *dir;
- struct fuse_args *args;
-
- int fd;
- int dead;
-
- /* kqueue stuff */
- int kq;
-};
-
-struct fuse_config {
- uid_t uid;
- gid_t gid;
- pid_t pid;
- mode_t umask;
- int set_mode;
- int set_uid;
- int set_gid;
- int use_ino;
-};
-
-struct fuse_core_opts {
- char *mp;
- int foreground;
-};
-
-struct fuse_mount_opts {
- char *fsname;
- int allow_other;
- int def_perms;
- int max_read;
- int noatime;
- int nonempty;
- int rdonly;
-};
-
-struct fuse {
- struct fuse_chan *fc;
- struct fuse_operations op;
-
- int compat;
-
- struct tree vnode_tree;
- struct dict name_tree;
- uint64_t max_ino;
- void *private_data;
-
- struct fuse_config conf;
- struct fuse_session se;
-};
-
-#define FUSE_MAX_OPS 39
-#define FUSE_ROOT_INO ((ino_t)1)
-
-/* fuse_ops.c */
-int ifuse_exec_opcode(struct fuse *, struct fusebuf *);
-
-/* fuse_subr.c */
-struct fuse_vnode *alloc_vn(struct fuse *, const char *, ino_t, ino_t);
-void ref_vn(struct fuse_vnode *);
-void unref_vn(struct fuse *, struct fuse_vnode *);
-struct fuse_vnode *get_vn_by_name_and_parent(struct fuse *, uint8_t *,
- ino_t);
-void remove_vnode_from_name_tree(struct fuse *,
- struct fuse_vnode *);
-int set_vn(struct fuse *, struct fuse_vnode *);
-char *build_realname(struct fuse *, ino_t);
-
-/* tree.c */
-#define tree_init(t) SPLAY_INIT((t))
-#define tree_empty(t) SPLAY_EMPTY((t))
-int tree_check(struct tree *, uint64_t);
-void *tree_set(struct tree *, uint64_t, void *);
-void *tree_get(struct tree *, uint64_t);;
-void *tree_pop(struct tree *, uint64_t);
-
-/* dict.c */
-int dict_check(struct dict *, const char *);
-void *dict_set(struct dict *, const char *, void *);
-void *dict_get(struct dict *, const char *);;
-void *dict_pop(struct dict *, const char *);
-
-#define FUSE_VERSION_PKG_INFO "2.8.0"
-#define unused __attribute__ ((unused))
-
-#define PROTO(x) __dso_hidden typeof(x) x asm("__"#x)
-#define DEF(x) __strong_alias(x, __##x)
-
-PROTO(fuse_daemonize);
-PROTO(fuse_destroy);
-PROTO(fuse_get_context);
-PROTO(fuse_get_session);
-PROTO(fuse_loop);
-PROTO(fuse_mount);
-PROTO(fuse_new);
-PROTO(fuse_opt_add_arg);
-PROTO(fuse_opt_free_args);
-PROTO(fuse_opt_insert_arg);
-PROTO(fuse_opt_match);
-PROTO(fuse_opt_parse);
-PROTO(fuse_parse_cmdline);
-PROTO(fuse_remove_signal_handlers);
-PROTO(fuse_setup);
-PROTO(fuse_unmount);
-
-#endif /* _FUSE_SUBR_ */
blob - ec81adaf794fbb90ae913eba494d349dc505916b (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_set_signal_handlers.3
+++ /dev/null
@@ -1,62 +0,0 @@
-.\" $OpenBSD: fuse_set_signal_handlers.3,v 1.2 2018/07/05 14:55:05 jmc Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: July 5 2018 $
-.Dt FUSE_SET_SIGNAL_HANDLERS 3
-.Os
-.Sh NAME
-.Nm fuse_set_signal_handlers ,
-.Nm fuse_remove_signal_handlers
-.Nd install and remove FUSE signal handlers
-.Sh SYNOPSIS
-.In fuse.h
-.Ft int
-.Fn fuse_set_signal_handlers "struct fuse_session *se"
-.Ft void
-.Fn fuse_remove_signal_handlers "struct fuse_session *se"
-.Sh DESCRIPTION
-.Fn fuse_set_signal_handlers
-installs signal handlers for the signals SIGHUP, SIGINT and SIGTERM that
-will attempt to unmount the file system.
-SIGPIPE will be ignored.
-If there is already a signal handler installed for any of these signals
-then it is not replaced.
-.Pp
-.Fn fuse_remove_signal_handlers
-will restore the default signal handlers for any signals that were
-installed by
-.Fn fuse_set_signal_handlers .
-.Sh RETURN VALUES
-.Fn fuse_set_signal_handlers
-will return 0 on success and -1 on failure.
-.Sh SEE ALSO
-.Xr sigaction 2 ,
-.Xr fuse_setup 3
-.Sh STANDARDS
-The
-.Fn fuse_set_signal_handlers
-and
-.Fn fuse_remove_signal_handlers
-functions conform to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_set_signal_handlers
-and
-.Fn fuse_remove_signal_handlers
-functions first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Helg Bredow Aq Mt helg@openbsd.org
blob - 9a1902e8f509279ef7dc9a91fd9fbb3a93f196fd (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_setup.3
+++ /dev/null
@@ -1,87 +0,0 @@
-.\" $OpenBSD: fuse_setup.3,v 1.3 2018/11/28 21:19:11 mpi Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg.bredow@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: November 28 2018 $
-.Dt FUSE_SETUP 3
-.Os
-.Sh NAME
-.Nm fuse_setup
-.Nd FUSE helper function
-.Sh SYNOPSIS
-.In fuse.h
-.Ft struct fuse *
-.Fn fuse_setup "int argc" "char **argv" \
- "const struct fuse_operations *ops" "size_t size" "char **mp" \
- "int *mt" "void *data"
-.Sh DESCRIPTION
-.Fn fuse_setup
-is a helper function that mounts a FUSE file system, creates a new FUSE
-session and installs signal handlers that will try to unmount the file
-system on SIGINT, SIGTERM or SIGHUP.
-.Pp
-.Fn fuse_setup
-will parse the arguments specified by argv and if neither the
-.Fl f , Fl d
-or
-.Fl odebug
-options were specified, detach from the controlling terminal
-and run in the background.
-On success,
-.Fa mt
-will be 1 if the file system operations will be invoked in
-parallel (multi-threaded) or 0 if file system operations are serialized.
-File systems that do not support multi-threaded operation must include the
-.Fl s
-argument in
-.Fa argv .
-.Ox
-does not currently support multi-threaded operation.
-.Pp
-The file system will be mounted on
-.Fa mp ,
-which is the directory specified by the first
-argument that does not match one of the options recognised by
-.Xr fuse_parse_cmdline 3 .
-.Pp
-.Fa fuse_operations
-is a struct of size
-.Fa size
-that contains pointers to FUSE file system operations.
-See
-.Xr fuse_new 3 .
-.Sh RETURN VALUES
-.Fn fuse_setup
-will return NULL on failure.
-.Sh SEE ALSO
-.Xr fuse_main 3 ,
-.Xr fuse_mount 3 ,
-.Xr fuse_new 3 ,
-.Xr fuse_parse_cmdline 3 ,
-.Xr fuse_set_signal_handlers 3 ,
-.Xr fuse_teardown 3 ,
-.Xr fuse 4
-.Sh STANDARDS
-The
-.Fn fuse_setup
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_setup
-function first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
-.An Helg Bredow Aq Mt helg@openbsd.org
blob - c34cf0f40557e654031ade8a1386305a6fd1f76f (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_subr.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/* $OpenBSD: fuse_subr.c,v 1.12 2018/05/21 11:47:46 helg Exp $ */
-/*
- * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "fuse_private.h"
-#include "debug.h"
-
-struct fuse_vnode *
-alloc_vn(struct fuse *f, const char *path, ino_t ino, ino_t pino)
-{
- struct fuse_vnode *vn;
-
- if ((vn = malloc(sizeof(*vn))) == NULL) {
- DPERROR(__func__);
- return (NULL);
- }
-
- vn->ino = ino;
- vn->ref = 1;
- if (strlcpy(vn->path, path, sizeof(vn->path)) >= sizeof(vn->path)) {
- DPRINTF("%s: strlcpy name too long\n", __func__);
- free(vn);
- return (NULL);
- }
-
- if (pino == (ino_t)0)
- vn->parent = NULL;
- else {
- if ((vn->parent = tree_get(&f->vnode_tree, pino)) == NULL) {
- DPRINTF("%s: parent vnode %llu not in the vnode tree\n",
- __func__, pino);
- free(vn);
- errno = ENOENT;
- return (NULL);
- }
- ref_vn(vn->parent);
- }
-
- if (ino == (ino_t)-1) {
- f->max_ino++;
- vn->ino = f->max_ino;
- DPRINTF("New Inode: %llu\t", (unsigned long long)vn->ino);
- }
-
- return (vn);
-}
-
-void
-ref_vn(struct fuse_vnode *vn)
-{
- vn->ref++;
-}
-
-void
-unref_vn(struct fuse *f, struct fuse_vnode *vn)
-{
- if (--vn->ref == 0) {
- tree_pop(&f->vnode_tree, vn->ino);
- remove_vnode_from_name_tree(f, vn);
- if (vn->parent != NULL)
- unref_vn(f, vn->parent);
- free(vn);
- }
-}
-
-int
-set_vn(struct fuse *f, struct fuse_vnode *v)
-{
- struct fuse_vn_head *vn_head;
- struct fuse_vnode *vn;
-
- if (tree_set(&f->vnode_tree, v->ino, v) == NULL)
- return (0);
-
- if (!dict_check(&f->name_tree, v->path)) {
- vn_head = malloc(sizeof(*vn_head));
- if (vn_head == NULL)
- return (0);
- SIMPLEQ_INIT(vn_head);
- } else {
- vn_head = dict_get(&f->name_tree, v->path);
- if (vn_head == NULL)
- return (0);
- }
-
- SIMPLEQ_FOREACH(vn, vn_head, node) {
- if (v->parent == vn->parent && v->ino == vn->ino)
- return (1);
- }
-
- SIMPLEQ_INSERT_TAIL(vn_head, v, node);
- dict_set(&f->name_tree, v->path, vn_head);
-
- return (1);
-}
-
-void
-remove_vnode_from_name_tree(struct fuse *f, struct fuse_vnode *vn)
-{
- struct fuse_vn_head *vn_head;
- struct fuse_vnode *v;
- struct fuse_vnode *lastv;
-
- vn_head = dict_get(&f->name_tree, vn->path);
- if (vn_head == NULL)
- return;
-
- lastv = NULL;
- SIMPLEQ_FOREACH(v, vn_head, node) {
- if (v->parent == vn->parent)
- break;
-
- lastv = v;
- }
- if (v == NULL)
- return;
-
- /* if we found the vnode remove it */
- if (v == SIMPLEQ_FIRST(vn_head))
- SIMPLEQ_REMOVE_HEAD(vn_head, node);
- else
- SIMPLEQ_REMOVE_AFTER(vn_head, lastv, node);
-
- /* if the queue is empty we need to remove it from the dict */
- if (SIMPLEQ_EMPTY(vn_head)) {
- vn_head = dict_pop(&f->name_tree, vn->path);
- free(vn_head);
- }
-}
-
-struct fuse_vnode *
-get_vn_by_name_and_parent(struct fuse *f, uint8_t *xpath, ino_t pino)
-{
- struct fuse_vn_head *vn_head;
- struct fuse_vnode *v = NULL;
- const char *path = (const char *)xpath;
-
- vn_head = dict_get(&f->name_tree, path);
-
- if (vn_head == NULL)
- goto fail;
-
- SIMPLEQ_FOREACH(v, vn_head, node)
- if (v->parent && v->parent->ino == pino)
- return (v);
-
-fail:
- errno = ENOENT;
- return (NULL);
-}
-
-char *
-build_realname(struct fuse *f, ino_t ino)
-{
- struct fuse_vnode *vn;
- char *name;
- char *tmp = NULL;
- int firstshot = 0, ret;
-
- name = strdup("/");
- if (name == NULL)
- return (NULL);
-
- vn = tree_get(&f->vnode_tree, ino);
- if (!vn || !name) {
- free(name);
- return (NULL);
- }
-
- while (vn->parent != NULL) {
- if (firstshot++)
- ret = asprintf(&tmp, "/%s%s", vn->path, name);
- else
- ret = asprintf(&tmp, "/%s", vn->path);
-
- if (ret == -1) {
- free(name);
- return (NULL);
- }
-
- free(name);
- name = tmp;
- tmp = NULL;
- vn = vn->parent;
- }
-
- if (ino == (ino_t)0)
- DPRINTF("%s: NULL ino\t", __func__);
-
- DPRINTF("%s", name);
- return (name);
-}
blob - b731bc69113b0d3137b4bf074e1284b4178e8e8e (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_teardown.3
+++ /dev/null
@@ -1,54 +0,0 @@
-.\" $OpenBSD: fuse_teardown.3,v 1.2 2018/07/08 06:17:10 jmc Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg.bredow@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: July 8 2018 $
-.Dt FUSE_TEARDOWN 3
-.Os
-.Sh NAME
-.Nm fuse_teardown
-.Nd FUSE helper function
-.Sh SYNOPSIS
-.In fuse.h
-.Ft void
-.Fn fuse_teardown "struct fuse *f" "char *mp"
-.Sh DESCRIPTION
-.Fn fuse_teardown
-is a helper function that removes any signal handlers that were
-installed by a previous call to
-.Xr fuse_set_signal_handlers 3
-or
-.Xr fuse_setup 3
-and unmounts the file system mounted at
-.Fa mp .
-The FUSE session
-.Fa f
-is then destroyed.
-.Sh SEE ALSO
-.Xr fuse_destroy 3 ,
-.Xr fuse_remove_signal_handlers 3 ,
-.Xr fuse_unmount 3
-.Sh STANDARDS
-The
-.Fn fuse_teardown
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_teardown
-function first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
-.An Helg Bredow Aq Mt helg@openbsd.org
blob - 26f8c4b33098a57c3d494a5384b61e38d5cb1ee7 (mode 644)
blob + /dev/null
--- lib/libfuse/fuse_version.3
+++ /dev/null
@@ -1,42 +0,0 @@
-.\" $OpenBSD: fuse_version.3,v 1.2 2018/07/08 06:17:10 jmc Exp $
-.\"
-.\" Copyright (c) 2018 Helg Bredow <helg@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: July 8 2018 $
-.Dt FUSE_VERSION 3
-.Os
-.Sh NAME
-.Nm fuse_version
-.Nd get the version of the FUSE library
-.Sh SYNOPSIS
-.In fuse.h
-.Ft int
-.Fn fuse_version "void"
-.Sh DESCRIPTION
-Gets the version of the FUSE library as a whole number.
-For example, Version 2.6 is returned as 26.
-.Sh SEE ALSO
-.Xr fuse_main 3
-.Sh STANDARDS
-The
-.Fn fuse_version
-function conforms to FUSE 2.6.
-.Sh HISTORY
-The
-.Fn fuse_version
-function first appeared in
-.Ox 5.4 .
-.Sh AUTHORS
-.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
blob - b0b0fd270e7d373f73b6fed1b8dd73f6b788c9a9 (mode 644)
blob + /dev/null
--- lib/libfuse/generate_pkgconfig.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-#
-# $OpenBSD: generate_pkgconfig.sh,v 1.2 2013/06/15 11:40:56 jasper Exp $
-#
-# Copyright (c) 2010,2011 Jasper Lievisse Adriaanse <jasper@openbsd.org>
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-# Generate pkg-config file for fuse
-
-usage() {
- echo "usage: ${0##*/} -c current_directory -o obj_directory"
- exit 1
-}
-
-curdir=
-objdir=
-while getopts "c:o:" flag; do
- case "$flag" in
- c)
- curdir=$OPTARG
- ;;
- o)
- objdir=$OPTARG
- ;;
- *)
- usage
- ;;
- esac
-done
-
-[ -n "${curdir}" ] || usage
-if [ ! -d "${curdir}" ]; then
- echo "${0##*/}: ${curdir}: not found"
- exit 1
-fi
-[ -n "${objdir}" ] || usage
-if [ ! -w "${objdir}" ]; then
- echo "${0##*/}: ${objdir}: not found or not writable"
- exit 1
-fi
-
-version_re="s/^#define[[:blank:]]+FUSE_VERSION_PKG_INFO[[:blank:]]+\"(.*)\".*/\1/p"
-version_file=${curdir}/fuse_private.h
-lib_version=$(sed -nE ${version_re} ${version_file})
-
-pc_file="${objdir}/fuse.pc"
-cat > ${pc_file} << __EOF__
-prefix=/usr
-exec_prefix=\${prefix}
-libdir=\${exec_prefix}/lib
-includedir=\${prefix}/include
-
-Name: fuse
-Description: fuse filesystem library
-Version: ${lib_version}
-Requires:
-Libs: -L\${libdir} -lfuse
-Cflags: -I\${includedir}
-__EOF__
blob - b52599a164f6872e7c8b55a4df1f1c6e25ae4012 (mode 644)
blob + /dev/null
--- lib/libfuse/shlib_version
+++ /dev/null
@@ -1,2 +0,0 @@
-major=2
-minor=0
blob - dccd6e875c372b3f9bedf6aaa08a18fce45fb0ae (mode 644)
blob + /dev/null
--- lib/libfuse/tree.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* $OpenBSD: tree.c,v 1.2 2014/02/05 20:13:58 syl Exp $ */
-
-/*
- * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <errno.h>
-
-#include "fuse_private.h"
-
-struct treeentry {
- SPLAY_ENTRY(treeentry) entry;
- uint64_t id;
- void *data;
-};
-
-static int treeentry_cmp(struct treeentry *, struct treeentry *);
-
-SPLAY_PROTOTYPE(tree, treeentry, entry, treeentry_cmp);
-
-int
-tree_check(struct tree *t, uint64_t id)
-{
- struct treeentry key;
-
- key.id = id;
- return (SPLAY_FIND(tree, t, &key) != NULL);
-}
-
-void *
-tree_set(struct tree *t, uint64_t id, void *data)
-{
- struct treeentry *entry, key;
-
- key.id = id;
- if ((entry = SPLAY_FIND(tree, t, &key)) == NULL) {
- entry = malloc(sizeof *entry);
- if (entry == NULL)
- return (NULL);
- entry->id = id;
- SPLAY_INSERT(tree, t, entry);
- }
-
- entry->data = data;
-
- return (entry);
-}
-
-void *
-tree_get(struct tree *t, uint64_t id)
-{
- struct treeentry key, *entry;
-
- key.id = id;
- if ((entry = SPLAY_FIND(tree, t, &key)) == NULL) {
- errno = ENOENT;
- return (NULL);
- }
-
- return (entry->data);
-}
-
-void *
-tree_pop(struct tree *t, uint64_t id)
-{
- struct treeentry key, *entry;
- void *data;
-
- key.id = id;
- if ((entry = SPLAY_FIND(tree, t, &key)) == NULL)
- return (NULL);
-
- data = entry->data;
- SPLAY_REMOVE(tree, t, entry);
- free(entry);
-
- return (data);
-}
-
-static int
-treeentry_cmp(struct treeentry *a, struct treeentry *b)
-{
- if (a->id < b->id)
- return (-1);
- if (a->id > b->id)
- return (1);
- return (0);
-}
-
-SPLAY_GENERATE(tree, treeentry, entry, treeentry_cmp);
blob - d06f8ec0f464acf05ab3ae39171ed780aa00bd48
blob + ac947678fb84bed9302e835daba4f0ef03f9b070
--- sys/miscfs/fuse/fuse_device.c
+++ sys/miscfs/fuse/fuse_device.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_device.c,v 1.35 2020/12/25 12:59:52 visa Exp $ */
+/* $OpenBSD: fuse_device.c,v 1.34 2020/05/13 08:13:42 mpi Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -25,17 +25,12 @@
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/vnode.h>
-#include <sys/fusebuf.h>
+#include <sys/fuse_kernel.h>
+#include "fusebuf.h"
#include "fusefs_node.h"
#include "fusefs.h"
-#ifdef FUSE_DEBUG
-#define DPRINTF(fmt, arg...) printf("%s: " fmt, "fuse", ##arg)
-#else
-#define DPRINTF(fmt, arg...)
-#endif
-
SIMPLEQ_HEAD(fusebuf_head, fusebuf);
struct fuse_d {
@@ -46,8 +41,6 @@ struct fuse_d {
struct fusebuf_head fd_fbufs_in;
struct fusebuf_head fd_fbufs_wait;
- /* kq fields */
- struct selinfo fd_rsel;
LIST_ENTRY(fuse_d) fd_list;
};
@@ -69,54 +62,6 @@ int fusekqfilter(dev_t dev, struct knote *kn);
int filt_fuse_read(struct knote *, long);
void filt_fuse_rdetach(struct knote *);
-const static struct filterops fuse_rd_filtops = {
- .f_flags = FILTEROP_ISFD,
- .f_attach = NULL,
- .f_detach = filt_fuse_rdetach,
- .f_event = filt_fuse_read,
-};
-
-#ifdef FUSE_DEBUG
-static void
-fuse_dump_buff(char *buff, int len)
-{
- char text[17];
- int i;
-
- if (len < 0) {
- printf("invalid len: %d", len);
- return;
- }
- if (buff == NULL) {
- printf("invalid buff");
- return;
- }
-
- memset(text, 0, 17);
- for (i = 0; i < len; i++) {
- if (i != 0 && (i % 16) == 0) {
- printf(": %s\n", text);
- memset(text, 0, 17);
- }
-
- printf("%.2x ", buff[i] & 0xff);
-
- if (buff[i] > ' ' && buff[i] < '~')
- text[i%16] = buff[i] & 0xff;
- else
- text[i%16] = '.';
- }
-
- if ((i % 16) != 0)
- while ((i % 16) != 0) {
- printf(" ");
- i++;
- }
-
- printf(": %s\n", text);
-}
-#endif
-
struct fuse_d *
fuse_lookup(int unit)
{
@@ -129,7 +74,7 @@ fuse_lookup(int unit)
}
/*
- * Cleanup all msgs from sc_fbufs_in and sc_fbufs_wait.
+ * Cleanup all msgs from fd_fbufs_in and fd_fbufs_wait.
*/
void
fuse_device_cleanup(dev_t dev)
@@ -144,7 +89,6 @@ fuse_device_cleanup(dev_t dev)
/* clear FIFO IN */
lprev = NULL;
SIMPLEQ_FOREACH_SAFE(f, &fd->fd_fbufs_in, fb_next, ftmp) {
- DPRINTF("cleanup unprocessed msg in sc_fbufs_in\n");
if (lprev == NULL)
SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_in, fb_next);
else
@@ -152,7 +96,7 @@ fuse_device_cleanup(dev_t dev)
fb_next);
stat_fbufs_in--;
- f->fb_err = ENXIO;
+ f->fb_err = -ENXIO;
wakeup(f);
lprev = f;
}
@@ -160,7 +104,6 @@ fuse_device_cleanup(dev_t dev)
/* clear FIFO WAIT*/
lprev = NULL;
SIMPLEQ_FOREACH_SAFE(f, &fd->fd_fbufs_wait, fb_next, ftmp) {
- DPRINTF("umount unprocessed msg in sc_fbufs_wait\n");
if (lprev == NULL)
SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_wait, fb_next);
else
@@ -168,7 +111,7 @@ fuse_device_cleanup(dev_t dev)
fb_next);
stat_fbufs_wait--;
- f->fb_err = ENXIO;
+ f->fb_err = -ENXIO;
wakeup(f);
lprev = f;
}
@@ -185,7 +128,7 @@ fuse_device_queue_fbuf(dev_t dev, struct fusebuf *fbuf
SIMPLEQ_INSERT_TAIL(&fd->fd_fbufs_in, fbuf, fb_next);
stat_fbufs_in++;
- selwakeup(&fd->fd_rsel);
+ wakeup_one(&fd->fd_fbufs_in);
}
void
@@ -197,7 +140,14 @@ fuse_device_set_fmp(struct fusefs_mnt *fmp, int set)
if (fd == NULL)
return;
- fd->fd_fmp = set ? fmp : NULL;
+ if (set)
+ fd->fd_fmp = fmp;
+ else {
+ fd->fd_fmp = NULL;
+
+ /* Let sleeping daemons know the device is dead */
+ wakeup(&fd->fd_fbufs_in);
+ }
}
void
@@ -232,199 +182,87 @@ int
fuseclose(dev_t dev, int flags, int fmt, struct proc *p)
{
struct fuse_d *fd;
- int error;
fd = fuse_lookup(minor(dev));
if (fd == NULL)
return (EINVAL);
if (fd->fd_fmp) {
- printf("fuse: device close without umount\n");
+ /*
+ * Device closed without umount. This is OK but don't
+ * automatically unmount the file system since it may be
+ * unmounted later. Worst case, it can be unmounted manually
+ * with umount(2).
+ */
fd->fd_fmp->sess_init = 0;
fuse_device_cleanup(dev);
- if ((vfs_busy(fd->fd_fmp->mp, VB_WRITE | VB_NOWAIT)) != 0)
- goto end;
- error = dounmount(fd->fd_fmp->mp, MNT_FORCE, p);
- if (error)
- printf("fuse: unmount failed with error %d\n", error);
- fd->fd_fmp = NULL;
+ fuse_device_set_fmp(fd->fd_fmp, 0);
}
-end:
LIST_REMOVE(fd, fd_list);
free(fd, M_DEVBUF, sizeof(*fd));
stat_opened_fusedev--;
return (0);
}
-/*
- * FIOCGETFBDAT Get fusebuf datas from kernel to user
- * FIOCSETFBDAT Set fusebuf datas from user to kernel
- */
int
-fuseioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
+fuseread(dev_t dev, struct uio *uio, int ioflag)
{
- struct fb_ioctl_xch *ioexch;
- struct fusebuf *lastfbuf;
- struct fusebuf *fbuf;
struct fuse_d *fd;
+ struct fusebuf *fbuf;
int error = 0;
fd = fuse_lookup(minor(dev));
if (fd == NULL)
return (ENXIO);
- switch (cmd) {
- case FIOCGETFBDAT:
- ioexch = (struct fb_ioctl_xch *)addr;
+ if (fd->fd_fmp == NULL)
+ return (ENODEV);
- /* Looking for uuid in fd_fbufs_in */
- SIMPLEQ_FOREACH(fbuf, &fd->fd_fbufs_in, fb_next) {
- if (fbuf->fb_uuid == ioexch->fbxch_uuid)
- break;
+ /* Loop to avoid a race condition with multithreaded daemons. */
+ fbuf = SIMPLEQ_FIRST(&fd->fd_fbufs_in);
+ while (fbuf == NULL) {
+ if (ioflag & O_NONBLOCK)
+ return (EAGAIN);
- lastfbuf = fbuf;
- }
- if (fbuf == NULL) {
- printf("fuse: Cannot find fusebuf\n");
- return (EINVAL);
- }
+ error = tsleep_nsec(&fd->fd_fbufs_in, PWAIT | PCATCH,
+ "fbread", INFSLP);
- /* Remove the fbuf from fd_fbufs_in */
- if (fbuf == SIMPLEQ_FIRST(&fd->fd_fbufs_in))
- SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_in, fb_next);
- else
- SIMPLEQ_REMOVE_AFTER(&fd->fd_fbufs_in, lastfbuf,
- fb_next);
- stat_fbufs_in--;
+ if (fd->fd_fmp == NULL)
+ return (ENODEV);
- /* Do not handle fbufs with bad len */
- if (fbuf->fb_len != ioexch->fbxch_len) {
- printf("fuse: Bad fusebuf len\n");
- return (EINVAL);
- }
+ if (error == EINTR || error == ERESTART)
+ return (EINTR);
- /* Update the userland fbuf */
- error = copyout(fbuf->fb_dat, ioexch->fbxch_data,
- ioexch->fbxch_len);
- if (error) {
- printf("fuse: cannot copyout\n");
- return (error);
- }
-
-#ifdef FUSE_DEBUG
- fuse_dump_buff(fbuf->fb_dat, fbuf->fb_len);
-#endif
-
- /* Adding fbuf in fd_fbufs_wait */
- free(fbuf->fb_dat, M_FUSEFS, fbuf->fb_len);
- fbuf->fb_dat = NULL;
- SIMPLEQ_INSERT_TAIL(&fd->fd_fbufs_wait, fbuf, fb_next);
- stat_fbufs_wait++;
- break;
-
- case FIOCSETFBDAT:
- DPRINTF("SET BUFFER\n");
- ioexch = (struct fb_ioctl_xch *)addr;
-
- /* looking for uuid in fd_fbufs_wait */
- SIMPLEQ_FOREACH(fbuf, &fd->fd_fbufs_wait, fb_next) {
- if (fbuf->fb_uuid == ioexch->fbxch_uuid)
- break;
-
- lastfbuf = fbuf;
- }
- if (fbuf == NULL) {
- printf("fuse: Cannot find fusebuf\n");
- return (EINVAL);
- }
-
- /* Do not handle fbufs with bad len */
- if (fbuf->fb_len != ioexch->fbxch_len) {
- printf("fuse: Bad fusebuf size\n");
- return (EINVAL);
- }
-
- /* fetching data from userland */
- fbuf->fb_dat = malloc(ioexch->fbxch_len, M_FUSEFS,
- M_WAITOK | M_ZERO);
- error = copyin(ioexch->fbxch_data, fbuf->fb_dat,
- ioexch->fbxch_len);
- if (error) {
- printf("fuse: Cannot copyin\n");
- free(fbuf->fb_dat, M_FUSEFS, fbuf->fb_len);
- fbuf->fb_dat = NULL;
- return (error);
- }
-
-#ifdef FUSE_DEBUG
- fuse_dump_buff(fbuf->fb_dat, fbuf->fb_len);
-#endif
-
- /* Remove fbuf from fd_fbufs_wait */
- if (fbuf == SIMPLEQ_FIRST(&fd->fd_fbufs_wait))
- SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_wait, fb_next);
- else
- SIMPLEQ_REMOVE_AFTER(&fd->fd_fbufs_wait, lastfbuf,
- fb_next);
- stat_fbufs_wait--;
- wakeup(fbuf);
- break;
- default:
- error = EINVAL;
+ fbuf = SIMPLEQ_FIRST(&fd->fd_fbufs_in);
}
- return (error);
-}
-
-int
-fuseread(dev_t dev, struct uio *uio, int ioflag)
-{
- struct fuse_d *fd;
- struct fusebuf *fbuf;
- struct fb_hdr hdr;
- void *tmpaddr;
- int error = 0;
-
- fd = fuse_lookup(minor(dev));
- if (fd == NULL)
- return (ENXIO);
-
- if (SIMPLEQ_EMPTY(&fd->fd_fbufs_in)) {
- if (ioflag & O_NONBLOCK)
- return (EAGAIN);
-
- goto end;
+ /* The whole fusebuf must be read at once */
+ if (uio->uio_resid < FUSEBUF_INSIZE(fbuf)) {
+ printf("fuse: invalid read: %zu opcode=%d fb_len=%llu\n",
+ uio->uio_resid, fbuf->fb_type, fbuf->fb_len);
+ return (EINVAL);
}
- fbuf = SIMPLEQ_FIRST(&fd->fd_fbufs_in);
- /* We get the whole fusebuf or nothing */
- if (uio->uio_resid != FUSEBUFSIZE)
- return (EINVAL);
-
- /* Do not send kernel pointers */
- memcpy(&hdr.fh_next, &fbuf->fb_next, sizeof(fbuf->fb_next));
- memset(&fbuf->fb_next, 0, sizeof(fbuf->fb_next));
- tmpaddr = fbuf->fb_dat;
- fbuf->fb_dat = NULL;
- error = uiomove(fbuf, FUSEBUFSIZE, uio);
+ error = uiomove(&fbuf->hdr, sizeof(fbuf->hdr), uio);
if (error)
goto end;
+ error = uiomove(&fbuf->op, fbuf->op_in_len, uio);
+ if (error)
+ goto end;
+ error = uiomove(fbuf->fb_dat, fbuf->fb_len, uio);
+ if (error)
+ goto end;
-#ifdef FUSE_DEBUG
- fuse_dump_buff((char *)fbuf, FUSEBUFSIZE);
-#endif
- /* Restore kernel pointers */
- memcpy(&fbuf->fb_next, &hdr.fh_next, sizeof(fbuf->fb_next));
- fbuf->fb_dat = tmpaddr;
-
- /* Remove the fbuf if it does not contains data */
- if (fbuf->fb_len == 0) {
- SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_in, fb_next);
- stat_fbufs_in--;
- SIMPLEQ_INSERT_TAIL(&fd->fd_fbufs_wait, fbuf, fb_next);
- stat_fbufs_wait++;
+ SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_in, fb_next);
+ stat_fbufs_in--;
+ if (fbuf->fb_type == FUSE_FORGET) {
+ /* FUSE_FORGET has no response */
+ fb_delete(fbuf);
+ goto end;
}
+ SIMPLEQ_INSERT_TAIL(&fd->fd_fbufs_wait, fbuf, fb_next);
+ stat_fbufs_wait++;
end:
return (error);
@@ -436,147 +274,163 @@ fusewrite(dev_t dev, struct uio *uio, int ioflag)
struct fusebuf *lastfbuf;
struct fuse_d *fd;
struct fusebuf *fbuf;
- struct fb_hdr hdr;
+ struct fuse_out_header hdr;
int error = 0;
fd = fuse_lookup(minor(dev));
if (fd == NULL)
return (ENXIO);
- /* We get the whole fusebuf or nothing */
- if (uio->uio_resid != FUSEBUFSIZE)
+ if (uio->uio_resid < sizeof(hdr)) {
+ printf("fuse: invalid fusebuf write\n");
return (EINVAL);
+ }
+ /* Read the header */
if ((error = uiomove(&hdr, sizeof(hdr), uio)) != 0)
return (error);
- /* looking for uuid in fd_fbufs_wait */
+ /* Validate the userland provided fbuf size */
+ if (hdr.len < sizeof(hdr)) {
+ printf("fuse: invalid fusebuf header length\n");
+ return (EINVAL);
+ }
+
+ /*
+ * A unique value of zero means daemon is notifying us and hdr.error
+ * contains notification type. Currently unsupported.
+ */
+ if (hdr.unique == 0) {
+ printf("fuse: Ignoring FUSE_NOTIFY_");
+ switch (hdr.error) {
+ case FUSE_NOTIFY_POLL:
+ printf("POLL\n");
+ return (0);
+ case FUSE_NOTIFY_INVAL_INODE:
+ printf("INODE\n");
+ return (0);
+ case FUSE_NOTIFY_INVAL_ENTRY:
+ printf("ENTRY\n");
+ return (0);
+ case FUSE_NOTIFY_STORE:
+ printf("STORE\n");
+ return (0);
+ case FUSE_NOTIFY_RETRIEVE:
+ printf("RETRIEVE\n");
+ return (0);
+ case FUSE_NOTIFY_DELETE:
+ printf("DELETE\n");
+ return (0);
+ default:
+ printf("?: %d\n", hdr.error);
+ return (EINVAL);
+ }
+ }
+
+ /* Find matching fbuf in wait list */
SIMPLEQ_FOREACH(fbuf, &fd->fd_fbufs_wait, fb_next) {
- if (fbuf->fb_uuid == hdr.fh_uuid)
+ if (fbuf->fb_uuid == hdr.unique)
break;
lastfbuf = fbuf;
}
- if (fbuf == NULL)
+ if (fbuf == NULL) {
+ printf("fuse: cannot find fusebuf in wait list\n");
return (EINVAL);
+ }
- /* Update fb_hdr */
- fbuf->fb_len = hdr.fh_len;
- fbuf->fb_err = hdr.fh_err;
- fbuf->fb_ino = hdr.fh_ino;
+ fbuf->fb_err = hdr.error;
- /* Check for corrupted fbufs */
- if ((fbuf->fb_len && fbuf->fb_err) ||
- SIMPLEQ_EMPTY(&fd->fd_fbufs_wait)) {
- printf("fuse: dropping corrupted fusebuf\n");
- error = EINVAL;
+ /* Don't expect output or data if there was an error */
+ if (fbuf->fb_err) {
+ if (uio->uio_resid > 0) {
+ printf("fuse: invalid fusebuf\n");
+ return (EINVAL);
+ }
goto end;
}
- /* Get the missing datas from the fbuf */
- error = uiomove(&fbuf->FD, uio->uio_resid, uio);
- if (error)
- return error;
- fbuf->fb_dat = NULL;
-#ifdef FUSE_DEBUG
- fuse_dump_buff((char *)fbuf, FUSEBUFSIZE);
-#endif
+ /* Calculate the length of the data buffer to expect */
+ if (fbuf->op_out_buf) {
+ fbuf->fb_len = hdr.len - sizeof(hdr) - fbuf->op_out_len;
+ if (fbuf->fb_len > fd->fd_fmp->max_read || fbuf->fb_len < 0) {
+ printf("fuse: invalid fusebuf read size: %llu "
+ "opcode=%d\n", fbuf->fb_len, fbuf->fb_type);
+ return (EINVAL);
+ }
+ } else
+ fbuf->fb_len = 0;
- switch (fbuf->fb_type) {
- case FBT_INIT:
- fd->fd_fmp->sess_init = 1;
- break ;
- case FBT_DESTROY:
- fd->fd_fmp = NULL;
- break ;
+ /* We get the whole fusebuf or nothing */
+ if (FUSEBUF_OUTSIZE(fbuf) != uio->uio_resid + sizeof(hdr)) {
+ printf("fuse: invalid fusebuf size\n");
+ return (EINVAL);
}
-end:
- /* Remove the fbuf if it does not contains data */
- if (fbuf->fb_len == 0) {
- if (fbuf == SIMPLEQ_FIRST(&fd->fd_fbufs_wait))
- SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_wait, fb_next);
- else
- SIMPLEQ_REMOVE_AFTER(&fd->fd_fbufs_wait, lastfbuf,
- fb_next);
- stat_fbufs_wait--;
- if (fbuf->fb_type == FBT_INIT)
- fb_delete(fbuf);
- else
- wakeup(fbuf);
- }
- return (error);
-}
+ if ((error = uiomove(&fbuf->op, fbuf->op_out_len, uio)) != 0)
+ return (error);
-int
-fusepoll(dev_t dev, int events, struct proc *p)
-{
- struct fuse_d *fd;
- int revents = 0;
+ if (fbuf->fb_len > 0) {
+ fbuf->fb_dat = malloc(fbuf->fb_len, M_FUSEFS,
+ M_WAITOK | M_ZERO);
+ if ((error = uiomove(fbuf->fb_dat, fbuf->fb_len, uio)) != 0) {
+ free(fbuf->fb_dat, M_FUSEFS, fbuf->fb_len);
+ return (error);
+ }
+ }
- fd = fuse_lookup(minor(dev));
- if (fd == NULL)
- return (POLLERR);
+ if (fbuf->fb_type == FUSE_INIT) {
+ /*
+ * We don't support userspace with a smaller major version and
+ * it's up to userspace implementations to fall back to our
+ * version if they are capable of a later version.
+ */
+ if (fbuf->op.out.init.major != FUSE_KERNEL_VERSION) {
+ printf("fuse: unsupported major version: %d.%d\n",
+ fbuf->op.out.init.major, fbuf->op.out.init.minor);
+ return (EINVAL);
+ }
- if (events & (POLLIN | POLLRDNORM))
- if (!SIMPLEQ_EMPTY(&fd->fd_fbufs_in))
- revents |= events & (POLLIN | POLLRDNORM);
+ /*
+ * If the major versions match then both shall use the smallest
+ * of the two minor versions for communication. 7.9 is the
+ * smallest version less than what we support where the ABI has
+ * not changed. Supporting an earlier version would require
+ * conditional handling of some FUSE input arguments. If the
+ * daemon supports a later version then it must fall back to
+ * ours.
+ */
+ if (fbuf->op.out.init.minor < 9) {
+ printf("fuse: unsupported minor version: %d.%d\n",
+ fbuf->op.out.init.major, fbuf->op.out.init.minor);
+ return (EINVAL);
+ }
- if (events & (POLLOUT | POLLWRNORM))
- revents |= events & (POLLOUT | POLLWRNORM);
+ /*
+ * max_write determines the size of buffer to send to the file
+ * system daemon when writing so ensure that it's sane.
+ */
+ fd->fd_fmp->max_write = MIN(fbuf->op.out.init.max_write,
+ FUSEBUFMAXSIZE);
+ if (fd->fd_fmp->max_write == 0)
+ fd->fd_fmp->max_write = FUSEBUFMAXSIZE;
- if (revents == 0)
- if (events & (POLLIN | POLLRDNORM))
- selrecord(p, &fd->fd_rsel);
-
- return (revents);
-}
-
-int
-fusekqfilter(dev_t dev, struct knote *kn)
-{
- struct fuse_d *fd;
- struct klist *klist;
-
- fd = fuse_lookup(minor(dev));
- if (fd == NULL)
- return (EINVAL);
-
- switch (kn->kn_filter) {
- case EVFILT_READ:
- klist = &fd->fd_rsel.si_note;
- kn->kn_fop = &fuse_rd_filtops;
- break;
- case EVFILT_WRITE:
- return (seltrue_kqfilter(dev, kn));
- default:
- return (EINVAL);
+ fd->fd_fmp->sess_init = 1;
}
- kn->kn_hook = fd;
+end:
+ /* Remove the fbuf now that it's been successfully received */
+ if (fbuf == SIMPLEQ_FIRST(&fd->fd_fbufs_wait))
+ SIMPLEQ_REMOVE_HEAD(&fd->fd_fbufs_wait, fb_next);
+ else
+ SIMPLEQ_REMOVE_AFTER(&fd->fd_fbufs_wait, lastfbuf, fb_next);
+ stat_fbufs_wait--;
- klist_insert_locked(klist, kn);
+ /* The kernel doesn't wait for a response to FUSE_INIT */
+ if (fbuf->fb_type == FUSE_INIT)
+ fb_delete(fbuf);
+ else
+ wakeup(fbuf);
- return (0);
-}
-
-void
-filt_fuse_rdetach(struct knote *kn)
-{
- struct fuse_d *fd = kn->kn_hook;
- struct klist *klist = &fd->fd_rsel.si_note;
-
- klist_remove_locked(klist, kn);
-}
-
-int
-filt_fuse_read(struct knote *kn, long hint)
-{
- struct fuse_d *fd = kn->kn_hook;
- int event = 0;
-
- if (!SIMPLEQ_EMPTY(&fd->fd_fbufs_in))
- event = 1;
-
- return (event);
+ return (error);
}
blob - b944b7563159cbd023f171be03b57680b973d442
blob + 906a7b84d0b4a75d465fb0fc75647da94fd16498
--- sys/miscfs/fuse/fuse_file.c
+++ sys/miscfs/fuse/fuse_file.c
@@ -20,8 +20,9 @@
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/vnode.h>
-#include <sys/fusebuf.h>
+#include <sys/fuse_kernel.h>
+#include "fusebuf.h"
#include "fusefs_node.h"
#include "fusefs.h"
@@ -36,8 +37,8 @@ fusefs_file_open(struct fusefs_mnt *fmp, struct fusefs
return (0);
fbuf = fb_setup(0, ip->ufs_ino.i_number,
- ((isdir) ? FBT_OPENDIR : FBT_OPEN), p);
- fbuf->fb_io_flags = flags;
+ ((isdir) ? FUSE_OPENDIR : FUSE_OPEN), p);
+ fbuf->op.in.open.flags = flags;
error = fb_queue(fmp->dev, fbuf);
if (error) {
@@ -45,7 +46,7 @@ fusefs_file_open(struct fusefs_mnt *fmp, struct fusefs
return (error);
}
- ip->fufh[fufh_type].fh_id = fbuf->fb_io_fd;
+ ip->fufh[fufh_type].fh_id = fbuf->op.out.open.fh;
ip->fufh[fufh_type].fh_type = fufh_type;
fb_delete(fbuf);
@@ -61,13 +62,13 @@ fusefs_file_close(struct fusefs_mnt *fmp, struct fusef
if (fmp->sess_init) {
fbuf = fb_setup(0, ip->ufs_ino.i_number,
- ((isdir) ? FBT_RELEASEDIR : FBT_RELEASE), p);
- fbuf->fb_io_fd = ip->fufh[fufh_type].fh_id;
- fbuf->fb_io_flags = flags;
+ ((isdir) ? FUSE_RELEASEDIR : FUSE_RELEASE), p);
+ fbuf->op.in.release.fh = ip->fufh[fufh_type].fh_id;
+ fbuf->op.in.release.flags = flags;
error = fb_queue(fmp->dev, fbuf);
if (error && (error != ENOSYS))
- printf("fusefs: file error %d\n", error);
+ printf("fusefs: file close error %d\n", error);
fb_delete(fbuf);
}
blob - 7e19d2449eec4068a386d5fd568fd13b7e0c4077
blob + 670dce2977271ba20c6c566247773413a5676916
--- sys/miscfs/fuse/fuse_lookup.c
+++ sys/miscfs/fuse/fuse_lookup.c
@@ -23,8 +23,8 @@
#include <sys/statvfs.h>
#include <sys/vnode.h>
#include <sys/lock.h>
-#include <sys/fusebuf.h>
+#include "fusebuf.h"
#include "fusefs_node.h"
#include "fusefs.h"
@@ -74,7 +74,7 @@ fusefs_lookup(void *v)
/* got a real entry */
fbuf = fb_setup(cnp->cn_namelen + 1, dp->ufs_ino.i_number,
- FBT_LOOKUP, p);
+ FUSE_LOOKUP, p);
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
@@ -111,11 +111,18 @@ fusefs_lookup(void *v)
return (ENOENT);
}
- nid = fbuf->fb_ino;
- nvtype = IFTOVT(fbuf->fb_attr.st_mode);
+ nid = fbuf->op.out.entry.nodeid;
+ nvtype = IFTOVT(fbuf->op.out.entry.attr.mode);
fb_delete(fbuf);
}
+ if (nid == 0) {
+ /* zero nodeid means ENOENT */
+ printf("fusefs_lookup: file system returned nodeid=0 instead of "
+ "ENOENT\n");
+ return (ENOENT);
+ }
+
if (nameiop == DELETE && (flags & ISLASTCN)) {
/*
* Write access to directory required to delete files.
@@ -194,11 +201,10 @@ fusefs_lookup(void *v)
return (error);
reclaim:
- if (nid != dp->ufs_ino.i_number && nid != FUSE_ROOTINO) {
- fbuf = fb_setup(0, nid, FBT_RECLAIM, p);
- if (fb_queue(fmp->dev, fbuf))
- printf("fusefs: libfuse vnode reclaim failed\n");
- fb_delete(fbuf);
+ if (nid != dp->ufs_ino.i_number && nid != FUSE_ROOT_ID) {
+ fbuf = fb_setup(0, nid, FUSE_FORGET, p);
+ fbuf->op.in.forget.nlookup = 1;
+ fuse_device_queue_fbuf(fmp->dev, fbuf); /* no response */
}
return (error);
}
blob - 3e2af8960af4c69e8fa14dd37462a39858ef34a2
blob + cc8a8983e74d1742a88d287ad7e04b51783fc74f
--- sys/miscfs/fuse/fuse_vfsops.c
+++ sys/miscfs/fuse/fuse_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_vfsops.c,v 1.44 2020/11/17 03:23:10 gnezdo Exp $ */
+/* $OpenBSD: fuse_vfsops.c,v 1.43 2019/12/26 13:28:49 bluhm Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -28,8 +28,8 @@
#include <sys/statvfs.h>
#include <sys/sysctl.h>
#include <sys/vnode.h>
-#include <sys/fusebuf.h>
+#include "fusebuf.h"
#include "fusefs_node.h"
#include "fusefs.h"
@@ -47,8 +47,7 @@ int fusefs_vptofh(struct vnode *, struct fid *);
int fusefs_init(struct vfsconf *);
int fusefs_sysctl(int *, u_int, void *, size_t *, void *, size_t,
struct proc *);
-int fusefs_checkexp(struct mount *, struct mbuf *, int *,
- struct ucred **);
+int fusefs_checkexp(struct mount *, struct mbuf *, int *, struct ucred **);
const struct vfsops fusefs_vfsops = {
.vfs_mount = fusefs_mount,
@@ -68,7 +67,7 @@ const struct vfsops fusefs_vfsops = {
struct pool fusefs_fbuf_pool;
-#define PENDING 2 /* FBT_INIT reply not yet received */
+#define PENDING 2 /* FUSE_INIT reply not yet received */
int
fusefs_mount(struct mount *mp, const char *path, void *data,
@@ -110,7 +109,6 @@ fusefs_mount(struct mount *mp, const char *path, void
fmp->max_read = MIN(args->max_read, FUSEBUFMAXSIZE);
else
fmp->max_read = FUSEBUFMAXSIZE;
-
fmp->allow_other = args->allow_other;
mp->mnt_data = fmp;
@@ -125,7 +123,11 @@ fusefs_mount(struct mount *mp, const char *path, void
strlcpy(mp->mnt_stat.f_mntfromspec, "fusefs", MNAMELEN);
fuse_device_set_fmp(fmp, 1);
- fbuf = fb_setup(0, 0, FBT_INIT, p);
+ fbuf = fb_setup(0, 0, FUSE_INIT, p);
+ fbuf->op.in.init.major = FUSE_KERNEL_VERSION;
+ fbuf->op.in.init.minor = FUSE_KERNEL_MINOR_VERSION;
+ fbuf->op.in.init.max_readahead = 0;
+ fbuf->op.in.init.flags = 0; /* OpenBSD supports nothing... */
/* cannot tsleep on mount */
fuse_device_queue_fbuf(fmp->dev, fbuf);
@@ -158,8 +160,7 @@ fusefs_unmount(struct mount *mp, int mntflags, struct
return (error);
if (fmp->sess_init && fmp->sess_init != PENDING) {
- fbuf = fb_setup(0, 0, FBT_DESTROY, p);
-
+ fbuf = fb_setup(0, 0, FUSE_DESTROY, p);
error = fb_queue(fmp->dev, fbuf);
if (error)
@@ -183,7 +184,7 @@ fusefs_root(struct mount *mp, struct vnode **vpp)
struct vnode *nvp;
int error;
- if ((error = VFS_VGET(mp, FUSE_ROOTINO, &nvp)) != 0)
+ if ((error = VFS_VGET(mp, FUSE_ROOT_ID, &nvp)) != 0)
return (error);
nvp->v_type = VDIR;
@@ -215,10 +216,10 @@ fusefs_statfs(struct mount *mp, struct statfs *sbp, st
copy_statfs_info(sbp, mp);
/*
- * Both FBT_INIT and FBT_STATFS are sent to the FUSE file system
+ * Both FUSE_INIT and FUSE_STATFS are sent to the FUSE file system
* daemon when it is mounted. However, the daemon is the process
* that called mount(2) so to prevent a deadlock return dummy
- * values until the response to FBT_INIT init is received. All
+ * values until the response to FUSE_INIT init is received. All
* other VFS syscalls are queued.
*/
if (!fmp->sess_init || fmp->sess_init == PENDING) {
@@ -232,7 +233,7 @@ fusefs_statfs(struct mount *mp, struct statfs *sbp, st
sbp->f_iosize = 0;
sbp->f_namemax = 0;
} else {
- fbuf = fb_setup(0, FUSE_ROOTINO, FBT_STATFS, p);
+ fbuf = fb_setup(0, FUSE_ROOT_ID, FUSE_STATFS, p);
error = fb_queue(fmp->dev, fbuf);
@@ -241,15 +242,15 @@ fusefs_statfs(struct mount *mp, struct statfs *sbp, st
return (error);
}
- sbp->f_bavail = fbuf->fb_stat.f_bavail;
- sbp->f_bfree = fbuf->fb_stat.f_bfree;
- sbp->f_blocks = fbuf->fb_stat.f_blocks;
- sbp->f_files = fbuf->fb_stat.f_files;
- sbp->f_ffree = fbuf->fb_stat.f_ffree;
- sbp->f_favail = fbuf->fb_stat.f_favail;
- sbp->f_bsize = fbuf->fb_stat.f_frsize;
- sbp->f_iosize = fbuf->fb_stat.f_bsize;
- sbp->f_namemax = fbuf->fb_stat.f_namemax;
+ sbp->f_bavail = fbuf->op.out.statfs.st.bavail;
+ sbp->f_bfree = fbuf->op.out.statfs.st.bfree;
+ sbp->f_blocks = fbuf->op.out.statfs.st.blocks;
+ sbp->f_files = fbuf->op.out.statfs.st.files;
+ sbp->f_ffree = fbuf->op.out.statfs.st.ffree;
+ sbp->f_favail = fbuf->op.out.statfs.st.ffree;
+ sbp->f_bsize = fbuf->op.out.statfs.st.frsize;
+ sbp->f_iosize = fbuf->op.out.statfs.st.bsize;
+ sbp->f_namemax = fbuf->op.out.statfs.st.namelen;
fb_delete(fbuf);
}
@@ -277,8 +278,10 @@ retry:
/*
* check if vnode is in hash.
*/
- if ((*vpp = ufs_ihashget(fmp->dev, ino)) != NULLVP)
+ if ((*vpp = ufs_ihashget(fmp->dev, ino)) != NULLVP) {
+ VTOI(*vpp)->nlookup++;
return (0);
+ }
/*
* if not create it
@@ -296,6 +299,7 @@ retry:
ip->ufs_ino.i_vnode = nvp;
ip->ufs_ino.i_dev = fmp->dev;
ip->ufs_ino.i_number = ino;
+ ip->nlookup = 1;
for (i = 0; i < FUFH_MAXTYPE; i++)
ip->fufh[i].fh_type = FUFH_INVALID;
@@ -312,7 +316,7 @@ retry:
ip->ufs_ino.i_ump = (struct ufsmount *)fmp;
- if (ino == FUSE_ROOTINO)
+ if (ino == FUSE_ROOT_ID)
nvp->v_flag |= VROOT;
else {
/*
@@ -353,21 +357,30 @@ fusefs_init(struct vfsconf *vfc)
return (0);
}
-extern int stat_fbufs_in, stat_fbufs_wait, stat_opened_fusedev;
-
-const struct sysctl_bounded_args fusefs_vars[] = {
- { FUSEFS_OPENDEVS, &stat_opened_fusedev, 1, 0 },
- { FUSEFS_INFBUFS, &stat_fbufs_in, 1, 0 },
- { FUSEFS_WAITFBUFS, &stat_fbufs_wait, 1, 0 },
- { FUSEFS_POOL_NBPAGES, &fusefs_fbuf_pool.pr_npages, 1, 0 },
-};
-
int
fusefs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen, struct proc *p)
{
- return sysctl_bounded_arr(fusefs_vars, nitems(fusefs_vars), name,
- namelen, oldp, oldlenp, newp, newlen);
+ extern int stat_fbufs_in, stat_fbufs_wait, stat_opened_fusedev;
+
+ /* all sysctl names at this level are terminal */
+ if (namelen != 1)
+ return (ENOTDIR); /* overloaded */
+
+ switch (name[0]) {
+ case FUSEFS_OPENDEVS:
+ return (sysctl_rdint(oldp, oldlenp, newp,
+ stat_opened_fusedev));
+ case FUSEFS_INFBUFS:
+ return (sysctl_rdint(oldp, oldlenp, newp, stat_fbufs_in));
+ case FUSEFS_WAITFBUFS:
+ return (sysctl_rdint(oldp, oldlenp, newp, stat_fbufs_wait));
+ case FUSEFS_POOL_NBPAGES:
+ return (sysctl_rdint(oldp, oldlenp, newp,
+ fusefs_fbuf_pool.pr_npages));
+ default:
+ return (EOPNOTSUPP);
+ }
}
int
blob - 27fd296abf0582c8fab2e27b197f580390e914b8
blob + 9cbca2f3d7c7b1e2db58de82e012f9365692dffb
--- sys/miscfs/fuse/fuse_vnops.c
+++ sys/miscfs/fuse/fuse_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_vnops.c,v 1.62 2020/12/25 12:59:52 visa Exp $ */
+/* $OpenBSD: fuse_vnops.c,v 1.61 2020/06/11 09:18:43 mpi Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -20,6 +20,7 @@
#include <sys/dirent.h>
#include <sys/fcntl.h>
#include <sys/file.h>
+#include <sys/filedesc.h>
#include <sys/lockf.h>
#include <sys/malloc.h>
#include <sys/mount.h>
@@ -31,8 +32,9 @@
#include <sys/statvfs.h>
#include <sys/vnode.h>
#include <sys/lock.h>
-#include <sys/fusebuf.h>
+#include <sys/fuse_kernel.h>
+#include "fusebuf.h"
#include "fusefs_node.h"
#include "fusefs.h"
@@ -154,7 +156,7 @@ fusefs_kqfilter(void *v)
kn->kn_hook = (caddr_t)vp;
- klist_insert_locked(&vp->v_selectinfo.si_note, kn);
+ klist_insert(&vp->v_selectinfo.si_note, kn);
return (0);
}
@@ -164,7 +166,7 @@ filt_fusefsdetach(struct knote *kn)
{
struct vnode *vp = (struct vnode *)kn->kn_hook;
- klist_remove_locked(&vp->v_selectinfo.si_note, kn);
+ klist_remove(&vp->v_selectinfo.si_note, kn);
}
int
@@ -272,7 +274,7 @@ fusefs_open(void *v)
uvm_vnp_uncache(vp);
}
- /* already open i think all is ok */
+ /* already open I think all is ok */
if (ip->fufh[fufh_type].fh_type != FUFH_INVALID)
return (0);
@@ -329,8 +331,8 @@ fusefs_close(void *v)
if (ip->fufh[fufh_type].fh_type == FUFH_INVALID)
return (EBADF);
- fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_FLUSH, ap->a_p);
- fbuf->fb_io_fd = ip->fufh[fufh_type].fh_id;
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FUSE_FLUSH, ap->a_p);
+ fbuf->op.in.flush.fh = ip->fufh[fufh_type].fh_id;
error = fb_queue(fmp->dev, fbuf);
fb_delete(fbuf);
if (error == ENOSYS) {
@@ -405,7 +407,7 @@ fusefs_getattr(void *v)
struct ucred *cred = p->p_ucred;
struct fusefs_node *ip;
struct fusebuf *fbuf;
- struct stat *st;
+ struct fuse_attr *st;
int error = 0;
ip = VTOI(vp);
@@ -429,7 +431,7 @@ fusefs_getattr(void *v)
vap->va_fsid = fmp->mp->mnt_stat.f_fsid.val[0];
vap->va_fileid = ip->ufs_ino.i_number;
vap->va_size = S_BLKSIZE;
- vap->va_blocksize = S_BLKSIZE;
+ vap->va_blocksize = PAGE_SIZE;
vap->va_atime.tv_sec = fmp->mp->mnt_stat.f_ctime;
vap->va_mtime.tv_sec = fmp->mp->mnt_stat.f_ctime;
vap->va_ctime.tv_sec = fmp->mp->mnt_stat.f_ctime;
@@ -441,7 +443,7 @@ fusefs_getattr(void *v)
if (!fmp->sess_init)
return (ENXIO);
- fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_GETATTR, p);
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FUSE_GETATTR, p);
error = fb_queue(fmp->dev, fbuf);
if (error) {
@@ -449,23 +451,27 @@ fusefs_getattr(void *v)
return (error);
}
- st = &fbuf->fb_attr;
+ st = &fbuf->op.out.attr.attr;
memset(vap, 0, sizeof(*vap));
- vap->va_type = IFTOVT(st->st_mode);
- vap->va_mode = st->st_mode & ~S_IFMT;
- vap->va_nlink = st->st_nlink;
- vap->va_uid = st->st_uid;
- vap->va_gid = st->st_gid;
+ vap->va_type = IFTOVT(st->mode);
+ vap->va_mode = st->mode & ~S_IFMT;
+ vap->va_nlink = st->nlink;
+ vap->va_uid = st->uid;
+ vap->va_gid = st->gid;
vap->va_fsid = fmp->mp->mnt_stat.f_fsid.val[0];
- vap->va_fileid = st->st_ino;
- vap->va_size = st->st_size;
- vap->va_blocksize = st->st_blksize;
- vap->va_atime = st->st_atim;
- vap->va_mtime = st->st_mtim;
- vap->va_ctime = st->st_ctim;
- vap->va_rdev = st->st_rdev;
- vap->va_bytes = st->st_blocks * S_BLKSIZE;
+ vap->va_fileid = st->ino;
+ vap->va_size = st->size;
+ // XXX check for sanity or rely on VFS?
+ vap->va_blocksize = st->blksize > 0 ? st->blksize : PAGE_SIZE;
+ vap->va_atime.tv_sec = st->atime;
+ vap->va_atime.tv_nsec = st->atimensec;
+ vap->va_mtime.tv_sec = st->mtime;
+ vap->va_mtime.tv_nsec = st->mtimensec;
+ vap->va_ctime.tv_sec = st->ctime;
+ vap->va_ctime.tv_nsec = st->ctimensec;
+ vap->va_rdev = st->rdev;
+ vap->va_bytes = st->blocks * S_BLKSIZE;
fb_delete(fbuf);
return (error);
@@ -482,7 +488,6 @@ fusefs_setattr(void *v)
struct proc *p = ap->a_p;
struct fusefs_mnt *fmp;
struct fusebuf *fbuf;
- struct fb_io *io;
int error = 0;
fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;
@@ -501,17 +506,16 @@ fusefs_setattr(void *v)
if (fmp->undef_op & UNDEF_SETATTR)
return (ENOSYS);
- fbuf = fb_setup(sizeof(*io), ip->ufs_ino.i_number, FBT_SETATTR, p);
- io = fbtod(fbuf, struct fb_io *);
- io->fi_flags = 0;
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FUSE_SETATTR, p);
+ fbuf->op.in.setattr.valid = 0;
if (vap->va_uid != (uid_t)VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY) {
error = EROFS;
goto out;
}
- fbuf->fb_attr.st_uid = vap->va_uid;
- io->fi_flags |= FUSE_FATTR_UID;
+ fbuf->op.in.setattr.uid |= vap->va_uid;
+ fbuf->op.in.setattr.valid |= FATTR_UID;
}
if (vap->va_gid != (gid_t)VNOVAL) {
@@ -519,8 +523,8 @@ fusefs_setattr(void *v)
error = EROFS;
goto out;
}
- fbuf->fb_attr.st_gid = vap->va_gid;
- io->fi_flags |= FUSE_FATTR_GID;
+ fbuf->op.in.setattr.gid |= vap->va_gid;
+ fbuf->op.in.setattr.valid |= FATTR_GID;
}
if (vap->va_size != VNOVAL) {
@@ -544,8 +548,8 @@ fusefs_setattr(void *v)
break;
}
- fbuf->fb_attr.st_size = vap->va_size;
- io->fi_flags |= FUSE_FATTR_SIZE;
+ fbuf->op.in.setattr.size |= vap->va_size;
+ fbuf->op.in.setattr.valid |= FATTR_SIZE;
}
if (vap->va_atime.tv_nsec != VNOVAL) {
@@ -553,8 +557,9 @@ fusefs_setattr(void *v)
error = EROFS;
goto out;
}
- fbuf->fb_attr.st_atim = vap->va_atime;
- io->fi_flags |= FUSE_FATTR_ATIME;
+ fbuf->op.in.setattr.atime = vap->va_atime.tv_sec;
+ fbuf->op.in.setattr.atimensec = vap->va_atime.tv_nsec;
+ fbuf->op.in.setattr.valid |= FATTR_ATIME;
}
if (vap->va_mtime.tv_nsec != VNOVAL) {
@@ -562,8 +567,9 @@ fusefs_setattr(void *v)
error = EROFS;
goto out;
}
- fbuf->fb_attr.st_mtim = vap->va_mtime;
- io->fi_flags |= FUSE_FATTR_MTIME;
+ fbuf->op.in.setattr.mtime = vap->va_mtime.tv_sec;
+ fbuf->op.in.setattr.mtimensec = vap->va_mtime.tv_nsec;
+ fbuf->op.in.setattr.valid |= FATTR_MTIME;
}
/* XXX should set a flag if (vap->va_vaflags & VA_UTIMES_CHANGE) */
@@ -583,12 +589,11 @@ fusefs_setattr(void *v)
error = EFTYPE;
goto out;
}
-
- fbuf->fb_attr.st_mode = vap->va_mode & ALLPERMS;
- io->fi_flags |= FUSE_FATTR_MODE;
+ fbuf->op.in.setattr.mode = vap->va_mode & ALLPERMS;
+ fbuf->op.in.setattr.valid |= FATTR_MODE;
}
- if (!io->fi_flags) {
+ if (!fbuf->op.in.setattr.valid) {
goto out;
}
@@ -662,9 +667,9 @@ fusefs_link(void *v)
}
fbuf = fb_setup(cnp->cn_namelen + 1, dip->ufs_ino.i_number,
- FBT_LINK, p);
+ FUSE_LINK, p);
- fbuf->fb_io_ino = ip->ufs_ino.i_number;
+ fbuf->op.in.link.oldnodeid = ip->ufs_ino.i_number;
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
@@ -702,7 +707,7 @@ fusefs_symlink(void *v)
struct fusefs_node *dp;
struct fusefs_mnt *fmp;
struct fusebuf *fbuf;
- struct vnode *tdp;
+ struct vnode *tvp;
int error = 0;
int len;
@@ -722,7 +727,7 @@ fusefs_symlink(void *v)
len = strlen(target) + 1;
fbuf = fb_setup(len + cnp->cn_namelen + 1, dp->ufs_ino.i_number,
- FBT_SYMLINK, p);
+ FUSE_SYMLINK, p);
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
@@ -737,17 +742,26 @@ fusefs_symlink(void *v)
goto bad;
}
- if ((error = VFS_VGET(fmp->mp, fbuf->fb_ino, &tdp))) {
+ /* symlink returns a fuse_entry_out with the ino of the new link */
+ if (fbuf->op.out.entry.nodeid == 0 ||
+ fbuf->op.out.entry.nodeid == FUSE_ROOT_ID) {
+ printf("fusefs_symlink: file system returned invalid nodeid\n");
+ error = EINVAL;
fb_delete(fbuf);
goto bad;
}
- tdp->v_type = VLNK;
+ if ((error = VFS_VGET(fmp->mp, fbuf->op.out.entry.nodeid, &tvp))) {
+ fb_delete(fbuf);
+ goto bad;
+ }
+
+ tvp->v_type = VLNK;
VN_KNOTE(ap->a_dvp, NOTE_WRITE);
- *vpp = tdp;
+ *vpp = tvp;
fb_delete(fbuf);
- vput(tdp);
+ vput(tvp);
bad:
vput(dvp);
return (error);
@@ -764,17 +778,25 @@ fusefs_readdir(void *v)
struct proc *p;
struct uio *uio;
int error = 0, eofflag = 0, diropen = 0;
+ struct dirent de;
+ struct fuse_dirent *fde;
+ uint64_t fresid;
+ off_t foffset, freclen;
vp = ap->a_vp;
uio = ap->a_uio;
p = uio->uio_procp;
+ foffset = uio->uio_offset;
ip = VTOI(vp);
fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;
-
if (!fmp->sess_init)
return (ENXIO);
+ /*
+ * Basic check for ensure buffer is large enough for at least one
+ * dirent with maximum allowed name length.
+ */
if (uio->uio_resid < sizeof(struct dirent))
return (EINVAL);
@@ -786,23 +808,16 @@ fusefs_readdir(void *v)
diropen = 1;
}
- while (uio->uio_resid > 0) {
- fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_READDIR, p);
+ while (!error && uio->uio_resid > DIRENT_RECSIZE(1)) {
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FUSE_READDIR, p);
- fbuf->fb_io_fd = ip->fufh[FUFH_RDONLY].fh_id;
- fbuf->fb_io_off = uio->uio_offset;
- fbuf->fb_io_len = MIN(uio->uio_resid, fmp->max_read);
+ fbuf->op.in.read.fh = ip->fufh[FUFH_RDONLY].fh_id;
+ fbuf->op.in.read.offset = foffset;
+ fbuf->op.in.read.size = MIN(uio->uio_resid, fmp->max_read);
error = fb_queue(fmp->dev, fbuf);
if (error) {
- /*
- * dirent was larger than residual space left in
- * buffer.
- */
- if (error == ENOBUFS)
- error = 0;
-
fb_delete(fbuf);
break;
}
@@ -812,16 +827,89 @@ fusefs_readdir(void *v)
eofflag = 1;
fb_delete(fbuf);
break;
- }
-
- if ((error = uiomove(fbuf->fb_dat, fbuf->fb_len, uio))) {
+ } else if (fbuf->fb_len < FUSE_NAME_OFFSET) {
+ printf("fusefs_readdir: fb_len too small: %llu\n",
+ fbuf->fb_len);
+ error = EIO;
fb_delete(fbuf);
break;
}
+ /* convert FUSE dirents to those expected by userland */
+ fresid = fbuf->fb_len;
+ fde = (struct fuse_dirent *)fbuf->fb_dat;
+ while (uio->uio_resid > 0 && fresid >= FUSE_NAME_OFFSET) {
+ /* basic sanity check */
+ if (fde->namelen == 0 || fde->namelen > MAXNAMLEN) {
+ printf("fusefs_readdir: invalid namelen: %d\n",
+ fde->namelen);
+ error = EIO;
+ break;
+ }
+
+ freclen = FUSE_DIRENT_SIZE(fde);
+
+ /*
+ * prevent reading past end of buffer on last dirent if
+ * size is (deliberately) set too large.
+ */
+ if (freclen > fresid) {
+ printf("fusefs_readdir: corrupt FUSE dirent\n");
+ error = EIO;
+ break;
+ }
+
+ /* file names cannot contain a slash */
+ if (memchr(fde->name, '/', fde->namelen) != NULL) {
+ error = EIO;
+ break;
+ }
+
+ de.d_namlen = fde->namelen;
+ de.d_reclen = DIRENT_RECSIZE(de.d_namlen);
+
+ if (uio->uio_resid < de.d_reclen)
+ goto out;
+
+ /*
+ * d_off is used by telldir, seekdir, readdir libc
+ * functions and expect the file system's offset. This
+ * will be passed back to this function so needs to be
+ * the FUSE offset.
+ */
+ de.d_off = fde->off;
+ de.d_fileno = fde->ino;
+ de.d_type = fde->type;
+ memcpy(de.d_name, fde->name, de.d_namlen);
+ memset(de.d_name + de.d_namlen, 0, de.d_reclen
+ - de.d_namlen - offsetof(struct dirent, d_name));
+ if ((error = uiomove(&de, de.d_reclen, uio)))
+ break;
+
+ /* advance to next FUSE dirent but check it's sane */
+ fresid -= freclen;
+ if (fde->off - foffset != freclen) {
+ printf("fusefs_readdir: foffset/size mismatch "
+ "%llu:%lld\n", fde->off - foffset, freclen);
+ error = EIO;
+ break;
+ }
+ foffset = fde->off;
+ fde = (struct fuse_dirent *)((char *)fde + freclen);
+ }
+
fb_delete(fbuf);
+
+ /* avoid unnecessary calls if we know it's EOF */
+ if (!error && fresid == 0 && uio->uio_resid > 0) {
+ eofflag = 1;
+ break;
+ }
}
+out:
+ uio->uio_offset = foffset;
+
if (!error && ap->a_eofflag != NULL)
*ap->a_eofflag = eofflag;
@@ -899,7 +987,7 @@ fusefs_readlink(void *v)
if (fmp->undef_op & UNDEF_READLINK)
return (ENOSYS);
- fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_READLINK, p);
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FUSE_READLINK, p);
error = fb_queue(fmp->dev, fbuf);
@@ -927,7 +1015,7 @@ fusefs_reclaim(void *v)
struct fusefs_filehandle *fufh = NULL;
struct fusefs_mnt *fmp;
struct fusebuf *fbuf;
- int type, error = 0;
+ int type = 0;
fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;
@@ -941,20 +1029,14 @@ fusefs_reclaim(void *v)
}
}
- /*
- * If the fuse connection is opened ask libfuse to free the vnodes.
- */
- if (fmp->sess_init && ip->ufs_ino.i_number != FUSE_ROOTINO) {
- fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_RECLAIM, p);
- error = fb_queue(fmp->dev, fbuf);
- if (error)
- printf("fusefs: vnode reclaim failed: %d\n", error);
- fb_delete(fbuf);
+ /* If the fuse connection is opened ask libfuse to free the vnodes. */
+ if (fmp->sess_init && ip->ufs_ino.i_number != FUSE_ROOT_ID) {
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FUSE_FORGET, p);
+ fbuf->op.in.forget.nlookup = ip->nlookup;
+ fuse_device_queue_fbuf(fmp->dev, fbuf); /* no response */
}
- /*
- * Remove the inode from its hash chain.
- */
+ /* Remove the inode from its hash chain. */
ufs_ihashrem(&ip->ufs_ino);
free(ip, M_FUSEFS, sizeof(*ip));
@@ -986,7 +1068,7 @@ fusefs_create(void *v)
struct vnode *dvp = ap->a_dvp;
struct vattr *vap = ap->a_vap;
struct proc *p = cnp->cn_proc;
- struct vnode *tdp = NULL;
+ struct vnode *tvp = NULL;
struct fusefs_mnt *fmp;
struct fusefs_node *ip;
struct fusebuf *fbuf;
@@ -1004,9 +1086,10 @@ fusefs_create(void *v)
return (ENOSYS);
fbuf = fb_setup(cnp->cn_namelen + 1, ip->ufs_ino.i_number,
- FBT_MKNOD, p);
+ FUSE_MKNOD, p);
- fbuf->fb_io_mode = mode;
+ fbuf->op.in.mknod.mode = mode;
+ fbuf->op.in.mknod.umask = p->p_p->ps_fd->fd_cmask;
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
@@ -1019,12 +1102,20 @@ fusefs_create(void *v)
goto out;
}
- if ((error = VFS_VGET(fmp->mp, fbuf->fb_ino, &tdp)))
+ /* mknod returns a fuse_entry_out with the ino of the new file */
+ if (fbuf->op.out.entry.nodeid == 0 ||
+ fbuf->op.out.entry.nodeid == FUSE_ROOT_ID) {
+ printf("fusefs_create: file system returned invalid nodeid\n");
+ error = EINVAL;
goto out;
+ }
- tdp->v_type = IFTOVT(fbuf->fb_io_mode);
+ if ((error = VFS_VGET(fmp->mp, fbuf->op.out.entry.nodeid, &tvp)))
+ goto out;
- *vpp = tdp;
+ tvp->v_type = IFTOVT(mode);
+
+ *vpp = tvp;
VN_KNOTE(ap->a_dvp, NOTE_WRITE);
out:
fb_delete(fbuf);
@@ -1040,7 +1131,7 @@ fusefs_mknod(void *v)
struct vnode *dvp = ap->a_dvp;
struct vattr *vap = ap->a_vap;
struct proc *p = cnp->cn_proc;
- struct vnode *tdp = NULL;
+ struct vnode *tvp = NULL;
struct fusefs_mnt *fmp;
struct fusefs_node *ip;
struct fusebuf *fbuf;
@@ -1056,11 +1147,12 @@ fusefs_mknod(void *v)
return (ENOSYS);
fbuf = fb_setup(cnp->cn_namelen + 1, ip->ufs_ino.i_number,
- FBT_MKNOD, p);
+ FUSE_MKNOD, p);
- fbuf->fb_io_mode = MAKEIMODE(vap->va_type, vap->va_mode);
+ fbuf->op.in.mknod.mode = MAKEIMODE(vap->va_type, vap->va_mode);
+ fbuf->op.in.mknod.umask = p->p_p->ps_fd->fd_cmask;
if (vap->va_rdev != VNOVAL)
- fbuf->fb_io_rdev = vap->va_rdev;
+ fbuf->op.in.mknod.rdev = vap->va_rdev;
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
@@ -1073,12 +1165,20 @@ fusefs_mknod(void *v)
goto out;
}
- if ((error = VFS_VGET(fmp->mp, fbuf->fb_ino, &tdp)))
+ /* mknod returns a fuse_entry_out with the ino of the new file */
+ if (fbuf->op.out.entry.nodeid == 0 ||
+ fbuf->op.out.entry.nodeid == FUSE_ROOT_ID) {
+ printf("fusefs_mknod: file system returned invalid nodeid\n");
+ error = EINVAL;
goto out;
+ }
- tdp->v_type = IFTOVT(fbuf->fb_io_mode);
+ if ((error = VFS_VGET(fmp->mp, fbuf->op.out.entry.nodeid, &tvp)))
+ goto out;
- *vpp = tdp;
+ tvp->v_type = IFTOVT(fbuf->op.in.mknod.mode);
+
+ *vpp = tvp;
VN_KNOTE(ap->a_dvp, NOTE_WRITE);
/* Remove inode so that it will be reloaded by VFS_VGET and
@@ -1118,12 +1218,12 @@ fusefs_read(void *v)
return (EINVAL);
while (uio->uio_resid > 0) {
- fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_READ, p);
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FUSE_READ, p);
size = MIN(uio->uio_resid, fmp->max_read);
- fbuf->fb_io_fd = fusefs_fd_get(ip, FUFH_RDONLY);
- fbuf->fb_io_off = uio->uio_offset;
- fbuf->fb_io_len = size;
+ fbuf->op.in.read.fh = fusefs_fd_get(ip, FUFH_RDONLY);
+ fbuf->op.in.read.offset = uio->uio_offset;
+ fbuf->op.in.read.size = size;
error = fb_queue(fmp->dev, fbuf);
@@ -1177,12 +1277,12 @@ fusefs_write(void *v)
}
while (uio->uio_resid > 0) {
- len = MIN(uio->uio_resid, fmp->max_read);
- fbuf = fb_setup(len, ip->ufs_ino.i_number, FBT_WRITE, p);
+ len = MIN(uio->uio_resid, fmp->max_write);
+ fbuf = fb_setup(len, ip->ufs_ino.i_number, FUSE_WRITE, p);
- fbuf->fb_io_fd = fusefs_fd_get(ip, FUFH_WRONLY);
- fbuf->fb_io_off = uio->uio_offset;
- fbuf->fb_io_len = len;
+ fbuf->op.in.write.fh = fusefs_fd_get(ip, FUFH_WRONLY);
+ fbuf->op.in.write.offset = uio->uio_offset;
+ fbuf->op.in.write.size = len;
if ((error = uiomove(fbuf->fb_dat, len, uio))) {
printf("fusefs: uio error %i\n", error);
@@ -1194,8 +1294,8 @@ fusefs_write(void *v)
if (error)
break;
- diff = len - fbuf->fb_io_len;
- if (fbuf->fb_io_len > len) {
+ diff = len - fbuf->op.out.write.size;
+ if (fbuf->op.out.write.size > len) {
error = EINVAL;
break;
}
@@ -1317,14 +1417,14 @@ abortit:
}
fbuf = fb_setup(fcnp->cn_namelen + tcnp->cn_namelen + 2,
- dp->ufs_ino.i_number, FBT_RENAME, p);
+ dp->ufs_ino.i_number, FUSE_RENAME, p);
memcpy(fbuf->fb_dat, fcnp->cn_nameptr, fcnp->cn_namelen);
fbuf->fb_dat[fcnp->cn_namelen] = '\0';
memcpy(fbuf->fb_dat + fcnp->cn_namelen + 1, tcnp->cn_nameptr,
tcnp->cn_namelen);
fbuf->fb_dat[fcnp->cn_namelen + tcnp->cn_namelen + 1] = '\0';
- fbuf->fb_io_ino = VTOI(tdvp)->ufs_ino.i_number;
+ fbuf->op.in.rename.newdir = VTOI(tdvp)->ufs_ino.i_number;
error = fb_queue(fmp->dev, fbuf);
@@ -1363,7 +1463,7 @@ fusefs_mkdir(void *v)
struct componentname *cnp = ap->a_cnp;
struct vattr *vap = ap->a_vap;
struct proc *p = cnp->cn_proc;
- struct vnode *tdp = NULL;
+ struct vnode *tvp = NULL;
struct fusefs_node *ip;
struct fusefs_mnt *fmp;
struct fusebuf *fbuf;
@@ -1384,9 +1484,10 @@ fusefs_mkdir(void *v)
}
fbuf = fb_setup(cnp->cn_namelen + 1, ip->ufs_ino.i_number,
- FBT_MKDIR, p);
+ FUSE_MKDIR, p);
- fbuf->fb_io_mode = MAKEIMODE(vap->va_type, vap->va_mode);
+ fbuf->op.in.mkdir.mode = MAKEIMODE(vap->va_type, vap->va_mode);
+ fbuf->op.in.mkdir.umask = p->p_p->ps_fd->fd_cmask;
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
@@ -1399,14 +1500,23 @@ fusefs_mkdir(void *v)
goto out;
}
- if ((error = VFS_VGET(fmp->mp, fbuf->fb_ino, &tdp))) {
+ /* mkdir returns a fuse_entry_out with the ino of the new directory */
+ if (fbuf->op.out.entry.nodeid == 0 ||
+ fbuf->op.out.entry.nodeid == FUSE_ROOT_ID) {
+ printf("fusefs_mkdir: file sytem returned invalid nodeid\n");
+ error = EINVAL;
fb_delete(fbuf);
goto out;
}
- tdp->v_type = IFTOVT(fbuf->fb_io_mode);
+ if ((error = VFS_VGET(fmp->mp, fbuf->op.out.entry.nodeid, &tvp))) {
+ fb_delete(fbuf);
+ goto out;
+ }
- *vpp = tdp;
+ tvp->v_type = IFTOVT(fbuf->op.in.mkdir.mode);
+
+ *vpp = tvp;
VN_KNOTE(ap->a_dvp, NOTE_WRITE | NOTE_LINK);
fb_delete(fbuf);
out:
@@ -1444,7 +1554,7 @@ fusefs_rmdir(void *v)
VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
fbuf = fb_setup(cnp->cn_namelen + 1, dp->ufs_ino.i_number,
- FBT_RMDIR, p);
+ FUSE_RMDIR, p);
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
@@ -1501,7 +1611,7 @@ fusefs_remove(void *v)
}
fbuf = fb_setup(cnp->cn_namelen + 1, dp->ufs_ino.i_number,
- FBT_UNLINK, p);
+ FUSE_UNLINK, p);
memcpy(fbuf->fb_dat, cnp->cn_nameptr, cnp->cn_namelen);
fbuf->fb_dat[cnp->cn_namelen] = '\0';
@@ -1604,8 +1714,8 @@ fusefs_fsync(void *v)
if (fufh->fh_type == FUFH_WRONLY ||
fufh->fh_type == FUFH_RDWR) {
- fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_FSYNC, p);
- fbuf->fb_io_fd = fufh->fh_id;
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FUSE_FSYNC, p);
+ fbuf->op.in.fsync.fh = fufh->fh_id;
/* Always behave as if ap->a_waitfor = MNT_WAIT. */
error = fb_queue(fmp->dev, fbuf);
blob - c2d01bd7b14a9a8c96518d8df00a3b9b5259c59a
blob + 75deb300389c5f756a779b40d1fb12b339d3dad7
--- sys/miscfs/fuse/fusebuf.c
+++ sys/miscfs/fuse/fusebuf.c
@@ -25,8 +25,9 @@
#include <sys/statvfs.h>
#include <sys/systm.h>
#include <sys/vnode.h>
-#include <sys/fusebuf.h>
+#include <sys/fuse_kernel.h>
+#include "fusebuf.h"
#include "fusefs_node.h"
#include "fusefs.h"
@@ -35,7 +36,85 @@ fb_setup(size_t len, ino_t ino, int op, struct proc *p
{
struct fusebuf *fbuf;
+ KASSERT(len <= FUSEBUFMAXSIZE);
+
fbuf = pool_get(&fusefs_fbuf_pool, PR_WAITOK | PR_ZERO);
+
+ fbuf->op_in_len = 0;
+ fbuf->op_out_len = 0;
+ fbuf->op_out_buf = 0;
+ switch(op) {
+ case FUSE_GETATTR:
+ fbuf->op_in_len = sizeof(struct fuse_getattr_in);
+ fbuf->op_out_len = sizeof(struct fuse_attr_out);
+ break;
+ case FUSE_SETATTR:
+ fbuf->op_in_len = sizeof(struct fuse_setattr_in);
+ fbuf->op_out_len = sizeof(struct fuse_attr_out);
+ break;
+ case FUSE_READLINK:
+ fbuf->op_out_buf = 1;
+ break;
+ case FUSE_FLUSH:
+ fbuf->op_in_len = sizeof(struct fuse_flush_in);
+ break;
+ case FUSE_INIT:
+ fbuf->op_in_len = sizeof(struct fuse_init_in);
+ fbuf->op_out_len = sizeof(struct fuse_init_out);
+ break;
+ case FUSE_OPEN:
+ case FUSE_OPENDIR:
+ fbuf->op_in_len = sizeof(struct fuse_open_in);
+ fbuf->op_out_len = sizeof(struct fuse_open_out);
+ break;
+ case FUSE_READ:
+ case FUSE_READDIR:
+ fbuf->op_in_len = sizeof(struct fuse_read_in);
+ fbuf->op_out_buf = 1;
+ break;
+ case FUSE_MKDIR:
+ fbuf->op_in_len = sizeof(struct fuse_mkdir_in);
+ fbuf->op_out_len = sizeof(struct fuse_entry_out);
+ break;
+ case FUSE_MKNOD:
+ fbuf->op_in_len = sizeof(struct fuse_mknod_in);
+ fbuf->op_out_len = sizeof(struct fuse_entry_out);
+ break;
+ case FUSE_FSYNC:
+ fbuf->op_in_len = sizeof(struct fuse_fsync_in);
+ break;
+ case FUSE_RENAME:
+ fbuf->op_in_len = sizeof(struct fuse_rename_in);
+ break;
+ case FUSE_LINK:
+ fbuf->op_in_len = sizeof(struct fuse_link_in);
+ fbuf->op_out_len = sizeof(struct fuse_entry_out);
+ break;
+ case FUSE_SYMLINK:
+ fbuf->op_out_len = sizeof(struct fuse_entry_out);
+ break;
+ case FUSE_RELEASE:
+ case FUSE_RELEASEDIR:
+ fbuf->op_in_len = sizeof(struct fuse_release_in);
+ break;
+ case FUSE_WRITE:
+ fbuf->op_in_len = sizeof(struct fuse_write_in);
+ fbuf->op_out_len = sizeof(struct fuse_write_out);
+ break;
+ case FUSE_ACCESS:
+ fbuf->op_in_len = sizeof(struct fuse_access_in);
+ break;
+ case FUSE_FORGET:
+ fbuf->op_in_len = sizeof(struct fuse_forget_in);
+ break;
+ case FUSE_LOOKUP:
+ fbuf->op_out_len = sizeof(struct fuse_entry_out);
+ break;
+ case FUSE_STATFS:
+ fbuf->op_out_len = sizeof(struct fuse_statfs_out);
+ break;
+ }
+ fbuf->hdr.len = sizeof(fbuf->hdr) + fbuf->op_in_len + len;
fbuf->fb_len = len;
fbuf->fb_err = 0;
arc4random_buf(&fbuf->fb_uuid, sizeof fbuf->fb_uuid);
@@ -48,7 +127,6 @@ fb_setup(size_t len, ino_t ino, int op, struct proc *p
fbuf->fb_tid = p->p_tid + THREAD_PID_OFFSET;
fbuf->fb_uid = p->p_ucred->cr_uid;
fbuf->fb_gid = p->p_ucred->cr_gid;
- fbuf->fb_umask = p->p_p->ps_fd->fd_cmask;
if (len == 0)
fbuf->fb_dat = NULL;
else
@@ -82,9 +160,9 @@ int
fb_queue(dev_t dev, struct fusebuf *fbuf)
{
fuse_device_queue_fbuf(dev, fbuf);
- tsleep_nsec(fbuf, PWAIT, "fuse", INFSLP);
+ tsleep_nsec(fbuf, PWAIT, "fbwrite", INFSLP);
- return (fbuf->fb_err);
+ return -(fbuf->fb_err);
}
void
blob - 424291c684aba02bfe08848b5bb42bbaa157bafe
blob + fe429c8d98477e3275c58f5e0b4168b88d180a91
--- sys/miscfs/fuse/fusefs.h
+++ sys/miscfs/fuse/fusefs.h
@@ -33,16 +33,6 @@
{ "fusefs_pool_pages", CTLTYPE_INT }, \
}
-struct fb_ioctl_xch {
- uint64_t fbxch_uuid;
- size_t fbxch_len;
- uint8_t *fbxch_data;
-};
-
-/* FUSE Device ioctls */
-#define FIOCGETFBDAT _IOW('F', 0, struct fb_ioctl_xch)
-#define FIOCSETFBDAT _IOW('F', 1, struct fb_ioctl_xch)
-
#ifdef _KERNEL
struct fuse_msg;
@@ -51,6 +41,7 @@ struct fusefs_mnt {
struct mount *mp;
uint32_t undef_op;
int max_read;
+ int max_write;
int sess_init;
int allow_other;
dev_t dev;
@@ -84,11 +75,6 @@ void fuse_device_cleanup(dev_t);
void fuse_device_queue_fbuf(dev_t, struct fusebuf *);
void fuse_device_set_fmp(struct fusefs_mnt *, int);
-/*
- * The root inode is the root of the file system. Inode 0 can't be used for
- * normal purposes.
- */
-#define FUSE_ROOTINO ((ino_t)1)
#define VFSTOFUSEFS(mp) ((struct fusefs_mnt *)((mp)->mnt_data))
#endif /* _KERNEL */
blob - /dev/null
blob + ec55aff1d6315ae3904d0017dea7011a7e0e9e7b (mode 644)
--- /dev/null
+++ sys/miscfs/fuse/fusebuf.h
@@ -0,0 +1,100 @@
+/* $OpenBSD: fusebuf.h,v 1.13 2018/06/19 11:27:54 helg Exp $ */
+/*
+ * Copyright (c) 2013 Sylvestre Gallon
+ * Copyright (c) 2013 Martin Pieuchot
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SYS_FUSEBUF_H_
+#define _SYS_FUSEBUF_H_
+
+#include <sys/fuse_kernel.h>
+
+/*
+ * Fusebufs vary in size depending on the operation up to a maximum sane
+ * size for the data used in read, readdir, write etc.
+ */
+#define FUSEBUF_INSIZE(fbuf) \
+ (sizeof(struct fuse_in_header) + (fbuf)->op_in_len + (fbuf)->dat_len)
+#define FUSEBUF_OUTSIZE(fbuf) \
+ (sizeof(struct fuse_out_header) + (fbuf)->op_out_len + \
+ ((fbuf)->op_out_buf ? (fbuf)->dat_len : 0))
+/*
+ * Maximum size for fb_dat.
+ */
+#define FUSEBUFMAXSIZE (4096*1024)
+
+/*
+ * An operation is issued by the kernel through fuse(4) when the
+ * userland file system needs to execute an action (mkdir(2),
+ * link(2), etc).
+ *
+ * When the userland file system answers to this operation it uses
+ * the same ID (fb_uuid).
+ */
+struct fusebuf {
+ SIMPLEQ_ENTRY(fusebuf) next; /* next buffer in chain */
+ int32_t error; /* error returned by daemon */
+ struct fuse_in_header hdr;
+ size_t op_in_len; /* size of input */
+ size_t op_out_len; /* size of output */
+ uint8_t op_out_buf; /* whether to expect data */
+ union {
+ union {
+ struct fuse_forget_in forget;
+ struct fuse_getattr_in getattr;
+ struct fuse_setattr_in setattr;
+ struct fuse_mknod_in mknod;
+ struct fuse_mkdir_in mkdir;
+ struct fuse_rename_in rename;
+ struct fuse_link_in link;
+ struct fuse_open_in open;
+ struct fuse_read_in read;
+ struct fuse_write_in write;
+ struct fuse_release_in release;
+ struct fuse_fsync_in fsync;
+ struct fuse_flush_in flush;
+ struct fuse_init_in init;
+ struct fuse_access_in access;
+ } in;
+ union {
+ struct fuse_entry_out entry;
+ struct fuse_attr_out attr;
+ struct fuse_open_out open;
+ struct fuse_write_out write;
+ struct fuse_statfs_out statfs;
+ struct fuse_init_out init;
+ } out;
+ } op;
+ uint64_t dat_len;
+ uint8_t *dat;
+};
+
+#define fb_dat dat
+#define fb_next next
+#define fb_err error
+#define fb_len dat_len
+#define fb_type hdr.opcode
+#define fb_uuid hdr.unique
+#define fb_ino hdr.nodeid
+#define fb_tid hdr.pid
+#define fb_uid hdr.uid
+#define fb_gid hdr.gid
+
+/* fusebuf prototypes */
+struct fusebuf *fb_setup(size_t, ino_t, int, struct proc *);
+int fb_queue(dev_t, struct fusebuf *);
+void fb_delete(struct fusebuf *);
+
+#endif /* _SYS_FUSEBUF_H_ */
blob - 3436c84ae3179f5de865193c548184f01c0c73a8
blob + 6db5a847321bb98fcf6b0427822bf6b9d9ea7c43
--- sys/miscfs/fuse/fusefs_node.h
+++ sys/miscfs/fuse/fusefs_node.h
@@ -43,6 +43,9 @@ struct fusefs_node {
/** meta **/
off_t filesize;
+
+ /** lookup count needed by libfuse FUSE_FORGET **/
+ uint64_t nlookup;
};
#ifdef ITOV
blob - 5783e5244d2ab3d42897bd8cf78e6ae1f1f59c64
blob + 973d6a4c23f6fcde8373d49575c0018486784c2a
--- sys/sys/conf.h
+++ sys/sys/conf.h
@@ -467,12 +467,12 @@ extern struct cdevsw cdevsw[];
(dev_type_stop((*))) enodev, 0, selfalse, \
(dev_type_mmap((*))) enodev }
-/* open, close, read, write, poll, ioctl */
+/* open, close, read, write */
#define cdev_fuse_init(c,n) { \
dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
- dev_init(c,n,write), dev_init(c,n,ioctl), \
- (dev_type_stop((*))) enodev, 0, dev_init(c,n,poll), \
- (dev_type_mmap((*))) enodev, 0, D_CLONE, dev_init(c,n,kqfilter) }
+ dev_init(c,n,write), (dev_type_ioctl((*))) enodev, \
+ (dev_type_stop((*))) enodev, 0, seltrue, \
+ (dev_type_mmap((*))) enodev, 0, D_CLONE, seltrue_kqfilter }
/* open, close, ioctl */
#define cdev_pvbus_init(c,n) { \
blob - 87066051f44e008306a1683181a928af7c6a1b4e (mode 644)
blob + /dev/null
--- sys/sys/fusebuf.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* $OpenBSD: fusebuf.h,v 1.13 2018/06/19 11:27:54 helg Exp $ */
-/*
- * Copyright (c) 2013 Sylvestre Gallon
- * Copyright (c) 2013 Martin Pieuchot
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _SYS_FUSEBUF_H_
-#define _SYS_FUSEBUF_H_
-
-/*
- * Fusebufs are of a single size, 4096 bytes.
- */
-#define FUSEBUFSIZE (sizeof(struct fusebuf))
-#define FUSEBUFMAXSIZE (4096*1024)
-
-/* header at beginning of each fusebuf: */
-struct fb_hdr {
- SIMPLEQ_ENTRY(fusebuf) fh_next; /* next buffer in chain */
- size_t fh_len; /* Amount of data */
- int fh_err; /* errno to pass back */
- int fh_type; /* type of data */
- ino_t fh_ino; /* Inode of this fusebuf */
- uint64_t fh_uuid; /* Uuid to track the answer */
- pid_t fh_tid; /* calling proc thread id */
- uid_t fh_uid; /* calling proc uid */
- gid_t fh_gid; /* calling proc gid */
- mode_t fh_umask; /* calling proc umask */
-};
-
-/* header for fuse file operations (like read/write/mkdir): */
-struct fb_io {
- uint64_t fi_fd; /* fd where the io is performed */
- ino_t fi_ino; /* ino for the io */
- off_t fi_off; /* offset for the io */
- size_t fi_len; /* Length of data */
- mode_t fi_mode; /* mode for fd */
- uint32_t fi_flags; /* flags on transfer */
- dev_t fi_rdev; /* dev for mknod */
-};
-
-/*
- * An operation is issued by the kernel through fuse(4) when the
- * userland file system needs to execute an action (mkdir(2),
- * link(2), etc).
- *
- * F_databuf can be superior to FUSELEN for fusefs_read, fusefs_writes and
- * fusefs_readdir. If it is the case the transfer will be split in N
- * fusebuf with a changing offset in FD_io.
- *
- * When the userland file system answers to this operation it uses
- * the same ID (fh_uuid).
- */
-struct fusebuf {
- struct fb_hdr fb_hdr;
- union {
- struct statvfs FD_stat; /* vfs statfs */
- struct stat FD_attr; /* for attr vnops */
- struct fb_io FD_io; /* for file io vnops */
- } FD;
- uint8_t *fb_dat; /* data's */
-};
-
-#define fb_next fb_hdr.fh_next
-#define fb_len fb_hdr.fh_len
-#define fb_err fb_hdr.fh_err
-#define fb_type fb_hdr.fh_type
-#define fb_ino fb_hdr.fh_ino
-#define fb_uuid fb_hdr.fh_uuid
-#define fb_tid fb_hdr.fh_tid
-#define fb_uid fb_hdr.fh_uid
-#define fb_gid fb_hdr.fh_gid
-#define fb_umask fb_hdr.fh_umask
-
-#define fb_stat FD.FD_stat
-#define fb_attr FD.FD_attr
-#define fb_io_fd FD.FD_io.fi_fd
-#define fb_io_ino FD.FD_io.fi_ino
-#define fb_io_off FD.FD_io.fi_off
-#define fb_io_len FD.FD_io.fi_len
-#define fb_io_mode FD.FD_io.fi_mode
-#define fb_io_flags FD.FD_io.fi_flags
-#define fb_io_rdev FD.FD_io.fi_rdev
-
-/*
- * Macros for type conversion
- * fbtod(fb,t) - convert fusebuf pointer to data pointer of correct
- * type
- */
-#define fbtod(fb,t) ((t)((fb)->fb_dat))
-
-/* flags needed by setattr */
-#define FUSE_FATTR_MODE (1 << 0)
-#define FUSE_FATTR_UID (1 << 1)
-#define FUSE_FATTR_GID (1 << 2)
-#define FUSE_FATTR_SIZE (1 << 3)
-#define FUSE_FATTR_ATIME (1 << 4)
-#define FUSE_FATTR_MTIME (1 << 5)
-#define FUSE_FATTR_FH (1 << 6)
-
-/* fusebuf types */
-#define FBT_LOOKUP 0
-#define FBT_GETATTR 1
-#define FBT_SETATTR 2
-#define FBT_READLINK 3
-#define FBT_SYMLINK 4
-#define FBT_MKNOD 5
-#define FBT_MKDIR 6
-#define FBT_UNLINK 7
-#define FBT_RMDIR 8
-#define FBT_RENAME 9
-#define FBT_LINK 10
-#define FBT_OPEN 11
-#define FBT_READ 12
-#define FBT_WRITE 13
-#define FBT_STATFS 14
-#define FBT_RELEASE 16
-#define FBT_FSYNC 17
-#define FBT_FLUSH 18
-#define FBT_INIT 19
-#define FBT_OPENDIR 20
-#define FBT_READDIR 21
-#define FBT_RELEASEDIR 22
-#define FBT_FSYNCDIR 23
-#define FBT_ACCESS 24
-#define FBT_DESTROY 26
-#define FBT_RECLAIM 27
-
-#ifdef _KERNEL
-
-/* fusebuf prototypes */
-struct fusebuf *fb_setup(size_t, ino_t, int, struct proc *);
-int fb_queue(dev_t, struct fusebuf *);
-void fb_delete(struct fusebuf *);
-
-#endif /* _KERNEL */
-#endif /* _SYS_FUSEBUF_H_ */
blob - /dev/null
blob + c632b58fbcf43103609523cc90fa708caee6d14f (mode 644)
--- /dev/null
+++ sys/sys/fuse_kernel.h
@@ -0,0 +1,691 @@
+/*
+ This file defines the kernel interface of FUSE
+ Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+
+ This -- and only this -- header file may also be distributed under
+ the terms of the BSD Licence as follows:
+
+ Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+/*
+ * This file defines the kernel interface of FUSE
+ *
+ * Protocol changelog:
+ *
+ * 7.9:
+ * - new fuse_getattr_in input argument of GETATTR
+ * - add lk_flags in fuse_lk_in
+ * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
+ * - add blksize field to fuse_attr
+ * - add file flags field to fuse_read_in and fuse_write_in
+ *
+ * 7.10
+ * - add nonseekable open flag
+ *
+ * 7.11
+ * - add IOCTL message
+ * - add unsolicited notification support
+ * - add POLL message and NOTIFY_POLL notification
+ *
+ * 7.12
+ * - add umask flag to input argument of open, mknod and mkdir
+ * - add notification messages for invalidation of inodes and
+ * directory entries
+ *
+ * 7.13
+ * - make max number of background requests and congestion threshold
+ * tunables
+ *
+ * 7.14
+ * - add splice support to fuse device
+ *
+ * 7.15
+ * - add store notify
+ * - add retrieve notify
+ *
+ * 7.16
+ * - add BATCH_FORGET request
+ * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct
+ * fuse_ioctl_iovec' instead of ambiguous 'struct iovec'
+ * - add FUSE_IOCTL_32BIT flag
+ *
+ * 7.17
+ * - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK
+ *
+ * 7.18
+ * - add FUSE_IOCTL_DIR flag
+ * - add FUSE_NOTIFY_DELETE
+ *
+ * 7.19
+ * - add FUSE_FALLOCATE
+ */
+
+#ifndef _LINUX_FUSE_H
+#define _LINUX_FUSE_H
+
+#include <sys/types.h>
+#define __u64 uint64_t
+#define __s64 int64_t
+#define __u32 uint32_t
+#define __s32 int32_t
+#define __u16 uint16_t
+
+/*
+ * Version negotiation:
+ *
+ * Both the kernel and userspace send the version they support in the
+ * INIT request and reply respectively.
+ *
+ * If the major versions match then both shall use the smallest
+ * of the two minor versions for communication.
+ *
+ * If the kernel supports a larger major version, then userspace shall
+ * reply with the major version it supports, ignore the rest of the
+ * INIT message and expect a new INIT message from the kernel with a
+ * matching major version.
+ *
+ * If the library supports a larger major version, then it shall fall
+ * back to the major protocol version sent by the kernel for
+ * communication and reply with that major version (and an arbitrary
+ * supported minor version).
+ */
+
+/** Version number of this interface */
+#define FUSE_KERNEL_VERSION 7
+
+/** Minor version number of this interface */
+#define FUSE_KERNEL_MINOR_VERSION 19
+
+/** The node ID of the root inode */
+#define FUSE_ROOT_ID 1
+
+/* Make sure all structures are padded to 64bit boundary, so 32bit
+ userspace works under 64bit kernels */
+
+struct fuse_attr {
+ __u64 ino;
+ __u64 size;
+ __u64 blocks;
+ __u64 atime;
+ __u64 mtime;
+ __u64 ctime;
+ __u32 atimensec;
+ __u32 mtimensec;
+ __u32 ctimensec;
+ __u32 mode;
+ __u32 nlink;
+ __u32 uid;
+ __u32 gid;
+ __u32 rdev;
+ __u32 blksize;
+ __u32 padding;
+};
+
+struct fuse_kstatfs {
+ __u64 blocks;
+ __u64 bfree;
+ __u64 bavail;
+ __u64 files;
+ __u64 ffree;
+ __u32 bsize;
+ __u32 namelen;
+ __u32 frsize;
+ __u32 padding;
+ __u32 spare[6];
+};
+
+struct fuse_file_lock {
+ __u64 start;
+ __u64 end;
+ __u32 type;
+ __u32 pid; /* tgid */
+};
+
+/**
+ * Bitmasks for fuse_setattr_in.valid
+ */
+#define FATTR_MODE (1 << 0)
+#define FATTR_UID (1 << 1)
+#define FATTR_GID (1 << 2)
+#define FATTR_SIZE (1 << 3)
+#define FATTR_ATIME (1 << 4)
+#define FATTR_MTIME (1 << 5)
+#define FATTR_FH (1 << 6)
+#define FATTR_ATIME_NOW (1 << 7)
+#define FATTR_MTIME_NOW (1 << 8)
+#define FATTR_LOCKOWNER (1 << 9)
+
+/**
+ * Flags returned by the OPEN request
+ *
+ * FOPEN_DIRECT_IO: bypass page cache for this open file
+ * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
+ * FOPEN_NONSEEKABLE: the file is not seekable
+ */
+#define FOPEN_DIRECT_IO (1 << 0)
+#define FOPEN_KEEP_CACHE (1 << 1)
+#define FOPEN_NONSEEKABLE (1 << 2)
+
+/**
+ * INIT request/reply flags
+ *
+ * FUSE_POSIX_LOCKS: remote locking for POSIX file locks
+ * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
+ * FUSE_DONT_MASK: don't apply umask to file mode on create operations
+ * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
+ */
+#define FUSE_ASYNC_READ (1 << 0)
+#define FUSE_POSIX_LOCKS (1 << 1)
+#define FUSE_FILE_OPS (1 << 2)
+#define FUSE_ATOMIC_O_TRUNC (1 << 3)
+#define FUSE_EXPORT_SUPPORT (1 << 4)
+#define FUSE_BIG_WRITES (1 << 5)
+#define FUSE_DONT_MASK (1 << 6)
+#define FUSE_FLOCK_LOCKS (1 << 10)
+
+/**
+ * CUSE INIT request/reply flags
+ *
+ * CUSE_UNRESTRICTED_IOCTL: use unrestricted ioctl
+ */
+#define CUSE_UNRESTRICTED_IOCTL (1 << 0)
+
+/**
+ * Release flags
+ */
+#define FUSE_RELEASE_FLUSH (1 << 0)
+#define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1)
+
+/**
+ * Getattr flags
+ */
+#define FUSE_GETATTR_FH (1 << 0)
+
+/**
+ * Lock flags
+ */
+#define FUSE_LK_FLOCK (1 << 0)
+
+/**
+ * WRITE flags
+ *
+ * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
+ * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
+ */
+#define FUSE_WRITE_CACHE (1 << 0)
+#define FUSE_WRITE_LOCKOWNER (1 << 1)
+
+/**
+ * Read flags
+ */
+#define FUSE_READ_LOCKOWNER (1 << 1)
+
+/**
+ * Ioctl flags
+ *
+ * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
+ * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
+ * FUSE_IOCTL_RETRY: retry with new iovecs
+ * FUSE_IOCTL_32BIT: 32bit ioctl
+ * FUSE_IOCTL_DIR: is a directory
+ *
+ * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
+ */
+#define FUSE_IOCTL_COMPAT (1 << 0)
+#define FUSE_IOCTL_UNRESTRICTED (1 << 1)
+#define FUSE_IOCTL_RETRY (1 << 2)
+#define FUSE_IOCTL_32BIT (1 << 3)
+#define FUSE_IOCTL_DIR (1 << 4)
+
+#define FUSE_IOCTL_MAX_IOV 256
+
+/**
+ * Poll flags
+ *
+ * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify
+ */
+#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)
+
+enum fuse_opcode {
+ FUSE_LOOKUP = 1,
+ FUSE_FORGET = 2, /* no reply */
+ FUSE_GETATTR = 3,
+ FUSE_SETATTR = 4,
+ FUSE_READLINK = 5,
+ FUSE_SYMLINK = 6,
+ FUSE_MKNOD = 8,
+ FUSE_MKDIR = 9,
+ FUSE_UNLINK = 10,
+ FUSE_RMDIR = 11,
+ FUSE_RENAME = 12,
+ FUSE_LINK = 13,
+ FUSE_OPEN = 14,
+ FUSE_READ = 15,
+ FUSE_WRITE = 16,
+ FUSE_STATFS = 17,
+ FUSE_RELEASE = 18,
+ FUSE_FSYNC = 20,
+ FUSE_SETXATTR = 21,
+ FUSE_GETXATTR = 22,
+ FUSE_LISTXATTR = 23,
+ FUSE_REMOVEXATTR = 24,
+ FUSE_FLUSH = 25,
+ FUSE_INIT = 26,
+ FUSE_OPENDIR = 27,
+ FUSE_READDIR = 28,
+ FUSE_RELEASEDIR = 29,
+ FUSE_FSYNCDIR = 30,
+ FUSE_GETLK = 31,
+ FUSE_SETLK = 32,
+ FUSE_SETLKW = 33,
+ FUSE_ACCESS = 34,
+ FUSE_CREATE = 35,
+ FUSE_INTERRUPT = 36,
+ FUSE_BMAP = 37,
+ FUSE_DESTROY = 38,
+ FUSE_IOCTL = 39,
+ FUSE_POLL = 40,
+ FUSE_NOTIFY_REPLY = 41,
+ FUSE_BATCH_FORGET = 42,
+ FUSE_FALLOCATE = 43,
+
+ /* CUSE specific operations */
+ CUSE_INIT = 4096,
+};
+
+enum fuse_notify_code {
+ FUSE_NOTIFY_POLL = 1,
+ FUSE_NOTIFY_INVAL_INODE = 2,
+ FUSE_NOTIFY_INVAL_ENTRY = 3,
+ FUSE_NOTIFY_STORE = 4,
+ FUSE_NOTIFY_RETRIEVE = 5,
+ FUSE_NOTIFY_DELETE = 6,
+ FUSE_NOTIFY_CODE_MAX,
+};
+
+/* The read buffer is required to be at least 8k, but may be much larger */
+#define FUSE_MIN_READ_BUFFER 8192
+
+#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
+
+struct fuse_entry_out {
+ __u64 nodeid; /* Inode ID */
+ __u64 generation; /* Inode generation: nodeid:gen must
+ be unique for the fs's lifetime */
+ __u64 entry_valid; /* Cache timeout for the name */
+ __u64 attr_valid; /* Cache timeout for the attributes */
+ __u32 entry_valid_nsec;
+ __u32 attr_valid_nsec;
+ struct fuse_attr attr;
+};
+
+struct fuse_forget_in {
+ __u64 nlookup;
+};
+
+struct fuse_forget_one {
+ __u64 nodeid;
+ __u64 nlookup;
+};
+
+struct fuse_batch_forget_in {
+ __u32 count;
+ __u32 dummy;
+};
+
+struct fuse_getattr_in {
+ __u32 getattr_flags;
+ __u32 dummy;
+ __u64 fh;
+};
+
+#define FUSE_COMPAT_ATTR_OUT_SIZE 96
+
+struct fuse_attr_out {
+ __u64 attr_valid; /* Cache timeout for the attributes */
+ __u32 attr_valid_nsec;
+ __u32 dummy;
+ struct fuse_attr attr;
+};
+
+#define FUSE_COMPAT_MKNOD_IN_SIZE 8
+
+struct fuse_mknod_in {
+ __u32 mode;
+ __u32 rdev;
+ __u32 umask;
+ __u32 padding;
+};
+
+struct fuse_mkdir_in {
+ __u32 mode;
+ __u32 umask;
+};
+
+struct fuse_rename_in {
+ __u64 newdir;
+};
+
+struct fuse_link_in {
+ __u64 oldnodeid;
+};
+
+struct fuse_setattr_in {
+ __u32 valid;
+ __u32 padding;
+ __u64 fh;
+ __u64 size;
+ __u64 lock_owner;
+ __u64 atime;
+ __u64 mtime;
+ __u64 unused2;
+ __u32 atimensec;
+ __u32 mtimensec;
+ __u32 unused3;
+ __u32 mode;
+ __u32 unused4;
+ __u32 uid;
+ __u32 gid;
+ __u32 unused5;
+};
+
+struct fuse_open_in {
+ __u32 flags;
+ __u32 unused;
+};
+
+struct fuse_create_in {
+ __u32 flags;
+ __u32 mode;
+ __u32 umask;
+ __u32 padding;
+};
+
+struct fuse_open_out {
+ __u64 fh;
+ __u32 open_flags;
+ __u32 padding;
+};
+
+struct fuse_release_in {
+ __u64 fh;
+ __u32 flags;
+ __u32 release_flags;
+ __u64 lock_owner;
+};
+
+struct fuse_flush_in {
+ __u64 fh;
+ __u32 unused;
+ __u32 padding;
+ __u64 lock_owner;
+};
+
+struct fuse_read_in {
+ __u64 fh;
+ __u64 offset;
+ __u32 size;
+ __u32 read_flags;
+ __u64 lock_owner;
+ __u32 flags;
+ __u32 padding;
+};
+
+#define FUSE_COMPAT_WRITE_IN_SIZE 24
+
+struct fuse_write_in {
+ __u64 fh;
+ __u64 offset;
+ __u32 size;
+ __u32 write_flags;
+ __u64 lock_owner;
+ __u32 flags;
+ __u32 padding;
+};
+
+struct fuse_write_out {
+ __u32 size;
+ __u32 padding;
+};
+
+#define FUSE_COMPAT_STATFS_SIZE 48
+
+struct fuse_statfs_out {
+ struct fuse_kstatfs st;
+};
+
+struct fuse_fsync_in {
+ __u64 fh;
+ __u32 fsync_flags;
+ __u32 padding;
+};
+
+struct fuse_setxattr_in {
+ __u32 size;
+ __u32 flags;
+};
+
+struct fuse_getxattr_in {
+ __u32 size;
+ __u32 padding;
+};
+
+struct fuse_getxattr_out {
+ __u32 size;
+ __u32 padding;
+};
+
+struct fuse_lk_in {
+ __u64 fh;
+ __u64 owner;
+ struct fuse_file_lock lk;
+ __u32 lk_flags;
+ __u32 padding;
+};
+
+struct fuse_lk_out {
+ struct fuse_file_lock lk;
+};
+
+struct fuse_access_in {
+ __u32 mask;
+ __u32 padding;
+};
+
+struct fuse_init_in {
+ __u32 major;
+ __u32 minor;
+ __u32 max_readahead;
+ __u32 flags;
+};
+
+struct fuse_init_out {
+ __u32 major;
+ __u32 minor;
+ __u32 max_readahead;
+ __u32 flags;
+ __u16 max_background;
+ __u16 congestion_threshold;
+ __u32 max_write;
+};
+
+#define CUSE_INIT_INFO_MAX 4096
+
+struct cuse_init_in {
+ __u32 major;
+ __u32 minor;
+ __u32 unused;
+ __u32 flags;
+};
+
+struct cuse_init_out {
+ __u32 major;
+ __u32 minor;
+ __u32 unused;
+ __u32 flags;
+ __u32 max_read;
+ __u32 max_write;
+ __u32 dev_major; /* chardev major */
+ __u32 dev_minor; /* chardev minor */
+ __u32 spare[10];
+};
+
+struct fuse_interrupt_in {
+ __u64 unique;
+};
+
+struct fuse_bmap_in {
+ __u64 block;
+ __u32 blocksize;
+ __u32 padding;
+};
+
+struct fuse_bmap_out {
+ __u64 block;
+};
+
+struct fuse_ioctl_in {
+ __u64 fh;
+ __u32 flags;
+ __u32 cmd;
+ __u64 arg;
+ __u32 in_size;
+ __u32 out_size;
+};
+
+struct fuse_ioctl_iovec {
+ __u64 base;
+ __u64 len;
+};
+
+struct fuse_ioctl_out {
+ __s32 result;
+ __u32 flags;
+ __u32 in_iovs;
+ __u32 out_iovs;
+};
+
+struct fuse_poll_in {
+ __u64 fh;
+ __u64 kh;
+ __u32 flags;
+ __u32 padding;
+};
+
+struct fuse_poll_out {
+ __u32 revents;
+ __u32 padding;
+};
+
+struct fuse_notify_poll_wakeup_out {
+ __u64 kh;
+};
+
+struct fuse_fallocate_in {
+ __u64 fh;
+ __u64 offset;
+ __u64 length;
+ __u32 mode;
+ __u32 padding;
+};
+
+struct fuse_in_header {
+ __u32 len;
+ __u32 opcode;
+ __u64 unique;
+ __u64 nodeid;
+ __u32 uid;
+ __u32 gid;
+ __u32 pid;
+ __u32 padding;
+};
+
+struct fuse_out_header {
+ __u32 len;
+ __s32 error;
+ __u64 unique;
+};
+
+struct fuse_dirent {
+ __u64 ino;
+ __u64 off;
+ __u32 namelen;
+ __u32 type;
+ char name[];
+};
+
+#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
+#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
+#define FUSE_DIRENT_SIZE(d) \
+ FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
+
+struct fuse_notify_inval_inode_out {
+ __u64 ino;
+ __s64 off;
+ __s64 len;
+};
+
+struct fuse_notify_inval_entry_out {
+ __u64 parent;
+ __u32 namelen;
+ __u32 padding;
+};
+
+struct fuse_notify_delete_out {
+ __u64 parent;
+ __u64 child;
+ __u32 namelen;
+ __u32 padding;
+};
+
+struct fuse_notify_store_out {
+ __u64 nodeid;
+ __u64 offset;
+ __u32 size;
+ __u32 padding;
+};
+
+struct fuse_notify_retrieve_out {
+ __u64 notify_unique;
+ __u64 nodeid;
+ __u64 offset;
+ __u32 size;
+ __u32 padding;
+};
+
+/* Matches the size of fuse_write_in */
+struct fuse_notify_retrieve_in {
+ __u64 dummy1;
+ __u64 offset;
+ __u32 size;
+ __u32 dummy2;
+ __u64 dummy3;
+ __u64 dummy4;
+};
+
+#endif /* _LINUX_FUSE_H */
Hi tech & ports,
I have once again been hacking on FUSE and have modified the kernel so
that the protocol used to communicate with userland is compatible with
other platforms.
This has the following benefits:
1. Enables the use of the reference version of libfuse so an OpenBSD
version of libfuse no longer needs to be maintained.
2. Porting of FUSE file systems is easier.
3. Porting of FUSE file systems that communicate directly with
/dev/fuse0 is now significantly easier. There are currently none in
ports because it's too hard.
Here's a summary of the changes that I am proposing to commit:
1. Modify the kernel so the protocol is binary compatible with other
platforms.
2. Remove libfuse from base.
3. Add libfuse to ports.
4. Modify the existing 24 ports to use libfuse from ports (this is not
yet complete and I will need help from porters)
I have attached both the OpenBSD source changes (created with got diff)
and the libfuse port for review. Thanks to mpi@ for his keen eyes on
the kernel changes and bket@ and abieber@ for help with the port.
I currently only have a port of the 2.x branch of libfuse (attached) but
will also port the 3.x libfuse once I have user mounting working. I am
not aware of any ports other than the latest version of sshfs that
depends on 3.x. In any case, we will need to support libfuse 2.x for
some time until all file systems are updated upstream to work with 3.x.
User mounting of file systems is something I plan to add later. It will
require a few kernel modifications. This change does not add new
functionality, it is only to switch to the reference libfuse.
I would like some advice on how best to commit all of this once it's
approved. The kernel and ports commits will need to be synchronised. Do
I bundle all the ports changes in one commit?
The patch is quite large so here's a summary.
fuse_kernel.h
New file added from Linux. This is a BSD licensed file from the Linux
and libfuse sources and defines the message formats for the FUSE kernel
protocol. This is included in the kernel source as well as libfuse
source. Other platforms do not distribute this file but I have included
it in /sys/sys since it documents the protocol and is needed for
development of file systems that communicate directly with /dev/fuse0.
Advice and opinions on this are welcome.
fuse_device.c
The FUSE device that implements the FUSE kernel protocol and therefore
required the most changes to be compatible with the reference
implementation.
It previously used ioctls to read and write data buffers for messages
that are a variable size (e.g. read, readdir, write). However, the FUSE
protocol expects the entire message to be read and written in one go.
This is the most important file to audit since it's where userland
writes back to the kernel so we need to protect against malicious data
being passed by the userland file system daemon.
The file system is no longer automatically unmounted when the FUSE
device is closed. This is consistent with other platforms. The file
system can still be manually unmounted with umount(2) in this situation.
I've removed debug output since it's not useful.
fuse_file.c
No significant changes. Aligned to new fuse_kernel.h header file.
fuse_lookup.c
No significant changes. Aligned to new fuse_kernel.h header file.
fuse_vfsops.c
No significant changes. Aligned to new fuse_kernel.h header file and
FUSE protocol changes for FUSE_INIT message. FUSE_INIT is the first
message sent by the kernel to the file system and is used to negotiate
the protocol version.
fusebuf.h
This header file has been moved from /sys/sys to /sys/miscfs/fuse since
struct fusebuf is no longer exposed to userland. struct fusebuf has
been completely modified to support the message formats defined in
fuse_kernel.h. Removed all FBT_* message type constants since these are
now defined in fuse_kernel.h as FUSE_*.
fusebuf.c
Umask for file creation is no longer set for all messages. It is now
only set for FUSE_MKDIR and FUSE_MKNOD fusebuf as per the FUSE protocol.
Read and write lengths for each message type are now set up in fb_setup
so that device reads and writes can be validated for sanity.
fusefs.h
Removed ioctl constants and structs since ioctl is no longer needed to
read and write from /dev/fuse0. Deleted FUSE_ROOTINO, this is now
defined as FUSE_ROOT_ID in fuse_kernel.h
fusefs_node.h
No change.
fuse_vnops.c
Mostly no significant changes. Aligned to new fuse_kernel.h header file.
The most significant change is to fusefs_readdir, which now needs to map
between fuse_dirent and dirent.
One question I have is whether we need to check that va_blocksize is not
too large in fusefs_fsstat as per
<https://ftp.openbsd.org/pub/OpenBSD/patches/6.1/common/017_fuse.patch.sig>
or is it enough that we now have a check in the getcwd sys call?
Thanks for reading this far. Any comments, suggestions and help are
welcome.
Regards,
Helg
No comments:
Post a Comment