From a9acd7ce8e87a2f3292dd23b0514746dd9a43c5b Mon Sep 17 00:00:00 2001 From: David Scott Date: Thu, 25 Jan 2018 16:44:22 +0000 Subject: [PATCH 1/7] Add support for FUSE 7.24 Signed-off-by: David Scott --- lib/profuse_.mllib | 2 + lib_gen/fuse_kernel.h.7_24 | 776 ++++++++++++++++++++++++++++++++++ lib_gen/profuse_typegen.ml | 1 + lib_gen/profuse_types_7_24.ml | 129 ++++++ 4 files changed, 908 insertions(+) create mode 100644 lib_gen/fuse_kernel.h.7_24 create mode 100644 lib_gen/profuse_types_7_24.ml diff --git a/lib/profuse_.mllib b/lib/profuse_.mllib index a5b70b4..c6642c8 100644 --- a/lib/profuse_.mllib +++ b/lib/profuse_.mllib @@ -16,6 +16,7 @@ Profuse_types_7_20 Profuse_types_7_21 Profuse_types_7_22 Profuse_types_7_23 +Profuse_types_7_24 Profuse_types_detected_7_8 Profuse_types_detected_7_9 Profuse_types_detected_7_10 @@ -32,6 +33,7 @@ Profuse_types_detected_7_20 Profuse_types_detected_7_21 Profuse_types_detected_7_22 Profuse_types_detected_7_23 +Profuse_types_detected_7_24 Profuse_signatures Profuse_7_8 Profuse_7_23 diff --git a/lib_gen/fuse_kernel.h.7_24 b/lib_gen/fuse_kernel.h.7_24 new file mode 100644 index 0000000..5974fae --- /dev/null +++ b/lib_gen/fuse_kernel.h.7_24 @@ -0,0 +1,776 @@ +/* + This file defines the kernel interface of FUSE + Copyright (C) 2001-2008 Miklos Szeredi + + This program can be distributed under the terms of the GNU GPL. + See the file COPYING. + + This -- and only this -- header file may also be distributed under + the terms of the BSD Licence as follows: + + Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +/* + * This file defines the kernel interface of FUSE + * + * Protocol changelog: + * + * 7.9: + * - new fuse_getattr_in input argument of GETATTR + * - add lk_flags in fuse_lk_in + * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in + * - add blksize field to fuse_attr + * - add file flags field to fuse_read_in and fuse_write_in + * + * 7.10 + * - add nonseekable open flag + * + * 7.11 + * - add IOCTL message + * - add unsolicited notification support + * - add POLL message and NOTIFY_POLL notification + * + * 7.12 + * - add umask flag to input argument of open, mknod and mkdir + * - add notification messages for invalidation of inodes and + * directory entries + * + * 7.13 + * - make max number of background requests and congestion threshold + * tunables + * + * 7.14 + * - add splice support to fuse device + * + * 7.15 + * - add store notify + * - add retrieve notify + * + * 7.16 + * - add BATCH_FORGET request + * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct + * fuse_ioctl_iovec' instead of ambiguous 'struct iovec' + * - add FUSE_IOCTL_32BIT flag + * + * 7.17 + * - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK + * + * 7.18 + * - add FUSE_IOCTL_DIR flag + * - add FUSE_NOTIFY_DELETE + * + * 7.19 + * - add FUSE_FALLOCATE + * + * 7.20 + * - add FUSE_AUTO_INVAL_DATA + * + * 7.21 + * - add FUSE_READDIRPLUS + * - send the requested events in POLL request + * + * 7.22 + * - add FUSE_ASYNC_DIO + * + * 7.23 + * - add FUSE_WRITEBACK_CACHE + * - add time_gran to fuse_init_out + * - add reserved space to fuse_init_out + * - add FATTR_CTIME + * - add ctime and ctimensec to fuse_setattr_in + * - add FUSE_RENAME2 request + * - add FUSE_NO_OPEN_SUPPORT flag + * + * 7.24 + * - add FUSE_LSEEK for SEEK_HOLE and SEEK_DATA support + */ + +#ifndef _LINUX_FUSE_H +#define _LINUX_FUSE_H + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +/* + * Version negotiation: + * + * Both the kernel and userspace send the version they support in the + * INIT request and reply respectively. + * + * If the major versions match then both shall use the smallest + * of the two minor versions for communication. + * + * If the kernel supports a larger major version, then userspace shall + * reply with the major version it supports, ignore the rest of the + * INIT message and expect a new INIT message from the kernel with a + * matching major version. + * + * If the library supports a larger major version, then it shall fall + * back to the major protocol version sent by the kernel for + * communication and reply with that major version (and an arbitrary + * supported minor version). + */ + +/** Version number of this interface */ +#define FUSE_KERNEL_VERSION 7 + +/** Minor version number of this interface */ +#define FUSE_KERNEL_MINOR_VERSION 24 + +/** The node ID of the root inode */ +#define FUSE_ROOT_ID 1 + +/* Make sure all structures are padded to 64bit boundary, so 32bit + userspace works under 64bit kernels */ + +struct fuse_attr { + uint64_t ino; + uint64_t size; + uint64_t blocks; + uint64_t atime; + uint64_t mtime; + uint64_t ctime; + uint32_t atimensec; + uint32_t mtimensec; + uint32_t ctimensec; + uint32_t mode; + uint32_t nlink; + uint32_t uid; + uint32_t gid; + uint32_t rdev; + uint32_t blksize; + uint32_t padding; +}; + +struct fuse_kstatfs { + uint64_t blocks; + uint64_t bfree; + uint64_t bavail; + uint64_t files; + uint64_t ffree; + uint32_t bsize; + uint32_t namelen; + uint32_t frsize; + uint32_t padding; + uint32_t spare[6]; +}; + +struct fuse_file_lock { + uint64_t start; + uint64_t end; + uint32_t type; + uint32_t pid; /* tgid */ +}; + +/** + * Bitmasks for fuse_setattr_in.valid + */ +#define FATTR_MODE (1 << 0) +#define FATTR_UID (1 << 1) +#define FATTR_GID (1 << 2) +#define FATTR_SIZE (1 << 3) +#define FATTR_ATIME (1 << 4) +#define FATTR_MTIME (1 << 5) +#define FATTR_FH (1 << 6) +#define FATTR_ATIME_NOW (1 << 7) +#define FATTR_MTIME_NOW (1 << 8) +#define FATTR_LOCKOWNER (1 << 9) +#define FATTR_CTIME (1 << 10) + +/** + * Flags returned by the OPEN request + * + * FOPEN_DIRECT_IO: bypass page cache for this open file + * FOPEN_KEEP_CACHE: don't invalidate the data cache on open + * FOPEN_NONSEEKABLE: the file is not seekable + */ +#define FOPEN_DIRECT_IO (1 << 0) +#define FOPEN_KEEP_CACHE (1 << 1) +#define FOPEN_NONSEEKABLE (1 << 2) + +/** + * INIT request/reply flags + * + * FUSE_ASYNC_READ: asynchronous read requests + * FUSE_POSIX_LOCKS: remote locking for POSIX file locks + * FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported) + * FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem + * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".." + * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB + * FUSE_DONT_MASK: don't apply umask to file mode on create operations + * FUSE_SPLICE_WRITE: kernel supports splice write on the device + * FUSE_SPLICE_MOVE: kernel supports splice move on the device + * FUSE_SPLICE_READ: kernel supports splice read on the device + * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks + * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories + * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages + * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one) + * FUSE_READDIRPLUS_AUTO: adaptive readdirplus + * FUSE_ASYNC_DIO: asynchronous direct I/O submission + * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes + * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens + */ +#define FUSE_ASYNC_READ (1 << 0) +#define FUSE_POSIX_LOCKS (1 << 1) +#define FUSE_FILE_OPS (1 << 2) +#define FUSE_ATOMIC_O_TRUNC (1 << 3) +#define FUSE_EXPORT_SUPPORT (1 << 4) +#define FUSE_BIG_WRITES (1 << 5) +#define FUSE_DONT_MASK (1 << 6) +#define FUSE_SPLICE_WRITE (1 << 7) +#define FUSE_SPLICE_MOVE (1 << 8) +#define FUSE_SPLICE_READ (1 << 9) +#define FUSE_FLOCK_LOCKS (1 << 10) +#define FUSE_HAS_IOCTL_DIR (1 << 11) +#define FUSE_AUTO_INVAL_DATA (1 << 12) +#define FUSE_DO_READDIRPLUS (1 << 13) +#define FUSE_READDIRPLUS_AUTO (1 << 14) +#define FUSE_ASYNC_DIO (1 << 15) +#define FUSE_WRITEBACK_CACHE (1 << 16) +#define FUSE_NO_OPEN_SUPPORT (1 << 17) + +/** + * CUSE INIT request/reply flags + * + * CUSE_UNRESTRICTED_IOCTL: use unrestricted ioctl + */ +#define CUSE_UNRESTRICTED_IOCTL (1 << 0) + +/** + * Release flags + */ +#define FUSE_RELEASE_FLUSH (1 << 0) +#define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1) + +/** + * Getattr flags + */ +#define FUSE_GETATTR_FH (1 << 0) + +/** + * Lock flags + */ +#define FUSE_LK_FLOCK (1 << 0) + +/** + * WRITE flags + * + * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed + * FUSE_WRITE_LOCKOWNER: lock_owner field is valid + */ +#define FUSE_WRITE_CACHE (1 << 0) +#define FUSE_WRITE_LOCKOWNER (1 << 1) + +/** + * Read flags + */ +#define FUSE_READ_LOCKOWNER (1 << 1) + +/** + * Ioctl flags + * + * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine + * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed + * FUSE_IOCTL_RETRY: retry with new iovecs + * FUSE_IOCTL_32BIT: 32bit ioctl + * FUSE_IOCTL_DIR: is a directory + * + * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs + */ +#define FUSE_IOCTL_COMPAT (1 << 0) +#define FUSE_IOCTL_UNRESTRICTED (1 << 1) +#define FUSE_IOCTL_RETRY (1 << 2) +#define FUSE_IOCTL_32BIT (1 << 3) +#define FUSE_IOCTL_DIR (1 << 4) + +#define FUSE_IOCTL_MAX_IOV 256 + +/** + * Poll flags + * + * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify + */ +#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0) + +enum fuse_opcode { + FUSE_LOOKUP = 1, + FUSE_FORGET = 2, /* no reply */ + FUSE_GETATTR = 3, + FUSE_SETATTR = 4, + FUSE_READLINK = 5, + FUSE_SYMLINK = 6, + FUSE_MKNOD = 8, + FUSE_MKDIR = 9, + FUSE_UNLINK = 10, + FUSE_RMDIR = 11, + FUSE_RENAME = 12, + FUSE_LINK = 13, + FUSE_OPEN = 14, + FUSE_READ = 15, + FUSE_WRITE = 16, + FUSE_STATFS = 17, + FUSE_RELEASE = 18, + FUSE_FSYNC = 20, + FUSE_SETXATTR = 21, + FUSE_GETXATTR = 22, + FUSE_LISTXATTR = 23, + FUSE_REMOVEXATTR = 24, + FUSE_FLUSH = 25, + FUSE_INIT = 26, + FUSE_OPENDIR = 27, + FUSE_READDIR = 28, + FUSE_RELEASEDIR = 29, + FUSE_FSYNCDIR = 30, + FUSE_GETLK = 31, + FUSE_SETLK = 32, + FUSE_SETLKW = 33, + FUSE_ACCESS = 34, + FUSE_CREATE = 35, + FUSE_INTERRUPT = 36, + FUSE_BMAP = 37, + FUSE_DESTROY = 38, + FUSE_IOCTL = 39, + FUSE_POLL = 40, + FUSE_NOTIFY_REPLY = 41, + FUSE_BATCH_FORGET = 42, + FUSE_FALLOCATE = 43, + FUSE_READDIRPLUS = 44, + FUSE_RENAME2 = 45, + FUSE_LSEEK = 46, + + /* CUSE specific operations */ + CUSE_INIT = 4096, +}; + +enum fuse_notify_code { + FUSE_NOTIFY_POLL = 1, + FUSE_NOTIFY_INVAL_INODE = 2, + FUSE_NOTIFY_INVAL_ENTRY = 3, + FUSE_NOTIFY_STORE = 4, + FUSE_NOTIFY_RETRIEVE = 5, + FUSE_NOTIFY_DELETE = 6, + FUSE_NOTIFY_CODE_MAX, +}; + +/* The read buffer is required to be at least 8k, but may be much larger */ +#define FUSE_MIN_READ_BUFFER 8192 + +#define FUSE_COMPAT_ENTRY_OUT_SIZE 120 + +struct fuse_entry_out { + uint64_t nodeid; /* Inode ID */ + uint64_t generation; /* Inode generation: nodeid:gen must + be unique for the fs's lifetime */ + uint64_t entry_valid; /* Cache timeout for the name */ + uint64_t attr_valid; /* Cache timeout for the attributes */ + uint32_t entry_valid_nsec; + uint32_t attr_valid_nsec; + struct fuse_attr attr; +}; + +struct fuse_forget_in { + uint64_t nlookup; +}; + +struct fuse_forget_one { + uint64_t nodeid; + uint64_t nlookup; +}; + +struct fuse_batch_forget_in { + uint32_t count; + uint32_t dummy; +}; + +struct fuse_getattr_in { + uint32_t getattr_flags; + uint32_t dummy; + uint64_t fh; +}; + +#define FUSE_COMPAT_ATTR_OUT_SIZE 96 + +struct fuse_attr_out { + uint64_t attr_valid; /* Cache timeout for the attributes */ + uint32_t attr_valid_nsec; + uint32_t dummy; + struct fuse_attr attr; +}; + +#define FUSE_COMPAT_MKNOD_IN_SIZE 8 + +struct fuse_mknod_in { + uint32_t mode; + uint32_t rdev; + uint32_t umask; + uint32_t padding; +}; + +struct fuse_mkdir_in { + uint32_t mode; + uint32_t umask; +}; + +struct fuse_rename_in { + uint64_t newdir; +}; + +struct fuse_rename2_in { + uint64_t newdir; + uint32_t flags; + uint32_t padding; +}; + +struct fuse_link_in { + uint64_t oldnodeid; +}; + +struct fuse_setattr_in { + uint32_t valid; + uint32_t padding; + uint64_t fh; + uint64_t size; + uint64_t lock_owner; + uint64_t atime; + uint64_t mtime; + uint64_t ctime; + uint32_t atimensec; + uint32_t mtimensec; + uint32_t ctimensec; + uint32_t mode; + uint32_t unused4; + uint32_t uid; + uint32_t gid; + uint32_t unused5; +}; + +struct fuse_open_in { + uint32_t flags; + uint32_t unused; +}; + +struct fuse_create_in { + uint32_t flags; + uint32_t mode; + uint32_t umask; + uint32_t padding; +}; + +struct fuse_open_out { + uint64_t fh; + uint32_t open_flags; + uint32_t padding; +}; + +struct fuse_release_in { + uint64_t fh; + uint32_t flags; + uint32_t release_flags; + uint64_t lock_owner; +}; + +struct fuse_flush_in { + uint64_t fh; + uint32_t unused; + uint32_t padding; + uint64_t lock_owner; +}; + +struct fuse_read_in { + uint64_t fh; + uint64_t offset; + uint32_t size; + uint32_t read_flags; + uint64_t lock_owner; + uint32_t flags; + uint32_t padding; +}; + +#define FUSE_COMPAT_WRITE_IN_SIZE 24 + +struct fuse_write_in { + uint64_t fh; + uint64_t offset; + uint32_t size; + uint32_t write_flags; + uint64_t lock_owner; + uint32_t flags; + uint32_t padding; +}; + +struct fuse_write_out { + uint32_t size; + uint32_t padding; +}; + +#define FUSE_COMPAT_STATFS_SIZE 48 + +struct fuse_statfs_out { + struct fuse_kstatfs st; +}; + +struct fuse_fsync_in { + uint64_t fh; + uint32_t fsync_flags; + uint32_t padding; +}; + +struct fuse_setxattr_in { + uint32_t size; + uint32_t flags; +}; + +struct fuse_getxattr_in { + uint32_t size; + uint32_t padding; +}; + +struct fuse_getxattr_out { + uint32_t size; + uint32_t padding; +}; + +struct fuse_lk_in { + uint64_t fh; + uint64_t owner; + struct fuse_file_lock lk; + uint32_t lk_flags; + uint32_t padding; +}; + +struct fuse_lk_out { + struct fuse_file_lock lk; +}; + +struct fuse_access_in { + uint32_t mask; + uint32_t padding; +}; + +struct fuse_init_in { + uint32_t major; + uint32_t minor; + uint32_t max_readahead; + uint32_t flags; +}; + +#define FUSE_COMPAT_INIT_OUT_SIZE 8 +#define FUSE_COMPAT_22_INIT_OUT_SIZE 24 + +struct fuse_init_out { + uint32_t major; + uint32_t minor; + uint32_t max_readahead; + uint32_t flags; + uint16_t max_background; + uint16_t congestion_threshold; + uint32_t max_write; + uint32_t time_gran; + uint32_t unused[9]; +}; + +#define CUSE_INIT_INFO_MAX 4096 + +struct cuse_init_in { + uint32_t major; + uint32_t minor; + uint32_t unused; + uint32_t flags; +}; + +struct cuse_init_out { + uint32_t major; + uint32_t minor; + uint32_t unused; + uint32_t flags; + uint32_t max_read; + uint32_t max_write; + uint32_t dev_major; /* chardev major */ + uint32_t dev_minor; /* chardev minor */ + uint32_t spare[10]; +}; + +struct fuse_interrupt_in { + uint64_t unique; +}; + +struct fuse_bmap_in { + uint64_t block; + uint32_t blocksize; + uint32_t padding; +}; + +struct fuse_bmap_out { + uint64_t block; +}; + +struct fuse_ioctl_in { + uint64_t fh; + uint32_t flags; + uint32_t cmd; + uint64_t arg; + uint32_t in_size; + uint32_t out_size; +}; + +struct fuse_ioctl_iovec { + uint64_t base; + uint64_t len; +}; + +struct fuse_ioctl_out { + int32_t result; + uint32_t flags; + uint32_t in_iovs; + uint32_t out_iovs; +}; + +struct fuse_poll_in { + uint64_t fh; + uint64_t kh; + uint32_t flags; + uint32_t events; +}; + +struct fuse_poll_out { + uint32_t revents; + uint32_t padding; +}; + +struct fuse_notify_poll_wakeup_out { + uint64_t kh; +}; + +struct fuse_fallocate_in { + uint64_t fh; + uint64_t offset; + uint64_t length; + uint32_t mode; + uint32_t padding; +}; + +struct fuse_in_header { + uint32_t len; + uint32_t opcode; + uint64_t unique; + uint64_t nodeid; + uint32_t uid; + uint32_t gid; + uint32_t pid; + uint32_t padding; +}; + +struct fuse_out_header { + uint32_t len; + int32_t error; + uint64_t unique; +}; + +struct fuse_dirent { + uint64_t ino; + uint64_t off; + uint32_t namelen; + uint32_t type; + char name[]; +}; + +#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) +#define FUSE_DIRENT_ALIGN(x) \ + (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1)) +#define FUSE_DIRENT_SIZE(d) \ + FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) + +struct fuse_direntplus { + struct fuse_entry_out entry_out; + struct fuse_dirent dirent; +}; + +#define FUSE_NAME_OFFSET_DIRENTPLUS \ + offsetof(struct fuse_direntplus, dirent.name) +#define FUSE_DIRENTPLUS_SIZE(d) \ + FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen) + +struct fuse_notify_inval_inode_out { + uint64_t ino; + int64_t off; + int64_t len; +}; + +struct fuse_notify_inval_entry_out { + uint64_t parent; + uint32_t namelen; + uint32_t padding; +}; + +struct fuse_notify_delete_out { + uint64_t parent; + uint64_t child; + uint32_t namelen; + uint32_t padding; +}; + +struct fuse_notify_store_out { + uint64_t nodeid; + uint64_t offset; + uint32_t size; + uint32_t padding; +}; + +struct fuse_notify_retrieve_out { + uint64_t notify_unique; + uint64_t nodeid; + uint64_t offset; + uint32_t size; + uint32_t padding; +}; + +/* Matches the size of fuse_write_in */ +struct fuse_notify_retrieve_in { + uint64_t dummy1; + uint64_t offset; + uint32_t size; + uint32_t dummy2; + uint64_t dummy3; + uint64_t dummy4; +}; + +/* Device ioctls: */ +#define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t) + +struct fuse_lseek_in { + uint64_t fh; + uint64_t offset; + uint32_t whence; + uint32_t padding; +}; + +struct fuse_lseek_out { + uint64_t offset; +}; + +#endif /* _LINUX_FUSE_H */ diff --git a/lib_gen/profuse_typegen.ml b/lib_gen/profuse_typegen.ml index 12061ea..468cf3f 100644 --- a/lib_gen/profuse_typegen.ml +++ b/lib_gen/profuse_typegen.ml @@ -44,6 +44,7 @@ let fuse_versions : (string * (string * (module Cstubs.Types.BINDINGS))) list = "7_21", ("fuse_kernel.h.7_21", (module Profuse_types_7_21.C)); "7_22", ("fuse_kernel.h.7_22", (module Profuse_types_7_21.C)); "7_23", ("fuse_kernel.h.7_23", (module Profuse_types_7_23.C)); + "7_24", ("fuse_kernel.h.7_24", (module Profuse_types_7_24.C)); ] let resolve_version : string -> (string * (module Cstubs.Types.BINDINGS)) = diff --git a/lib_gen/profuse_types_7_24.ml b/lib_gen/profuse_types_7_24.ml new file mode 100644 index 0000000..3902584 --- /dev/null +++ b/lib_gen/profuse_types_7_24.ml @@ -0,0 +1,129 @@ +(* + * Copyright (c) 2018 Docker Inc + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + *) + +module C(F: Cstubs.Types.TYPE) = struct + open F + + type 'a structure = 'a Ctypes_static.structure + + (* Build the types for FUSE 7.23, but don't seal the structs *) + module Version_7_23 = Profuse_types_7_23.C + (struct + include F + let seal _ = () + end) + + (* Extend and seal the structs *) + module Struct = struct + module V_7_23 = Version_7_23.Struct + module Kstatfs = struct include V_7_23.Kstatfs let () = seal t end + module File_lock = struct include V_7_23.File_lock let () = seal t end + module Dirent = struct include V_7_23.Dirent let () = seal t end + module Attr = struct include V_7_23.Attr let () = seal t end + module Forget_one = struct include V_7_23.Forget_one let () = seal t end + module Ioctl_iovec = struct include V_7_23.Ioctl_iovec let () = seal t end + module Direntplus = struct include V_7_23.Direntplus let () = seal t end + end + + module Out = struct + module V_7_23 = Version_7_23.Out + module Hdr = struct include V_7_23.Hdr let () = seal t end + module Write = struct include V_7_23.Write let () = seal t end + module Open = struct include V_7_23.Open let () = seal t end + module Entry = struct include V_7_23.Entry let () = seal t end + module Attr = struct include V_7_23.Attr let () = seal t end + module Statfs = struct include V_7_23.Statfs let () = seal t end + module Getxattr = struct include V_7_23.Getxattr let () = seal t end + module Lk = struct include V_7_23.Lk let () = seal t end + module Bmap = struct include V_7_23.Bmap let () = seal t end + module Ioctl = struct include V_7_23.Ioctl let () = seal t end + module Poll = struct include V_7_23.Poll let () = seal t end + module Notify_poll_wakeup = struct include V_7_23.Notify_poll_wakeup let () = seal t end + module Cuse_init = struct include V_7_23.Cuse_init let () = seal t end + module Notify_inval_inode = struct include V_7_23.Notify_inval_inode let () = seal t end + module Notify_inval_entry = struct include V_7_23.Notify_inval_entry let () = seal t end + module Notify_delete = struct include V_7_23.Notify_delete let () = seal t end + module Notify_store = struct include V_7_23.Notify_store let () = seal t end + module Notify_retrieve = struct include V_7_23.Notify_retrieve let () = seal t end + module Init = struct include V_7_23.Init let () = seal t end + module Lseek = struct + type t + let t : t structure typ = structure "fuse_lseek_out" + let ( -:* ) s x = field t s x + let offset = "offset" -:* uint64_t + let () = seal t + end + end + + module In = struct + module V_7_23 = Version_7_23.In + module Hdr = struct include V_7_23.Hdr let () = seal t end + module Open = struct include V_7_23.Open let () = seal t end + module Release = struct include V_7_23.Release let () = seal t end + module Access = struct include V_7_23.Access let () = seal t end + module Forget = struct include V_7_23.Forget let () = seal t end + module Flush = struct include V_7_23.Flush let () = seal t end + module Create = struct include V_7_23.Create let () = seal t end + module Mknod = struct include V_7_23.Mknod let () = seal t end + module Mkdir = struct include V_7_23.Mkdir let () = seal t end + module Rename = struct include V_7_23.Rename let () = seal t end + module Link = struct include V_7_23.Link let () = seal t end + module Fsync = struct include V_7_23.Fsync let () = seal t end + module Interrupt = struct include V_7_23.Interrupt let () = seal t end + module Bmap = struct include V_7_23.Bmap let () = seal t end + module Getxattr = struct include V_7_23.Getxattr let () = seal t end + module Setxattr = struct include V_7_23.Setxattr let () = seal t end + module Read = struct include V_7_23.Read let () = seal t end + module Write = struct include V_7_23.Write let () = seal t end + module Lk = struct include V_7_23.Lk let () = seal t end + module Getattr = struct include V_7_23.Getattr let () = seal t end + module Ioctl = struct include V_7_23.Ioctl let () = seal t end + module Poll = struct include V_7_23.Poll let () = seal t end + module Cuse_init = struct include V_7_23.Cuse_init let () = seal t end + module Notify_retrieve = struct include V_7_23.Notify_retrieve let () = seal t end + module Batch_forget = struct include V_7_23.Batch_forget let () = seal t end + module Fallocate = struct include V_7_23.Fallocate let () = seal t end + module Opcode = + struct + include (V_7_23.Opcode + : module type of V_7_23.Opcode + with type t := V_7_23.Opcode.t) + let fuse_lseek = constant "FUSE_LSEEK" uint32_t + + type t = [ V_7_23.Opcode.t + | `FUSE_LSEEK ] + + let enum_values = + (`FUSE_LSEEK, fuse_lseek) :: + (V_7_23.Opcode.enum_values :> (t * _) list) + end + + module Init = struct include V_7_23.Init let () = seal t end + module Setattr = struct include V_7_23.Setattr let () = seal t end + module Rename2 = struct include V_7_23.Rename2 let () = seal t end + module Lseek = struct + type t + let t : t structure typ = structure "fuse_lseek_in" + let ( -:* ) s x = field t s x + let fh = "fh" -:* uint64_t + let offset = "offset" -:* uint64_t + let whence = "whence" -:* uint32_t + let padding = "padding" -:* uint32_t + let () = seal t + end + end +end From 5d994b12e8303cfefeb73522829b797fabe32cfe Mon Sep 17 00:00:00 2001 From: David Scott Date: Thu, 25 Jan 2018 16:59:53 +0000 Subject: [PATCH 2/7] Add support for FUSE 7.25 Signed-off-by: David Scott --- lib/profuse_.mllib | 2 + lib_gen/fuse_kernel.h.7_25 | 781 ++++++++++++++++++++++++++++++++++ lib_gen/profuse_typegen.ml | 1 + lib_gen/profuse_types_7_25.ml | 110 +++++ 4 files changed, 894 insertions(+) create mode 100644 lib_gen/fuse_kernel.h.7_25 create mode 100644 lib_gen/profuse_types_7_25.ml diff --git a/lib/profuse_.mllib b/lib/profuse_.mllib index c6642c8..d80f2bb 100644 --- a/lib/profuse_.mllib +++ b/lib/profuse_.mllib @@ -17,6 +17,7 @@ Profuse_types_7_21 Profuse_types_7_22 Profuse_types_7_23 Profuse_types_7_24 +Profuse_types_7_25 Profuse_types_detected_7_8 Profuse_types_detected_7_9 Profuse_types_detected_7_10 @@ -34,6 +35,7 @@ Profuse_types_detected_7_21 Profuse_types_detected_7_22 Profuse_types_detected_7_23 Profuse_types_detected_7_24 +Profuse_types_detected_7_25 Profuse_signatures Profuse_7_8 Profuse_7_23 diff --git a/lib_gen/fuse_kernel.h.7_25 b/lib_gen/fuse_kernel.h.7_25 new file mode 100644 index 0000000..27e1736 --- /dev/null +++ b/lib_gen/fuse_kernel.h.7_25 @@ -0,0 +1,781 @@ +/* + This file defines the kernel interface of FUSE + Copyright (C) 2001-2008 Miklos Szeredi + + This program can be distributed under the terms of the GNU GPL. + See the file COPYING. + + This -- and only this -- header file may also be distributed under + the terms of the BSD Licence as follows: + + Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +/* + * This file defines the kernel interface of FUSE + * + * Protocol changelog: + * + * 7.9: + * - new fuse_getattr_in input argument of GETATTR + * - add lk_flags in fuse_lk_in + * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in + * - add blksize field to fuse_attr + * - add file flags field to fuse_read_in and fuse_write_in + * + * 7.10 + * - add nonseekable open flag + * + * 7.11 + * - add IOCTL message + * - add unsolicited notification support + * - add POLL message and NOTIFY_POLL notification + * + * 7.12 + * - add umask flag to input argument of open, mknod and mkdir + * - add notification messages for invalidation of inodes and + * directory entries + * + * 7.13 + * - make max number of background requests and congestion threshold + * tunables + * + * 7.14 + * - add splice support to fuse device + * + * 7.15 + * - add store notify + * - add retrieve notify + * + * 7.16 + * - add BATCH_FORGET request + * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct + * fuse_ioctl_iovec' instead of ambiguous 'struct iovec' + * - add FUSE_IOCTL_32BIT flag + * + * 7.17 + * - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK + * + * 7.18 + * - add FUSE_IOCTL_DIR flag + * - add FUSE_NOTIFY_DELETE + * + * 7.19 + * - add FUSE_FALLOCATE + * + * 7.20 + * - add FUSE_AUTO_INVAL_DATA + * + * 7.21 + * - add FUSE_READDIRPLUS + * - send the requested events in POLL request + * + * 7.22 + * - add FUSE_ASYNC_DIO + * + * 7.23 + * - add FUSE_WRITEBACK_CACHE + * - add time_gran to fuse_init_out + * - add reserved space to fuse_init_out + * - add FATTR_CTIME + * - add ctime and ctimensec to fuse_setattr_in + * - add FUSE_RENAME2 request + * - add FUSE_NO_OPEN_SUPPORT flag + * + * 7.24 + * - add FUSE_LSEEK for SEEK_HOLE and SEEK_DATA support + * + * 7.25 + * - add FUSE_PARALLEL_DIROPS + */ + +#ifndef _LINUX_FUSE_H +#define _LINUX_FUSE_H + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +/* + * Version negotiation: + * + * Both the kernel and userspace send the version they support in the + * INIT request and reply respectively. + * + * If the major versions match then both shall use the smallest + * of the two minor versions for communication. + * + * If the kernel supports a larger major version, then userspace shall + * reply with the major version it supports, ignore the rest of the + * INIT message and expect a new INIT message from the kernel with a + * matching major version. + * + * If the library supports a larger major version, then it shall fall + * back to the major protocol version sent by the kernel for + * communication and reply with that major version (and an arbitrary + * supported minor version). + */ + +/** Version number of this interface */ +#define FUSE_KERNEL_VERSION 7 + +/** Minor version number of this interface */ +#define FUSE_KERNEL_MINOR_VERSION 25 + +/** The node ID of the root inode */ +#define FUSE_ROOT_ID 1 + +/* Make sure all structures are padded to 64bit boundary, so 32bit + userspace works under 64bit kernels */ + +struct fuse_attr { + uint64_t ino; + uint64_t size; + uint64_t blocks; + uint64_t atime; + uint64_t mtime; + uint64_t ctime; + uint32_t atimensec; + uint32_t mtimensec; + uint32_t ctimensec; + uint32_t mode; + uint32_t nlink; + uint32_t uid; + uint32_t gid; + uint32_t rdev; + uint32_t blksize; + uint32_t padding; +}; + +struct fuse_kstatfs { + uint64_t blocks; + uint64_t bfree; + uint64_t bavail; + uint64_t files; + uint64_t ffree; + uint32_t bsize; + uint32_t namelen; + uint32_t frsize; + uint32_t padding; + uint32_t spare[6]; +}; + +struct fuse_file_lock { + uint64_t start; + uint64_t end; + uint32_t type; + uint32_t pid; /* tgid */ +}; + +/** + * Bitmasks for fuse_setattr_in.valid + */ +#define FATTR_MODE (1 << 0) +#define FATTR_UID (1 << 1) +#define FATTR_GID (1 << 2) +#define FATTR_SIZE (1 << 3) +#define FATTR_ATIME (1 << 4) +#define FATTR_MTIME (1 << 5) +#define FATTR_FH (1 << 6) +#define FATTR_ATIME_NOW (1 << 7) +#define FATTR_MTIME_NOW (1 << 8) +#define FATTR_LOCKOWNER (1 << 9) +#define FATTR_CTIME (1 << 10) + +/** + * Flags returned by the OPEN request + * + * FOPEN_DIRECT_IO: bypass page cache for this open file + * FOPEN_KEEP_CACHE: don't invalidate the data cache on open + * FOPEN_NONSEEKABLE: the file is not seekable + */ +#define FOPEN_DIRECT_IO (1 << 0) +#define FOPEN_KEEP_CACHE (1 << 1) +#define FOPEN_NONSEEKABLE (1 << 2) + +/** + * INIT request/reply flags + * + * FUSE_ASYNC_READ: asynchronous read requests + * FUSE_POSIX_LOCKS: remote locking for POSIX file locks + * FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported) + * FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem + * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".." + * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB + * FUSE_DONT_MASK: don't apply umask to file mode on create operations + * FUSE_SPLICE_WRITE: kernel supports splice write on the device + * FUSE_SPLICE_MOVE: kernel supports splice move on the device + * FUSE_SPLICE_READ: kernel supports splice read on the device + * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks + * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories + * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages + * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one) + * FUSE_READDIRPLUS_AUTO: adaptive readdirplus + * FUSE_ASYNC_DIO: asynchronous direct I/O submission + * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes + * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens + * FUSE_PARALLEL_DIROPS: allow parallel lookups and readdir + */ +#define FUSE_ASYNC_READ (1 << 0) +#define FUSE_POSIX_LOCKS (1 << 1) +#define FUSE_FILE_OPS (1 << 2) +#define FUSE_ATOMIC_O_TRUNC (1 << 3) +#define FUSE_EXPORT_SUPPORT (1 << 4) +#define FUSE_BIG_WRITES (1 << 5) +#define FUSE_DONT_MASK (1 << 6) +#define FUSE_SPLICE_WRITE (1 << 7) +#define FUSE_SPLICE_MOVE (1 << 8) +#define FUSE_SPLICE_READ (1 << 9) +#define FUSE_FLOCK_LOCKS (1 << 10) +#define FUSE_HAS_IOCTL_DIR (1 << 11) +#define FUSE_AUTO_INVAL_DATA (1 << 12) +#define FUSE_DO_READDIRPLUS (1 << 13) +#define FUSE_READDIRPLUS_AUTO (1 << 14) +#define FUSE_ASYNC_DIO (1 << 15) +#define FUSE_WRITEBACK_CACHE (1 << 16) +#define FUSE_NO_OPEN_SUPPORT (1 << 17) +#define FUSE_PARALLEL_DIROPS (1 << 18) + +/** + * CUSE INIT request/reply flags + * + * CUSE_UNRESTRICTED_IOCTL: use unrestricted ioctl + */ +#define CUSE_UNRESTRICTED_IOCTL (1 << 0) + +/** + * Release flags + */ +#define FUSE_RELEASE_FLUSH (1 << 0) +#define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1) + +/** + * Getattr flags + */ +#define FUSE_GETATTR_FH (1 << 0) + +/** + * Lock flags + */ +#define FUSE_LK_FLOCK (1 << 0) + +/** + * WRITE flags + * + * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed + * FUSE_WRITE_LOCKOWNER: lock_owner field is valid + */ +#define FUSE_WRITE_CACHE (1 << 0) +#define FUSE_WRITE_LOCKOWNER (1 << 1) + +/** + * Read flags + */ +#define FUSE_READ_LOCKOWNER (1 << 1) + +/** + * Ioctl flags + * + * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine + * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed + * FUSE_IOCTL_RETRY: retry with new iovecs + * FUSE_IOCTL_32BIT: 32bit ioctl + * FUSE_IOCTL_DIR: is a directory + * + * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs + */ +#define FUSE_IOCTL_COMPAT (1 << 0) +#define FUSE_IOCTL_UNRESTRICTED (1 << 1) +#define FUSE_IOCTL_RETRY (1 << 2) +#define FUSE_IOCTL_32BIT (1 << 3) +#define FUSE_IOCTL_DIR (1 << 4) + +#define FUSE_IOCTL_MAX_IOV 256 + +/** + * Poll flags + * + * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify + */ +#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0) + +enum fuse_opcode { + FUSE_LOOKUP = 1, + FUSE_FORGET = 2, /* no reply */ + FUSE_GETATTR = 3, + FUSE_SETATTR = 4, + FUSE_READLINK = 5, + FUSE_SYMLINK = 6, + FUSE_MKNOD = 8, + FUSE_MKDIR = 9, + FUSE_UNLINK = 10, + FUSE_RMDIR = 11, + FUSE_RENAME = 12, + FUSE_LINK = 13, + FUSE_OPEN = 14, + FUSE_READ = 15, + FUSE_WRITE = 16, + FUSE_STATFS = 17, + FUSE_RELEASE = 18, + FUSE_FSYNC = 20, + FUSE_SETXATTR = 21, + FUSE_GETXATTR = 22, + FUSE_LISTXATTR = 23, + FUSE_REMOVEXATTR = 24, + FUSE_FLUSH = 25, + FUSE_INIT = 26, + FUSE_OPENDIR = 27, + FUSE_READDIR = 28, + FUSE_RELEASEDIR = 29, + FUSE_FSYNCDIR = 30, + FUSE_GETLK = 31, + FUSE_SETLK = 32, + FUSE_SETLKW = 33, + FUSE_ACCESS = 34, + FUSE_CREATE = 35, + FUSE_INTERRUPT = 36, + FUSE_BMAP = 37, + FUSE_DESTROY = 38, + FUSE_IOCTL = 39, + FUSE_POLL = 40, + FUSE_NOTIFY_REPLY = 41, + FUSE_BATCH_FORGET = 42, + FUSE_FALLOCATE = 43, + FUSE_READDIRPLUS = 44, + FUSE_RENAME2 = 45, + FUSE_LSEEK = 46, + + /* CUSE specific operations */ + CUSE_INIT = 4096, +}; + +enum fuse_notify_code { + FUSE_NOTIFY_POLL = 1, + FUSE_NOTIFY_INVAL_INODE = 2, + FUSE_NOTIFY_INVAL_ENTRY = 3, + FUSE_NOTIFY_STORE = 4, + FUSE_NOTIFY_RETRIEVE = 5, + FUSE_NOTIFY_DELETE = 6, + FUSE_NOTIFY_CODE_MAX, +}; + +/* The read buffer is required to be at least 8k, but may be much larger */ +#define FUSE_MIN_READ_BUFFER 8192 + +#define FUSE_COMPAT_ENTRY_OUT_SIZE 120 + +struct fuse_entry_out { + uint64_t nodeid; /* Inode ID */ + uint64_t generation; /* Inode generation: nodeid:gen must + be unique for the fs's lifetime */ + uint64_t entry_valid; /* Cache timeout for the name */ + uint64_t attr_valid; /* Cache timeout for the attributes */ + uint32_t entry_valid_nsec; + uint32_t attr_valid_nsec; + struct fuse_attr attr; +}; + +struct fuse_forget_in { + uint64_t nlookup; +}; + +struct fuse_forget_one { + uint64_t nodeid; + uint64_t nlookup; +}; + +struct fuse_batch_forget_in { + uint32_t count; + uint32_t dummy; +}; + +struct fuse_getattr_in { + uint32_t getattr_flags; + uint32_t dummy; + uint64_t fh; +}; + +#define FUSE_COMPAT_ATTR_OUT_SIZE 96 + +struct fuse_attr_out { + uint64_t attr_valid; /* Cache timeout for the attributes */ + uint32_t attr_valid_nsec; + uint32_t dummy; + struct fuse_attr attr; +}; + +#define FUSE_COMPAT_MKNOD_IN_SIZE 8 + +struct fuse_mknod_in { + uint32_t mode; + uint32_t rdev; + uint32_t umask; + uint32_t padding; +}; + +struct fuse_mkdir_in { + uint32_t mode; + uint32_t umask; +}; + +struct fuse_rename_in { + uint64_t newdir; +}; + +struct fuse_rename2_in { + uint64_t newdir; + uint32_t flags; + uint32_t padding; +}; + +struct fuse_link_in { + uint64_t oldnodeid; +}; + +struct fuse_setattr_in { + uint32_t valid; + uint32_t padding; + uint64_t fh; + uint64_t size; + uint64_t lock_owner; + uint64_t atime; + uint64_t mtime; + uint64_t ctime; + uint32_t atimensec; + uint32_t mtimensec; + uint32_t ctimensec; + uint32_t mode; + uint32_t unused4; + uint32_t uid; + uint32_t gid; + uint32_t unused5; +}; + +struct fuse_open_in { + uint32_t flags; + uint32_t unused; +}; + +struct fuse_create_in { + uint32_t flags; + uint32_t mode; + uint32_t umask; + uint32_t padding; +}; + +struct fuse_open_out { + uint64_t fh; + uint32_t open_flags; + uint32_t padding; +}; + +struct fuse_release_in { + uint64_t fh; + uint32_t flags; + uint32_t release_flags; + uint64_t lock_owner; +}; + +struct fuse_flush_in { + uint64_t fh; + uint32_t unused; + uint32_t padding; + uint64_t lock_owner; +}; + +struct fuse_read_in { + uint64_t fh; + uint64_t offset; + uint32_t size; + uint32_t read_flags; + uint64_t lock_owner; + uint32_t flags; + uint32_t padding; +}; + +#define FUSE_COMPAT_WRITE_IN_SIZE 24 + +struct fuse_write_in { + uint64_t fh; + uint64_t offset; + uint32_t size; + uint32_t write_flags; + uint64_t lock_owner; + uint32_t flags; + uint32_t padding; +}; + +struct fuse_write_out { + uint32_t size; + uint32_t padding; +}; + +#define FUSE_COMPAT_STATFS_SIZE 48 + +struct fuse_statfs_out { + struct fuse_kstatfs st; +}; + +struct fuse_fsync_in { + uint64_t fh; + uint32_t fsync_flags; + uint32_t padding; +}; + +struct fuse_setxattr_in { + uint32_t size; + uint32_t flags; +}; + +struct fuse_getxattr_in { + uint32_t size; + uint32_t padding; +}; + +struct fuse_getxattr_out { + uint32_t size; + uint32_t padding; +}; + +struct fuse_lk_in { + uint64_t fh; + uint64_t owner; + struct fuse_file_lock lk; + uint32_t lk_flags; + uint32_t padding; +}; + +struct fuse_lk_out { + struct fuse_file_lock lk; +}; + +struct fuse_access_in { + uint32_t mask; + uint32_t padding; +}; + +struct fuse_init_in { + uint32_t major; + uint32_t minor; + uint32_t max_readahead; + uint32_t flags; +}; + +#define FUSE_COMPAT_INIT_OUT_SIZE 8 +#define FUSE_COMPAT_22_INIT_OUT_SIZE 24 + +struct fuse_init_out { + uint32_t major; + uint32_t minor; + uint32_t max_readahead; + uint32_t flags; + uint16_t max_background; + uint16_t congestion_threshold; + uint32_t max_write; + uint32_t time_gran; + uint32_t unused[9]; +}; + +#define CUSE_INIT_INFO_MAX 4096 + +struct cuse_init_in { + uint32_t major; + uint32_t minor; + uint32_t unused; + uint32_t flags; +}; + +struct cuse_init_out { + uint32_t major; + uint32_t minor; + uint32_t unused; + uint32_t flags; + uint32_t max_read; + uint32_t max_write; + uint32_t dev_major; /* chardev major */ + uint32_t dev_minor; /* chardev minor */ + uint32_t spare[10]; +}; + +struct fuse_interrupt_in { + uint64_t unique; +}; + +struct fuse_bmap_in { + uint64_t block; + uint32_t blocksize; + uint32_t padding; +}; + +struct fuse_bmap_out { + uint64_t block; +}; + +struct fuse_ioctl_in { + uint64_t fh; + uint32_t flags; + uint32_t cmd; + uint64_t arg; + uint32_t in_size; + uint32_t out_size; +}; + +struct fuse_ioctl_iovec { + uint64_t base; + uint64_t len; +}; + +struct fuse_ioctl_out { + int32_t result; + uint32_t flags; + uint32_t in_iovs; + uint32_t out_iovs; +}; + +struct fuse_poll_in { + uint64_t fh; + uint64_t kh; + uint32_t flags; + uint32_t events; +}; + +struct fuse_poll_out { + uint32_t revents; + uint32_t padding; +}; + +struct fuse_notify_poll_wakeup_out { + uint64_t kh; +}; + +struct fuse_fallocate_in { + uint64_t fh; + uint64_t offset; + uint64_t length; + uint32_t mode; + uint32_t padding; +}; + +struct fuse_in_header { + uint32_t len; + uint32_t opcode; + uint64_t unique; + uint64_t nodeid; + uint32_t uid; + uint32_t gid; + uint32_t pid; + uint32_t padding; +}; + +struct fuse_out_header { + uint32_t len; + int32_t error; + uint64_t unique; +}; + +struct fuse_dirent { + uint64_t ino; + uint64_t off; + uint32_t namelen; + uint32_t type; + char name[]; +}; + +#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) +#define FUSE_DIRENT_ALIGN(x) \ + (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1)) +#define FUSE_DIRENT_SIZE(d) \ + FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) + +struct fuse_direntplus { + struct fuse_entry_out entry_out; + struct fuse_dirent dirent; +}; + +#define FUSE_NAME_OFFSET_DIRENTPLUS \ + offsetof(struct fuse_direntplus, dirent.name) +#define FUSE_DIRENTPLUS_SIZE(d) \ + FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen) + +struct fuse_notify_inval_inode_out { + uint64_t ino; + int64_t off; + int64_t len; +}; + +struct fuse_notify_inval_entry_out { + uint64_t parent; + uint32_t namelen; + uint32_t padding; +}; + +struct fuse_notify_delete_out { + uint64_t parent; + uint64_t child; + uint32_t namelen; + uint32_t padding; +}; + +struct fuse_notify_store_out { + uint64_t nodeid; + uint64_t offset; + uint32_t size; + uint32_t padding; +}; + +struct fuse_notify_retrieve_out { + uint64_t notify_unique; + uint64_t nodeid; + uint64_t offset; + uint32_t size; + uint32_t padding; +}; + +/* Matches the size of fuse_write_in */ +struct fuse_notify_retrieve_in { + uint64_t dummy1; + uint64_t offset; + uint32_t size; + uint32_t dummy2; + uint64_t dummy3; + uint64_t dummy4; +}; + +/* Device ioctls: */ +#define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t) + +struct fuse_lseek_in { + uint64_t fh; + uint64_t offset; + uint32_t whence; + uint32_t padding; +}; + +struct fuse_lseek_out { + uint64_t offset; +}; + +#endif /* _LINUX_FUSE_H */ diff --git a/lib_gen/profuse_typegen.ml b/lib_gen/profuse_typegen.ml index 468cf3f..9317396 100644 --- a/lib_gen/profuse_typegen.ml +++ b/lib_gen/profuse_typegen.ml @@ -45,6 +45,7 @@ let fuse_versions : (string * (string * (module Cstubs.Types.BINDINGS))) list = "7_22", ("fuse_kernel.h.7_22", (module Profuse_types_7_21.C)); "7_23", ("fuse_kernel.h.7_23", (module Profuse_types_7_23.C)); "7_24", ("fuse_kernel.h.7_24", (module Profuse_types_7_24.C)); + "7_25", ("fuse_kernel.h.7_25", (module Profuse_types_7_25.C)); ] let resolve_version : string -> (string * (module Cstubs.Types.BINDINGS)) = diff --git a/lib_gen/profuse_types_7_25.ml b/lib_gen/profuse_types_7_25.ml new file mode 100644 index 0000000..72a10d0 --- /dev/null +++ b/lib_gen/profuse_types_7_25.ml @@ -0,0 +1,110 @@ +(* + * Copyright (c) 2018 Docker Inc + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + *) + +module C(F: Cstubs.Types.TYPE) = struct + open F + + type 'a structure = 'a Ctypes_static.structure + + (* Build the types for FUSE 7.25, but don't seal the structs *) + module Version_7_24 = Profuse_types_7_24.C + (struct + include F + let seal _ = () + end) + + (* Extend and seal the structs *) + module Struct = struct + module V_7_24 = Version_7_24.Struct + module Kstatfs = struct include V_7_24.Kstatfs let () = seal t end + module File_lock = struct include V_7_24.File_lock let () = seal t end + module Dirent = struct include V_7_24.Dirent let () = seal t end + module Attr = struct include V_7_24.Attr let () = seal t end + module Forget_one = struct include V_7_24.Forget_one let () = seal t end + module Ioctl_iovec = struct include V_7_24.Ioctl_iovec let () = seal t end + module Direntplus = struct include V_7_24.Direntplus let () = seal t end + end + + module Out = struct + module V_7_24 = Version_7_24.Out + module Hdr = struct include V_7_24.Hdr let () = seal t end + module Write = struct include V_7_24.Write let () = seal t end + module Open = struct include V_7_24.Open let () = seal t end + module Entry = struct include V_7_24.Entry let () = seal t end + module Attr = struct include V_7_24.Attr let () = seal t end + module Statfs = struct include V_7_24.Statfs let () = seal t end + module Getxattr = struct include V_7_24.Getxattr let () = seal t end + module Lk = struct include V_7_24.Lk let () = seal t end + module Bmap = struct include V_7_24.Bmap let () = seal t end + module Ioctl = struct include V_7_24.Ioctl let () = seal t end + module Poll = struct include V_7_24.Poll let () = seal t end + module Notify_poll_wakeup = struct include V_7_24.Notify_poll_wakeup let () = seal t end + module Cuse_init = struct include V_7_24.Cuse_init let () = seal t end + module Notify_inval_inode = struct include V_7_24.Notify_inval_inode let () = seal t end + module Notify_inval_entry = struct include V_7_24.Notify_inval_entry let () = seal t end + module Notify_delete = struct include V_7_24.Notify_delete let () = seal t end + module Notify_store = struct include V_7_24.Notify_store let () = seal t end + module Notify_retrieve = struct include V_7_24.Notify_retrieve let () = seal t end + module Init = struct include V_7_24.Init let () = seal t end + module Lseek = struct include V_7_24.Lseek let () = seal t end + + end + + module In = struct + module V_7_24 = Version_7_24.In + module Hdr = struct include V_7_24.Hdr let () = seal t end + module Open = struct include V_7_24.Open let () = seal t end + module Release = struct include V_7_24.Release let () = seal t end + module Access = struct include V_7_24.Access let () = seal t end + module Forget = struct include V_7_24.Forget let () = seal t end + module Flush = struct include V_7_24.Flush let () = seal t end + module Create = struct include V_7_24.Create let () = seal t end + module Mknod = struct include V_7_24.Mknod let () = seal t end + module Mkdir = struct include V_7_24.Mkdir let () = seal t end + module Rename = struct include V_7_24.Rename let () = seal t end + module Link = struct include V_7_24.Link let () = seal t end + module Fsync = struct include V_7_24.Fsync let () = seal t end + module Interrupt = struct include V_7_24.Interrupt let () = seal t end + module Bmap = struct include V_7_24.Bmap let () = seal t end + module Getxattr = struct include V_7_24.Getxattr let () = seal t end + module Setxattr = struct include V_7_24.Setxattr let () = seal t end + module Read = struct include V_7_24.Read let () = seal t end + module Write = struct include V_7_24.Write let () = seal t end + module Lk = struct include V_7_24.Lk let () = seal t end + module Getattr = struct include V_7_24.Getattr let () = seal t end + module Ioctl = struct include V_7_24.Ioctl let () = seal t end + module Poll = struct include V_7_24.Poll let () = seal t end + module Cuse_init = struct include V_7_24.Cuse_init let () = seal t end + module Notify_retrieve = struct include V_7_24.Notify_retrieve let () = seal t end + module Batch_forget = struct include V_7_24.Batch_forget let () = seal t end + module Fallocate = struct include V_7_24.Fallocate let () = seal t end + module Opcode = V_7_24.Opcode + + module Init = struct + module Flags = struct + include V_7_24.Init.Flags + let fuse_parallel_dirops = constant "FUSE_PARALLEL_DIROPS" t + end + include (V_7_24.Init + : module type of V_7_24.Init with module Flags := Flags) + let () = seal t + end + module Setattr = struct include V_7_24.Setattr let () = seal t end + module Rename2 = struct include V_7_24.Rename2 let () = seal t end + module Lseek = struct include V_7_24.Lseek let () = seal t end + end +end From a900f90a3ca7d7e5a590dad30391c53de44daeae Mon Sep 17 00:00:00 2001 From: David Scott Date: Thu, 25 Jan 2018 17:05:09 +0000 Subject: [PATCH 3/7] Add support for FUSE 7.26 Signed-off-by: David Scott --- lib/profuse_.mllib | 2 + lib_gen/fuse_kernel.h.7_26 | 790 ++++++++++++++++++++++++++++++++++ lib_gen/profuse_typegen.ml | 1 + lib_gen/profuse_types_7_26.ml | 112 +++++ 4 files changed, 905 insertions(+) create mode 100644 lib_gen/fuse_kernel.h.7_26 create mode 100644 lib_gen/profuse_types_7_26.ml diff --git a/lib/profuse_.mllib b/lib/profuse_.mllib index d80f2bb..435b521 100644 --- a/lib/profuse_.mllib +++ b/lib/profuse_.mllib @@ -18,6 +18,7 @@ Profuse_types_7_22 Profuse_types_7_23 Profuse_types_7_24 Profuse_types_7_25 +Profuse_types_7_26 Profuse_types_detected_7_8 Profuse_types_detected_7_9 Profuse_types_detected_7_10 @@ -36,6 +37,7 @@ Profuse_types_detected_7_22 Profuse_types_detected_7_23 Profuse_types_detected_7_24 Profuse_types_detected_7_25 +Profuse_types_detected_7_26 Profuse_signatures Profuse_7_8 Profuse_7_23 diff --git a/lib_gen/fuse_kernel.h.7_26 b/lib_gen/fuse_kernel.h.7_26 new file mode 100644 index 0000000..4b5001c --- /dev/null +++ b/lib_gen/fuse_kernel.h.7_26 @@ -0,0 +1,790 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ +/* + This file defines the kernel interface of FUSE + Copyright (C) 2001-2008 Miklos Szeredi + + This program can be distributed under the terms of the GNU GPL. + See the file COPYING. + + This -- and only this -- header file may also be distributed under + the terms of the BSD Licence as follows: + + Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +/* + * This file defines the kernel interface of FUSE + * + * Protocol changelog: + * + * 7.9: + * - new fuse_getattr_in input argument of GETATTR + * - add lk_flags in fuse_lk_in + * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in + * - add blksize field to fuse_attr + * - add file flags field to fuse_read_in and fuse_write_in + * + * 7.10 + * - add nonseekable open flag + * + * 7.11 + * - add IOCTL message + * - add unsolicited notification support + * - add POLL message and NOTIFY_POLL notification + * + * 7.12 + * - add umask flag to input argument of open, mknod and mkdir + * - add notification messages for invalidation of inodes and + * directory entries + * + * 7.13 + * - make max number of background requests and congestion threshold + * tunables + * + * 7.14 + * - add splice support to fuse device + * + * 7.15 + * - add store notify + * - add retrieve notify + * + * 7.16 + * - add BATCH_FORGET request + * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct + * fuse_ioctl_iovec' instead of ambiguous 'struct iovec' + * - add FUSE_IOCTL_32BIT flag + * + * 7.17 + * - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK + * + * 7.18 + * - add FUSE_IOCTL_DIR flag + * - add FUSE_NOTIFY_DELETE + * + * 7.19 + * - add FUSE_FALLOCATE + * + * 7.20 + * - add FUSE_AUTO_INVAL_DATA + * + * 7.21 + * - add FUSE_READDIRPLUS + * - send the requested events in POLL request + * + * 7.22 + * - add FUSE_ASYNC_DIO + * + * 7.23 + * - add FUSE_WRITEBACK_CACHE + * - add time_gran to fuse_init_out + * - add reserved space to fuse_init_out + * - add FATTR_CTIME + * - add ctime and ctimensec to fuse_setattr_in + * - add FUSE_RENAME2 request + * - add FUSE_NO_OPEN_SUPPORT flag + * + * 7.24 + * - add FUSE_LSEEK for SEEK_HOLE and SEEK_DATA support + * + * 7.25 + * - add FUSE_PARALLEL_DIROPS + * + * 7.26 + * - add FUSE_HANDLE_KILLPRIV + * - add FUSE_POSIX_ACL + */ + +#ifndef _LINUX_FUSE_H +#define _LINUX_FUSE_H + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +/* + * Version negotiation: + * + * Both the kernel and userspace send the version they support in the + * INIT request and reply respectively. + * + * If the major versions match then both shall use the smallest + * of the two minor versions for communication. + * + * If the kernel supports a larger major version, then userspace shall + * reply with the major version it supports, ignore the rest of the + * INIT message and expect a new INIT message from the kernel with a + * matching major version. + * + * If the library supports a larger major version, then it shall fall + * back to the major protocol version sent by the kernel for + * communication and reply with that major version (and an arbitrary + * supported minor version). + */ + +/** Version number of this interface */ +#define FUSE_KERNEL_VERSION 7 + +/** Minor version number of this interface */ +#define FUSE_KERNEL_MINOR_VERSION 26 + +/** The node ID of the root inode */ +#define FUSE_ROOT_ID 1 + +/* Make sure all structures are padded to 64bit boundary, so 32bit + userspace works under 64bit kernels */ + +struct fuse_attr { + uint64_t ino; + uint64_t size; + uint64_t blocks; + uint64_t atime; + uint64_t mtime; + uint64_t ctime; + uint32_t atimensec; + uint32_t mtimensec; + uint32_t ctimensec; + uint32_t mode; + uint32_t nlink; + uint32_t uid; + uint32_t gid; + uint32_t rdev; + uint32_t blksize; + uint32_t padding; +}; + +struct fuse_kstatfs { + uint64_t blocks; + uint64_t bfree; + uint64_t bavail; + uint64_t files; + uint64_t ffree; + uint32_t bsize; + uint32_t namelen; + uint32_t frsize; + uint32_t padding; + uint32_t spare[6]; +}; + +struct fuse_file_lock { + uint64_t start; + uint64_t end; + uint32_t type; + uint32_t pid; /* tgid */ +}; + +/** + * Bitmasks for fuse_setattr_in.valid + */ +#define FATTR_MODE (1 << 0) +#define FATTR_UID (1 << 1) +#define FATTR_GID (1 << 2) +#define FATTR_SIZE (1 << 3) +#define FATTR_ATIME (1 << 4) +#define FATTR_MTIME (1 << 5) +#define FATTR_FH (1 << 6) +#define FATTR_ATIME_NOW (1 << 7) +#define FATTR_MTIME_NOW (1 << 8) +#define FATTR_LOCKOWNER (1 << 9) +#define FATTR_CTIME (1 << 10) + +/** + * Flags returned by the OPEN request + * + * FOPEN_DIRECT_IO: bypass page cache for this open file + * FOPEN_KEEP_CACHE: don't invalidate the data cache on open + * FOPEN_NONSEEKABLE: the file is not seekable + */ +#define FOPEN_DIRECT_IO (1 << 0) +#define FOPEN_KEEP_CACHE (1 << 1) +#define FOPEN_NONSEEKABLE (1 << 2) + +/** + * INIT request/reply flags + * + * FUSE_ASYNC_READ: asynchronous read requests + * FUSE_POSIX_LOCKS: remote locking for POSIX file locks + * FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported) + * FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem + * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".." + * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB + * FUSE_DONT_MASK: don't apply umask to file mode on create operations + * FUSE_SPLICE_WRITE: kernel supports splice write on the device + * FUSE_SPLICE_MOVE: kernel supports splice move on the device + * FUSE_SPLICE_READ: kernel supports splice read on the device + * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks + * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories + * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages + * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one) + * FUSE_READDIRPLUS_AUTO: adaptive readdirplus + * FUSE_ASYNC_DIO: asynchronous direct I/O submission + * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes + * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens + * FUSE_PARALLEL_DIROPS: allow parallel lookups and readdir + * FUSE_HANDLE_KILLPRIV: fs handles killing suid/sgid/cap on write/chown/trunc + * FUSE_POSIX_ACL: filesystem supports posix acls + */ +#define FUSE_ASYNC_READ (1 << 0) +#define FUSE_POSIX_LOCKS (1 << 1) +#define FUSE_FILE_OPS (1 << 2) +#define FUSE_ATOMIC_O_TRUNC (1 << 3) +#define FUSE_EXPORT_SUPPORT (1 << 4) +#define FUSE_BIG_WRITES (1 << 5) +#define FUSE_DONT_MASK (1 << 6) +#define FUSE_SPLICE_WRITE (1 << 7) +#define FUSE_SPLICE_MOVE (1 << 8) +#define FUSE_SPLICE_READ (1 << 9) +#define FUSE_FLOCK_LOCKS (1 << 10) +#define FUSE_HAS_IOCTL_DIR (1 << 11) +#define FUSE_AUTO_INVAL_DATA (1 << 12) +#define FUSE_DO_READDIRPLUS (1 << 13) +#define FUSE_READDIRPLUS_AUTO (1 << 14) +#define FUSE_ASYNC_DIO (1 << 15) +#define FUSE_WRITEBACK_CACHE (1 << 16) +#define FUSE_NO_OPEN_SUPPORT (1 << 17) +#define FUSE_PARALLEL_DIROPS (1 << 18) +#define FUSE_HANDLE_KILLPRIV (1 << 19) +#define FUSE_POSIX_ACL (1 << 20) + +/** + * CUSE INIT request/reply flags + * + * CUSE_UNRESTRICTED_IOCTL: use unrestricted ioctl + */ +#define CUSE_UNRESTRICTED_IOCTL (1 << 0) + +/** + * Release flags + */ +#define FUSE_RELEASE_FLUSH (1 << 0) +#define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1) + +/** + * Getattr flags + */ +#define FUSE_GETATTR_FH (1 << 0) + +/** + * Lock flags + */ +#define FUSE_LK_FLOCK (1 << 0) + +/** + * WRITE flags + * + * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed + * FUSE_WRITE_LOCKOWNER: lock_owner field is valid + */ +#define FUSE_WRITE_CACHE (1 << 0) +#define FUSE_WRITE_LOCKOWNER (1 << 1) + +/** + * Read flags + */ +#define FUSE_READ_LOCKOWNER (1 << 1) + +/** + * Ioctl flags + * + * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine + * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed + * FUSE_IOCTL_RETRY: retry with new iovecs + * FUSE_IOCTL_32BIT: 32bit ioctl + * FUSE_IOCTL_DIR: is a directory + * + * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs + */ +#define FUSE_IOCTL_COMPAT (1 << 0) +#define FUSE_IOCTL_UNRESTRICTED (1 << 1) +#define FUSE_IOCTL_RETRY (1 << 2) +#define FUSE_IOCTL_32BIT (1 << 3) +#define FUSE_IOCTL_DIR (1 << 4) + +#define FUSE_IOCTL_MAX_IOV 256 + +/** + * Poll flags + * + * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify + */ +#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0) + +enum fuse_opcode { + FUSE_LOOKUP = 1, + FUSE_FORGET = 2, /* no reply */ + FUSE_GETATTR = 3, + FUSE_SETATTR = 4, + FUSE_READLINK = 5, + FUSE_SYMLINK = 6, + FUSE_MKNOD = 8, + FUSE_MKDIR = 9, + FUSE_UNLINK = 10, + FUSE_RMDIR = 11, + FUSE_RENAME = 12, + FUSE_LINK = 13, + FUSE_OPEN = 14, + FUSE_READ = 15, + FUSE_WRITE = 16, + FUSE_STATFS = 17, + FUSE_RELEASE = 18, + FUSE_FSYNC = 20, + FUSE_SETXATTR = 21, + FUSE_GETXATTR = 22, + FUSE_LISTXATTR = 23, + FUSE_REMOVEXATTR = 24, + FUSE_FLUSH = 25, + FUSE_INIT = 26, + FUSE_OPENDIR = 27, + FUSE_READDIR = 28, + FUSE_RELEASEDIR = 29, + FUSE_FSYNCDIR = 30, + FUSE_GETLK = 31, + FUSE_SETLK = 32, + FUSE_SETLKW = 33, + FUSE_ACCESS = 34, + FUSE_CREATE = 35, + FUSE_INTERRUPT = 36, + FUSE_BMAP = 37, + FUSE_DESTROY = 38, + FUSE_IOCTL = 39, + FUSE_POLL = 40, + FUSE_NOTIFY_REPLY = 41, + FUSE_BATCH_FORGET = 42, + FUSE_FALLOCATE = 43, + FUSE_READDIRPLUS = 44, + FUSE_RENAME2 = 45, + FUSE_LSEEK = 46, + + /* CUSE specific operations */ + CUSE_INIT = 4096, +}; + +enum fuse_notify_code { + FUSE_NOTIFY_POLL = 1, + FUSE_NOTIFY_INVAL_INODE = 2, + FUSE_NOTIFY_INVAL_ENTRY = 3, + FUSE_NOTIFY_STORE = 4, + FUSE_NOTIFY_RETRIEVE = 5, + FUSE_NOTIFY_DELETE = 6, + FUSE_NOTIFY_CODE_MAX, +}; + +/* The read buffer is required to be at least 8k, but may be much larger */ +#define FUSE_MIN_READ_BUFFER 8192 + +#define FUSE_COMPAT_ENTRY_OUT_SIZE 120 + +struct fuse_entry_out { + uint64_t nodeid; /* Inode ID */ + uint64_t generation; /* Inode generation: nodeid:gen must + be unique for the fs's lifetime */ + uint64_t entry_valid; /* Cache timeout for the name */ + uint64_t attr_valid; /* Cache timeout for the attributes */ + uint32_t entry_valid_nsec; + uint32_t attr_valid_nsec; + struct fuse_attr attr; +}; + +struct fuse_forget_in { + uint64_t nlookup; +}; + +struct fuse_forget_one { + uint64_t nodeid; + uint64_t nlookup; +}; + +struct fuse_batch_forget_in { + uint32_t count; + uint32_t dummy; +}; + +struct fuse_getattr_in { + uint32_t getattr_flags; + uint32_t dummy; + uint64_t fh; +}; + +#define FUSE_COMPAT_ATTR_OUT_SIZE 96 + +struct fuse_attr_out { + uint64_t attr_valid; /* Cache timeout for the attributes */ + uint32_t attr_valid_nsec; + uint32_t dummy; + struct fuse_attr attr; +}; + +#define FUSE_COMPAT_MKNOD_IN_SIZE 8 + +struct fuse_mknod_in { + uint32_t mode; + uint32_t rdev; + uint32_t umask; + uint32_t padding; +}; + +struct fuse_mkdir_in { + uint32_t mode; + uint32_t umask; +}; + +struct fuse_rename_in { + uint64_t newdir; +}; + +struct fuse_rename2_in { + uint64_t newdir; + uint32_t flags; + uint32_t padding; +}; + +struct fuse_link_in { + uint64_t oldnodeid; +}; + +struct fuse_setattr_in { + uint32_t valid; + uint32_t padding; + uint64_t fh; + uint64_t size; + uint64_t lock_owner; + uint64_t atime; + uint64_t mtime; + uint64_t ctime; + uint32_t atimensec; + uint32_t mtimensec; + uint32_t ctimensec; + uint32_t mode; + uint32_t unused4; + uint32_t uid; + uint32_t gid; + uint32_t unused5; +}; + +struct fuse_open_in { + uint32_t flags; + uint32_t unused; +}; + +struct fuse_create_in { + uint32_t flags; + uint32_t mode; + uint32_t umask; + uint32_t padding; +}; + +struct fuse_open_out { + uint64_t fh; + uint32_t open_flags; + uint32_t padding; +}; + +struct fuse_release_in { + uint64_t fh; + uint32_t flags; + uint32_t release_flags; + uint64_t lock_owner; +}; + +struct fuse_flush_in { + uint64_t fh; + uint32_t unused; + uint32_t padding; + uint64_t lock_owner; +}; + +struct fuse_read_in { + uint64_t fh; + uint64_t offset; + uint32_t size; + uint32_t read_flags; + uint64_t lock_owner; + uint32_t flags; + uint32_t padding; +}; + +#define FUSE_COMPAT_WRITE_IN_SIZE 24 + +struct fuse_write_in { + uint64_t fh; + uint64_t offset; + uint32_t size; + uint32_t write_flags; + uint64_t lock_owner; + uint32_t flags; + uint32_t padding; +}; + +struct fuse_write_out { + uint32_t size; + uint32_t padding; +}; + +#define FUSE_COMPAT_STATFS_SIZE 48 + +struct fuse_statfs_out { + struct fuse_kstatfs st; +}; + +struct fuse_fsync_in { + uint64_t fh; + uint32_t fsync_flags; + uint32_t padding; +}; + +struct fuse_setxattr_in { + uint32_t size; + uint32_t flags; +}; + +struct fuse_getxattr_in { + uint32_t size; + uint32_t padding; +}; + +struct fuse_getxattr_out { + uint32_t size; + uint32_t padding; +}; + +struct fuse_lk_in { + uint64_t fh; + uint64_t owner; + struct fuse_file_lock lk; + uint32_t lk_flags; + uint32_t padding; +}; + +struct fuse_lk_out { + struct fuse_file_lock lk; +}; + +struct fuse_access_in { + uint32_t mask; + uint32_t padding; +}; + +struct fuse_init_in { + uint32_t major; + uint32_t minor; + uint32_t max_readahead; + uint32_t flags; +}; + +#define FUSE_COMPAT_INIT_OUT_SIZE 8 +#define FUSE_COMPAT_22_INIT_OUT_SIZE 24 + +struct fuse_init_out { + uint32_t major; + uint32_t minor; + uint32_t max_readahead; + uint32_t flags; + uint16_t max_background; + uint16_t congestion_threshold; + uint32_t max_write; + uint32_t time_gran; + uint32_t unused[9]; +}; + +#define CUSE_INIT_INFO_MAX 4096 + +struct cuse_init_in { + uint32_t major; + uint32_t minor; + uint32_t unused; + uint32_t flags; +}; + +struct cuse_init_out { + uint32_t major; + uint32_t minor; + uint32_t unused; + uint32_t flags; + uint32_t max_read; + uint32_t max_write; + uint32_t dev_major; /* chardev major */ + uint32_t dev_minor; /* chardev minor */ + uint32_t spare[10]; +}; + +struct fuse_interrupt_in { + uint64_t unique; +}; + +struct fuse_bmap_in { + uint64_t block; + uint32_t blocksize; + uint32_t padding; +}; + +struct fuse_bmap_out { + uint64_t block; +}; + +struct fuse_ioctl_in { + uint64_t fh; + uint32_t flags; + uint32_t cmd; + uint64_t arg; + uint32_t in_size; + uint32_t out_size; +}; + +struct fuse_ioctl_iovec { + uint64_t base; + uint64_t len; +}; + +struct fuse_ioctl_out { + int32_t result; + uint32_t flags; + uint32_t in_iovs; + uint32_t out_iovs; +}; + +struct fuse_poll_in { + uint64_t fh; + uint64_t kh; + uint32_t flags; + uint32_t events; +}; + +struct fuse_poll_out { + uint32_t revents; + uint32_t padding; +}; + +struct fuse_notify_poll_wakeup_out { + uint64_t kh; +}; + +struct fuse_fallocate_in { + uint64_t fh; + uint64_t offset; + uint64_t length; + uint32_t mode; + uint32_t padding; +}; + +struct fuse_in_header { + uint32_t len; + uint32_t opcode; + uint64_t unique; + uint64_t nodeid; + uint32_t uid; + uint32_t gid; + uint32_t pid; + uint32_t padding; +}; + +struct fuse_out_header { + uint32_t len; + int32_t error; + uint64_t unique; +}; + +struct fuse_dirent { + uint64_t ino; + uint64_t off; + uint32_t namelen; + uint32_t type; + char name[]; +}; + +#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) +#define FUSE_DIRENT_ALIGN(x) \ + (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1)) +#define FUSE_DIRENT_SIZE(d) \ + FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) + +struct fuse_direntplus { + struct fuse_entry_out entry_out; + struct fuse_dirent dirent; +}; + +#define FUSE_NAME_OFFSET_DIRENTPLUS \ + offsetof(struct fuse_direntplus, dirent.name) +#define FUSE_DIRENTPLUS_SIZE(d) \ + FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen) + +struct fuse_notify_inval_inode_out { + uint64_t ino; + int64_t off; + int64_t len; +}; + +struct fuse_notify_inval_entry_out { + uint64_t parent; + uint32_t namelen; + uint32_t padding; +}; + +struct fuse_notify_delete_out { + uint64_t parent; + uint64_t child; + uint32_t namelen; + uint32_t padding; +}; + +struct fuse_notify_store_out { + uint64_t nodeid; + uint64_t offset; + uint32_t size; + uint32_t padding; +}; + +struct fuse_notify_retrieve_out { + uint64_t notify_unique; + uint64_t nodeid; + uint64_t offset; + uint32_t size; + uint32_t padding; +}; + +/* Matches the size of fuse_write_in */ +struct fuse_notify_retrieve_in { + uint64_t dummy1; + uint64_t offset; + uint32_t size; + uint32_t dummy2; + uint64_t dummy3; + uint64_t dummy4; +}; + +/* Device ioctls: */ +#define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t) + +struct fuse_lseek_in { + uint64_t fh; + uint64_t offset; + uint32_t whence; + uint32_t padding; +}; + +struct fuse_lseek_out { + uint64_t offset; +}; + +#endif /* _LINUX_FUSE_H */ diff --git a/lib_gen/profuse_typegen.ml b/lib_gen/profuse_typegen.ml index 9317396..1adf340 100644 --- a/lib_gen/profuse_typegen.ml +++ b/lib_gen/profuse_typegen.ml @@ -46,6 +46,7 @@ let fuse_versions : (string * (string * (module Cstubs.Types.BINDINGS))) list = "7_23", ("fuse_kernel.h.7_23", (module Profuse_types_7_23.C)); "7_24", ("fuse_kernel.h.7_24", (module Profuse_types_7_24.C)); "7_25", ("fuse_kernel.h.7_25", (module Profuse_types_7_25.C)); + "7_26", ("fuse_kernel.h.7_26", (module Profuse_types_7_26.C)); ] let resolve_version : string -> (string * (module Cstubs.Types.BINDINGS)) = diff --git a/lib_gen/profuse_types_7_26.ml b/lib_gen/profuse_types_7_26.ml new file mode 100644 index 0000000..11b4eca --- /dev/null +++ b/lib_gen/profuse_types_7_26.ml @@ -0,0 +1,112 @@ +(* + * Copyright (c) 2018 Docker Inc + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + *) + +module C(F: Cstubs.Types.TYPE) = struct + open F + + type 'a structure = 'a Ctypes_static.structure + + (* Build the types for FUSE 7.25, but don't seal the structs *) + module Version_7_25 = Profuse_types_7_25.C + (struct + include F + let seal _ = () + end) + + (* Extend and seal the structs *) + module Struct = struct + module V_7_25 = Version_7_25.Struct + module Kstatfs = struct include V_7_25.Kstatfs let () = seal t end + module File_lock = struct include V_7_25.File_lock let () = seal t end + module Dirent = struct include V_7_25.Dirent let () = seal t end + module Attr = struct include V_7_25.Attr let () = seal t end + module Forget_one = struct include V_7_25.Forget_one let () = seal t end + module Ioctl_iovec = struct include V_7_25.Ioctl_iovec let () = seal t end + module Direntplus = struct include V_7_25.Direntplus let () = seal t end + end + + module Out = struct + module V_7_25 = Version_7_25.Out + module Hdr = struct include V_7_25.Hdr let () = seal t end + module Write = struct include V_7_25.Write let () = seal t end + module Open = struct include V_7_25.Open let () = seal t end + module Entry = struct include V_7_25.Entry let () = seal t end + module Attr = struct include V_7_25.Attr let () = seal t end + module Statfs = struct include V_7_25.Statfs let () = seal t end + module Getxattr = struct include V_7_25.Getxattr let () = seal t end + module Lk = struct include V_7_25.Lk let () = seal t end + module Bmap = struct include V_7_25.Bmap let () = seal t end + module Ioctl = struct include V_7_25.Ioctl let () = seal t end + module Poll = struct include V_7_25.Poll let () = seal t end + module Notify_poll_wakeup = struct include V_7_25.Notify_poll_wakeup let () = seal t end + module Cuse_init = struct include V_7_25.Cuse_init let () = seal t end + module Notify_inval_inode = struct include V_7_25.Notify_inval_inode let () = seal t end + module Notify_inval_entry = struct include V_7_25.Notify_inval_entry let () = seal t end + module Notify_delete = struct include V_7_25.Notify_delete let () = seal t end + module Notify_store = struct include V_7_25.Notify_store let () = seal t end + module Notify_retrieve = struct include V_7_25.Notify_retrieve let () = seal t end + module Init = struct include V_7_25.Init let () = seal t end + module Lseek = struct include V_7_25.Lseek let () = seal t end + + end + + module In = struct + module V_7_25 = Version_7_25.In + module Hdr = struct include V_7_25.Hdr let () = seal t end + module Open = struct include V_7_25.Open let () = seal t end + module Release = struct include V_7_25.Release let () = seal t end + module Access = struct include V_7_25.Access let () = seal t end + module Forget = struct include V_7_25.Forget let () = seal t end + module Flush = struct include V_7_25.Flush let () = seal t end + module Create = struct include V_7_25.Create let () = seal t end + module Mknod = struct include V_7_25.Mknod let () = seal t end + module Mkdir = struct include V_7_25.Mkdir let () = seal t end + module Rename = struct include V_7_25.Rename let () = seal t end + module Link = struct include V_7_25.Link let () = seal t end + module Fsync = struct include V_7_25.Fsync let () = seal t end + module Interrupt = struct include V_7_25.Interrupt let () = seal t end + module Bmap = struct include V_7_25.Bmap let () = seal t end + module Getxattr = struct include V_7_25.Getxattr let () = seal t end + module Setxattr = struct include V_7_25.Setxattr let () = seal t end + module Read = struct include V_7_25.Read let () = seal t end + module Write = struct include V_7_25.Write let () = seal t end + module Lk = struct include V_7_25.Lk let () = seal t end + module Getattr = struct include V_7_25.Getattr let () = seal t end + module Ioctl = struct include V_7_25.Ioctl let () = seal t end + module Poll = struct include V_7_25.Poll let () = seal t end + module Cuse_init = struct include V_7_25.Cuse_init let () = seal t end + module Notify_retrieve = struct include V_7_25.Notify_retrieve let () = seal t end + module Batch_forget = struct include V_7_25.Batch_forget let () = seal t end + module Fallocate = struct include V_7_25.Fallocate let () = seal t end + module Opcode = V_7_25.Opcode + + module Init = struct + module Flags = struct + include V_7_25.Init.Flags + let fuse_handle_killpriv = constant "FUSE_HANDLE_KILLPRIV" t + let fuse_posix_acl = constant "FUSE_POSIX_ACL" t + + end + include (V_7_25.Init + : module type of V_7_25.Init with module Flags := Flags) + let () = seal t + end + module Setattr = struct include V_7_25.Setattr let () = seal t end + module Rename2 = struct include V_7_25.Rename2 let () = seal t end + module Lseek = struct include V_7_25.Lseek let () = seal t end + end +end From a7062d370a8433d35f70c2bf54be2250ac651661 Mon Sep 17 00:00:00 2001 From: David Scott Date: Thu, 25 Jan 2018 17:09:51 +0000 Subject: [PATCH 4/7] Clone Profuse_7_23 to Profuse_7_26 The differences between the two versions will become clear in the next few patches. Signed-off-by: David Scott --- Makefile | 3 +- lib/profuse_.mllib | 1 + lib/profuse_7_26.ml | 1583 ++++++++++++++++++++++++++++++++++++++++++ lib/profuse_7_26.mli | 641 +++++++++++++++++ 4 files changed, 2227 insertions(+), 1 deletion(-) create mode 100644 lib/profuse_7_26.ml create mode 100644 lib/profuse_7_26.mli diff --git a/Makefile b/Makefile index 6302bbe..0098349 100644 --- a/Makefile +++ b/Makefile @@ -31,10 +31,11 @@ endif TYPES=.mli .cmi .cmti -VERSIONS=_7_8 _7_23 +VERSIONS=_7_8 _7_23 _7_26 INSTALL:=$(addprefix profuse_7_8, $(TYPES)) \ $(addprefix profuse_7_23, $(TYPES)) \ + $(addprefix profuse_7_26, $(TYPES)) \ $(addprefix profuse_signatures, $(TYPES)) \ $(foreach versioned,$(addprefix $(MOD_NAME), $(VERSIONS)),\ $(addprefix $(versioned), $(TYPES)))\ diff --git a/lib/profuse_.mllib b/lib/profuse_.mllib index 435b521..f8100e9 100644 --- a/lib/profuse_.mllib +++ b/lib/profuse_.mllib @@ -41,3 +41,4 @@ Profuse_types_detected_7_26 Profuse_signatures Profuse_7_8 Profuse_7_23 +Profuse_7_26 diff --git a/lib/profuse_7_26.ml b/lib/profuse_7_26.ml new file mode 100644 index 0000000..34e40ac --- /dev/null +++ b/lib/profuse_7_26.ml @@ -0,0 +1,1583 @@ +(* + * Copyright (c) 2014-2015 David Sheets + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + *) + +open Ctypes +open Unsigned +module Types = Profuse_types_7_23.C(Profuse_types_detected_7_23) + +type 'a structure = 'a Types.structure + +module Flags = struct + type t = int32 + + let empty = 0l +end + +module Host = struct + type t = { + fcntl : Fcntl.Host.t; + errno : Errno.Host.t; + sys_stat : Sys_stat.Host.t; + dirent : Dirent.Host.t; + unistd : Unistd.host; + } + + let linux_4_0_5 = { + fcntl = Fcntl_host.Linux.V4_1_12.Musl.v1_1_12; + errno = Errno_host.Linux.v4_4_6; + sys_stat = Sys_stat_host.Linux.V4_1_12.Musl.v1_1_12; + dirent = Dirent_unix.host; (* TODO: FIXME *) + unistd = Unistd_unix.host; (* TODO: FIXME *) + } +end + +type chan = { + id : int; + mutable unique : Unsigned.uint64; + mnt : string; + version : int * int; + max_readahead : int; + max_write : int; + flags : Flags.t; + host : Host.t; +} + +exception ProtocolError of chan * string +exception Destroy of int + +type ('hdr, 'body) packet = { + chan : chan; + hdr : 'hdr Ctypes.structure; + pkt : 'body; +} + +module Struct = struct + module T = Types.Struct + + module Kstatfs = struct + module T = T.Kstatfs + + let store + ~blocks ~bfree ~bavail ~files ~ffree ~bsize ~namelen ~frsize mem = + setf mem T.blocks blocks; + setf mem T.bfree bfree; + setf mem T.bavail bavail; + setf mem T.files files; + setf mem T.ffree ffree; + setf mem T.bsize bsize; + setf mem T.namelen namelen; + setf mem T.frsize frsize; + () + + let create + ~blocks ~bfree ~bavail ~files ~ffree ~bsize ~namelen ~frsize () = + let kstatfs = make T.t in + store + ~blocks ~bfree ~bavail ~files ~ffree ~bsize ~namelen ~frsize kstatfs; + kstatfs + + let describe pkt = + let i64 = UInt64.to_int64 in + let i32 = UInt32.to_int32 in + let blocks = getf pkt T.blocks in + let bfree = getf pkt T.bfree in + let bavail = getf pkt T.bavail in + let files = getf pkt T.files in + let ffree = getf pkt T.ffree in + let bsize = getf pkt T.bsize in + let frsize = getf pkt T.frsize in + let namelen = getf pkt T.namelen in + Printf.sprintf + "blocks=%Ld bfree=%Ld bavail=%Ld files=%Ld ffree=%Ld bsize=%ld frsize=%ld namelen=%ld" + (i64 blocks) + (i64 bfree) + (i64 bavail) + (i64 files) + (i64 ffree) + (i32 bsize) + (i32 frsize) + (i32 namelen) + end + + module File_lock = struct + module T = T.File_lock + + let describe fl = + let start = getf fl T.start + and end_ = getf fl T.end_ + and type_ = getf fl T.type_ + and pid = getf fl T.pid in + Printf.sprintf "start=%Ld end=%Ld type=%ld pid=%ld" + (UInt64.to_int64 start) + (UInt64.to_int64 end_) + (UInt32.to_int32 type_) + (UInt32.to_int32 pid) + end + + module Attr = struct + module T = T.Attr + + let store ~ino ~size ~blocks + ~atime ~mtime ~ctime ~atimensec ~mtimensec ~ctimensec + ~mode ~nlink ~uid ~gid ~rdev ~blksize mem = + setf mem T.ino ino; + setf mem T.size size; + setf mem T.blocks blocks; + setf mem T.atime atime; + setf mem T.mtime mtime; + setf mem T.ctime ctime; + setf mem T.atimensec atimensec; + setf mem T.mtimensec mtimensec; + setf mem T.ctimensec ctimensec; + setf mem T.mode mode; + setf mem T.nlink nlink; + setf mem T.uid uid; + setf mem T.gid gid; + setf mem T.rdev rdev; + setf mem T.blksize blksize; + () + + let create ~ino ~size ~blocks + ~atime ~mtime ~ctime ~atimensec ~mtimensec ~ctimensec + ~mode ~nlink ~uid ~gid ~rdev ~blksize () = + let attr = make T.t in + store ~ino ~size ~blocks ~atime ~mtime ~ctime + ~atimensec ~mtimensec ~ctimensec ~mode ~nlink ~uid ~gid ~rdev ~blksize + attr; + attr + + let describe ~host pkt = + let phost = host.Host.sys_stat.Sys_stat.Host.mode in + let i64 = UInt64.to_int64 in + let i32 = UInt32.to_int32 in + let mode = UInt32.to_int (getf pkt T.mode) in + let mode_string = match Sys_stat.Mode.of_code ~host:phost mode with + | None -> "UNKNOWN" + | Some mode -> Sys_stat.Mode.to_string ~host:phost mode + in + (* TODO: nsec times? *) + Printf.sprintf + "ino=%Ld size=%Ld blocks=%Ld atime=%Ld mtime=%Ld ctime=%Ld mode=%s (0x%x) nlink=%ld uid=%ld gid=%ld rdev=%ld blksize=%ld" + (i64 (getf pkt T.ino)) + (i64 (getf pkt T.size)) + (i64 (getf pkt T.blocks)) + (i64 (getf pkt T.atime)) + (i64 (getf pkt T.mtime)) + (i64 (getf pkt T.ctime)) + mode_string + mode + (i32 (getf pkt T.nlink)) + (i32 (getf pkt T.uid)) + (i32 (getf pkt T.gid)) + (i32 (getf pkt T.rdev)) + (i32 (getf pkt T.blksize)) + end + + module Forget_one = struct + module T = T.Forget_one + end +end + +module In = struct + module T = Types.In + + module Opcode = struct + module T = T.Opcode + + type t = T.t + + let to_string = function + | `CUSE_INIT -> "CUSE_INIT" + | `FUSE_ACCESS -> "FUSE_ACCESS" + | `FUSE_BATCH_FORGET -> "FUSE_BATCH_FORGET" + | `FUSE_BMAP -> "FUSE_BMAP" + | `FUSE_CREATE -> "FUSE_CREATE" + | `FUSE_DESTROY -> "FUSE_DESTROY" + | `FUSE_FALLOCATE -> "FUSE_FALLOCATE" + | `FUSE_FLUSH -> "FUSE_FLUSH" + | `FUSE_FORGET -> "FUSE_FORGET" + | `FUSE_FSYNC -> "FUSE_FSYNC" + | `FUSE_FSYNCDIR -> "FUSE_FSYNCDIR" + | `FUSE_GETATTR -> "FUSE_GETATTR" + | `FUSE_GETLK -> "FUSE_GETLK" + | `FUSE_GETXATTR -> "FUSE_GETXATTR" + | `FUSE_INIT -> "FUSE_INIT" + | `FUSE_INTERRUPT -> "FUSE_INTERRUPT" + | `FUSE_IOCTL -> "FUSE_IOCTL" + | `FUSE_LINK -> "FUSE_LINK" + | `FUSE_LISTXATTR -> "FUSE_LISTXATTR" + | `FUSE_LOOKUP -> "FUSE_LOOKUP" + | `FUSE_MKDIR -> "FUSE_MKDIR" + | `FUSE_MKNOD -> "FUSE_MKNOD" + | `FUSE_NOTIFY_REPLY -> "FUSE_NOTIFY_REPLY" + | `FUSE_OPEN -> "FUSE_OPEN" + | `FUSE_OPENDIR -> "FUSE_OPENDIR" + | `FUSE_POLL -> "FUSE_POLL" + | `FUSE_READ -> "FUSE_READ" + | `FUSE_READDIR -> "FUSE_READDIR" + | `FUSE_READDIRPLUS -> "FUSE_READDIRPLUS" + | `FUSE_READLINK -> "FUSE_READLINK" + | `FUSE_RELEASE -> "FUSE_RELEASE" + | `FUSE_RELEASEDIR -> "FUSE_RELEASEDIR" + | `FUSE_REMOVEXATTR -> "FUSE_REMOVEXATTR" + | `FUSE_RENAME -> "FUSE_RENAME" + | `FUSE_RENAME2 -> "FUSE_RENAME2" + | `FUSE_RMDIR -> "FUSE_RMDIR" + | `FUSE_SETATTR -> "FUSE_SETATTR" + | `FUSE_SETLK -> "FUSE_SETLK" + | `FUSE_SETLKW -> "FUSE_SETLKW" + | `FUSE_SETXATTR -> "FUSE_SETXATTR" + | `FUSE_STATFS -> "FUSE_STATFS" + | `FUSE_SYMLINK -> "FUSE_SYMLINK" + | `FUSE_UNLINK -> "FUSE_UNLINK" + | `FUSE_WRITE -> "FUSE_WRITE" + | `Unknown i -> "UnknownOpcode("^(Int32.to_string i)^")" + + let returns = function + | `FUSE_FORGET | `FUSE_DESTROY -> false + | _ -> true + + let of_uint32 : Unsigned.UInt32.t -> Types.In.Opcode.t = + let l = List.map (fun (k, v) -> (v, k)) Types.In.Opcode.enum_values in + fun i -> + try ListLabels.assoc i l + with Not_found -> `Unknown (Unsigned.UInt32.to_int32 i) + + let to_uint32 v = ListLabels.assoc v Types.In.Opcode.enum_values + end + + module Hdr = struct + module T = T.Hdr + + let hdrsz = sizeof T.t + let sz = hdrsz + + (* Create a headed packet with count buffer sequentially after header *) + let packet ~opcode ~unique ~nodeid ~uid ~gid ~pid ~count = + let opcode = Opcode.to_uint32 opcode in + let bodysz = count in + let count = hdrsz + bodysz in + let pkt = allocate_n char ~count in + let hdr = !@ (coerce (ptr char) (ptr T.t) pkt) in + setf hdr T.len (UInt32.of_int count); + setf hdr T.opcode opcode; + setf hdr T.unique unique; + setf hdr T.nodeid nodeid; + setf hdr T.uid uid; + setf hdr T.gid gid; + setf hdr T.pid pid; + CArray.from_ptr (pkt +@ hdrsz) bodysz + + (* Create a headed packet with st struct sequentially after header *) + let make ~opcode ~unique ~nodeid ~uid ~gid ~pid st = + let count = sizeof st in + let pkt = packet ~opcode ~unique ~nodeid ~uid ~gid ~pid ~count in + !@ (coerce (ptr char) (ptr st) (CArray.start pkt)) + + let memcpy ~dest ~src n = + let cast p = from_voidp (array n uchar) p in + cast dest <-@ !@(cast src) + + let packet_from_hdr hdr ~count = + let bodysz = count in + let count = hdrsz + bodysz in + let pkt = allocate_n char ~count in + let dest = to_voidp pkt in + memcpy ~dest ~src:(to_voidp (addr hdr)) hdrsz; + setf hdr T.len (UInt32.of_int count); + CArray.from_ptr (pkt +@ hdrsz) bodysz + + let make_from_hdr hdr st = + let count = sizeof st in + let pkt = packet_from_hdr hdr ~count in + !@ (coerce (ptr char) (ptr st) (CArray.start pkt)) + end + + module Init = struct + module T = T.Init + end + + module Open = struct + module T = T.Open + end + + module Read = struct + module T = T.Read + end + + module Release = struct + module T = T.Release + end + + module Access = struct + module T = T.Access + end + + module Forget = struct + module T = T.Forget + end + + module Flush = struct + module T = T.Flush + end + + module Create = struct + module T = T.Create + + let struct_size = sizeof T.t + + let name p = coerce (ptr char) string ((from_voidp char p) +@ struct_size) + end + + module Mknod = struct + module T = T.Mknod + + let struct_size = sizeof T.t + + let name p = coerce (ptr char) string ((from_voidp char p) +@ struct_size) + end + + module Mkdir = struct + module T = T.Mkdir + + let struct_size = sizeof T.t + + let name p = coerce (ptr char) string ((from_voidp char p) +@ struct_size) + end + + module Rename = struct + module T = T.Rename + + let struct_size = sizeof T.t + + let source_destination p = + let p = (from_voidp char p) +@ struct_size in + let src = coerce (ptr char) string p in + let p = p +@ (String.length src + 1) in + let dest = coerce (ptr char) string p in + (src, dest) + end + + module Link = struct + module T = T.Link + + let struct_size = sizeof T.t + + let name p = coerce (ptr char) string ((from_voidp char p) +@ struct_size) + end + + module Write = struct + module T = T.Write + + let struct_size = sizeof T.t + + let data p = (from_voidp char p) +@ struct_size + end + + module Fsync = struct + module T = T.Fsync + end + + module Lk = struct + module T = T.Lk + + let describe lk = + let fh = getf lk T.fh + and owner = getf lk T.owner + and lk = getf lk T.lk + and lk_flags = getf lk T.lk_flags in + Printf.sprintf "fh=%Ld owner=%Ld lk=(%s) lk_flags=%Ld" + fh (UInt64.to_int64 owner) + (Struct.File_lock.describe lk) + (UInt32.to_int64 lk_flags) + end + + module Interrupt = struct + module T = T.Interrupt + end + + module Bmap = struct + module T = T.Bmap + end + + module Setattr = struct + module T = T.Setattr + + module Valid = struct + module T = T.Valid + + type t = { + mode : bool; + uid : bool; + gid : bool; + size : bool; + atime : bool; + mtime : bool; + fh : bool; + unknown : int32; + atime_now : bool; + mtime_now : bool; + lock_owner : bool; + ctime : bool; + } + + let (&&&) = UInt32.logand + let (|||) = UInt32.logor + + let to_string_list valid = + let list = if valid.mode then ["mode"] else [] in + let list = if valid.uid then "uid" ::list else list in + let list = if valid.gid then "gid" ::list else list in + let list = if valid.size then "size" ::list else list in + let list = if valid.atime then "atime" ::list else list in + let list = if valid.mtime then "mtime" ::list else list in + let list = if valid.fh then "fh" ::list else list in + let list = if valid.atime_now then "atime_now" ::list else list in + let list = if valid.mtime_now then "mtime_now" ::list else list in + let list = if valid.lock_owner then "lock_owner" ::list else list in + let list = if valid.ctime then "ctime" ::list else list in + if valid.unknown = Int32.zero + then list + else (Printf.sprintf "unknown[0x%lx]" valid.unknown)::list + + let all = UInt32.zero + ||| T.fattr_mode + ||| T.fattr_uid + ||| T.fattr_gid + ||| T.fattr_size + ||| T.fattr_atime + ||| T.fattr_mtime + ||| T.fattr_fh + ||| T.fattr_atime_now + ||| T.fattr_mtime_now + ||| T.fattr_lockowner + ||| T.fattr_ctime + + + let of_uint32 i = { + mode = UInt32.(compare zero (i &&& T.fattr_mode) <> 0); + uid = UInt32.(compare zero (i &&& T.fattr_uid) <> 0); + gid = UInt32.(compare zero (i &&& T.fattr_gid) <> 0); + size = UInt32.(compare zero (i &&& T.fattr_size) <> 0); + atime = UInt32.(compare zero (i &&& T.fattr_atime) <> 0); + mtime = UInt32.(compare zero (i &&& T.fattr_mtime) <> 0); + fh = UInt32.(compare zero (i &&& T.fattr_fh) <> 0); + unknown = UInt32.(to_int32 (i &&& (lognot all))); + atime_now = UInt32.(compare zero (i &&& T.fattr_atime_now) <> 0); + mtime_now = UInt32.(compare zero (i &&& T.fattr_mtime_now) <> 0); + lock_owner = UInt32.(compare zero (i &&& T.fattr_lockowner) <> 0); + ctime = UInt32.(compare zero (i &&& T.fattr_ctime) <> 0); + } + + let to_uint32 { + mode; + uid; + gid; + size; + atime; + mtime; + fh; + atime_now; + mtime_now; + lock_owner; + ctime; + } = + let open UInt32 in + (if mode then T.fattr_mode else zero) ||| + (if uid then T.fattr_uid else zero) ||| + (if gid then T.fattr_gid else zero) ||| + (if size then T.fattr_size else zero) ||| + (if atime then T.fattr_atime else zero) ||| + (if mtime then T.fattr_mtime else zero) ||| + (if fh then T.fattr_fh else zero) ||| + (if atime_now then T.fattr_atime_now else zero) ||| + (if mtime_now then T.fattr_mtime_now else zero) ||| + (if lock_owner then T.fattr_lockowner else zero) ||| + (if ctime then T.fattr_ctime else zero) + end + + let create_from_hdr + ~valid ~fh ~size + ~atime ~mtime ~atimensec ~mtimensec + ~mode ~uid ~gid ~lock_owner + ~ctime ~ctimensec + hdr = + let pkt = Hdr.make_from_hdr hdr T.t in + setf pkt T.valid valid; + setf pkt T.fh fh; + setf pkt T.size size; + setf pkt T.atime atime; + setf pkt T.mtime mtime; + setf pkt T.atimensec atimensec; + setf pkt T.mtimensec mtimensec; + setf pkt T.mode mode; + setf pkt T.uid uid; + setf pkt T.gid gid; + setf pkt T.lock_owner lock_owner; + setf pkt T.ctime ctime; + setf pkt T.ctimensec ctimensec; + CArray.from_ptr (coerce (ptr T.t) (ptr char) (addr pkt)) (sizeof T.t) + + let to_string_list ~host t = + let valid = Valid.of_uint32 (getf t T.valid) in + let list = + if valid.Valid.mode + then + let mode_code = Unsigned.UInt32.to_int (getf t T.mode) in + let mode = Sys_stat.File_perm.full_of_code ~host mode_code in + let mode_string = Sys_stat.File_perm.to_string ~host mode in + [Printf.sprintf "mode=%s" mode_string] + else [] + in + let list = + if valid.Valid.uid + then + let uid = Unsigned.UInt32.to_int (getf t T.uid) in + (Printf.sprintf "uid=%d" uid)::list + else list + in + let list = + if valid.Valid.gid + then + let gid = Unsigned.UInt32.to_int (getf t T.gid) in + (Printf.sprintf "gid=%d" gid)::list + else list + in + let list = + if valid.Valid.size + then + let size = Unsigned.UInt64.to_int64 (getf t T.size) in + (Printf.sprintf "size=%Ld" size)::list + else list + in + let list = + if valid.Valid.atime + then + let atime = Unsigned.UInt64.to_int64 (getf t T.atime) in + (Printf.sprintf "atime=%Ld" atime)::list + else list + in + let list = + if valid.Valid.atime_now + then (Printf.sprintf "atime_now")::list + else list + in + let list = + if valid.Valid.mtime + then + let mtime = Unsigned.UInt64.to_int64 (getf t T.mtime) in + (Printf.sprintf "mtime=%Ld" mtime)::list + else list + in + let list = + if valid.Valid.mtime_now + then (Printf.sprintf "mtime_now")::list + else list + in + let list = + if valid.Valid.fh + then + let fh = Unsigned.UInt64.to_int64 (getf t T.fh) in + (Printf.sprintf "fh=%Ld" fh)::list + else list + in + let list = + if valid.Valid.ctime + then + let ctime = Unsigned.UInt64.to_int64 (getf t T.ctime) in + (Printf.sprintf "ctime=%Ld" ctime)::list + else list + in + let list = + if valid.Valid.lock_owner + then + let mtime = Unsigned.UInt64.to_int64 (getf t T.lock_owner) in + (Printf.sprintf "lock_owner=%Ld" mtime)::list + else list + in + if valid.Valid.unknown = Int32.zero + then list + else (Printf.sprintf "unknown[0x%lx]" valid.Valid.unknown)::list + end + + module Getxattr = struct + module T = T.Getxattr + + let create_from_hdr ~size hdr = + let pkt = Hdr.make_from_hdr hdr T.t in + setf pkt T.size size; + CArray.from_ptr (coerce (ptr T.t) (ptr char) (addr pkt)) (sizeof T.t) + + let name p = coerce (ptr char) string (from_voidp char p +@ sizeof T.t) + end + + module Setxattr = struct + module T = T.Setxattr + + let create_from_hdr ~size ~flags hdr = + let pkt = Hdr.make_from_hdr hdr T.t in + setf pkt T.size size; + setf pkt T.flags flags; + CArray.from_ptr (coerce (ptr T.t) (ptr char) (addr pkt)) (sizeof T.t) + + let name p = coerce (ptr char) string (from_voidp char p +@ sizeof T.t) + end + + module Batch_forget = struct + module T = T.Batch_forget + end + + module Message = struct + type t = + | Init of Init.T.t structure + | Getattr + | Lookup of string + | Opendir of Open.T.t structure + | Readdir of Read.T.t structure + | Releasedir of Release.T.t structure + | Fsyncdir of Fsync.T.t structure + | Rmdir of string + | Getxattr of Getxattr.T.t structure * string + | Setxattr of Setxattr.T.t structure * string + | Listxattr of Getxattr.T.t structure + | Removexattr of string + | Access of Access.T.t structure + | Forget of Forget.T.t structure + | Readlink + | Open of Open.T.t structure + | Read of Read.T.t structure + | Write of Write.T.t structure * char Ctypes.ptr + | Statfs + | Flush of Flush.T.t structure + | Release of Release.T.t structure + | Fsync of Fsync.T.t structure + | Unlink of string + | Create of Create.T.t structure * string + | Mknod of Mknod.T.t structure * string + | Mkdir of Mkdir.T.t structure * string + | Setattr of Setattr.T.t structure + | Link of Link.T.t structure * string + | Symlink of string * string + | Rename of Rename.T.t structure * string * string + | Getlk of Lk.T.t structure + | Setlk of Lk.T.t structure + | Setlkw of Lk.T.t structure + | Interrupt of Interrupt.T.t structure + | Bmap of Bmap.T.t structure + | Batch_forget of Struct.Forget_one.T.t structure list + | Destroy + | Other of Opcode.t + | Unknown of int32 + + let unknown i = Unknown i + + let parse chan hdr len buf = + let opcode = Opcode.of_uint32 Hdr.(getf hdr T.opcode) in + {chan; hdr; pkt=Opcode.(match opcode with + | `FUSE_INIT -> Init (!@ (from_voidp Init.T.t buf)) + | `FUSE_GETATTR -> Getattr + | `FUSE_LOOKUP -> Lookup (coerce (ptr void) string buf) + | `FUSE_OPENDIR -> Opendir (!@ (from_voidp Open.T.t buf)) + | `FUSE_READDIR -> Readdir (!@ (from_voidp Read.T.t buf)) + | `FUSE_RELEASEDIR -> Releasedir (!@ (from_voidp Release.T.t buf)) + | `FUSE_FSYNCDIR -> Fsyncdir (!@ (from_voidp Fsync.T.t buf)) + | `FUSE_RMDIR -> Rmdir (coerce (ptr void) string buf) + | `FUSE_MKDIR -> + let name = Mkdir.name buf in + let s = !@ (from_voidp Mkdir.T.t buf) in + Mkdir (s, name) + | `FUSE_GETXATTR -> + let name = Getxattr.name buf in + let s = !@ (from_voidp Getxattr.T.t buf) in + Getxattr (s, name) + | `FUSE_SETXATTR -> + let name = Setxattr.name buf in + let s = !@ (from_voidp Setxattr.T.t buf) in + Setxattr (s, name) + | `FUSE_LISTXATTR -> Listxattr (!@ (from_voidp Getxattr.T.t buf)) + | `FUSE_REMOVEXATTR -> Removexattr (coerce (ptr void) string buf) + | `FUSE_ACCESS -> Access (!@ (from_voidp Access.T.t buf)) + | `FUSE_FORGET -> Forget (!@ (from_voidp Forget.T.t buf)) + | `FUSE_READLINK -> Readlink + | `FUSE_OPEN -> Open (!@ (from_voidp Open.T.t buf)) + | `FUSE_READ -> Read (!@ (from_voidp Read.T.t buf)) + | `FUSE_WRITE -> + let data = Write.data buf in + Write (!@ (from_voidp Write.T.t buf), data) + | `FUSE_STATFS -> Statfs + | `FUSE_FLUSH -> Flush (!@ (from_voidp Flush.T.t buf)) + | `FUSE_RELEASE -> Release (!@ (from_voidp Release.T.t buf)) + | `FUSE_FSYNC -> Fsync (!@ (from_voidp Fsync.T.t buf)) + | `FUSE_UNLINK -> Unlink (coerce (ptr void) string buf) + | `FUSE_CREATE -> + let name = Create.name buf in + let s = !@ (from_voidp Create.T.t buf) in + Create (s, name) + | `FUSE_MKNOD -> + let name = Mknod.name buf in + let s = !@ (from_voidp Mknod.T.t buf) in + Mknod (s, name) + | `FUSE_SETATTR -> Setattr (!@ (from_voidp Setattr.T.t buf)) + | `FUSE_LINK -> + let name = Link.name buf in + let s = !@ (from_voidp Link.T.t buf) in + Link (s, name) + | `FUSE_SYMLINK -> + let name = coerce (ptr void) string buf in + let buf = + to_voidp ((from_voidp char buf) +@ (String.length name + 1)) + in + let target = coerce (ptr void) string buf in + Symlink (name,target) + | `FUSE_RENAME -> + let (src, dest) = Rename.source_destination buf in + let s = !@ (from_voidp Rename.T.t buf) in + Rename (s,src,dest) + | `FUSE_GETLK -> Getlk (!@ (from_voidp Lk.T.t buf)) + | `FUSE_SETLK -> Setlk (!@ (from_voidp Lk.T.t buf)) + | `FUSE_SETLKW -> Setlkw (!@ (from_voidp Lk.T.t buf)) + | `FUSE_INTERRUPT -> Interrupt (!@ (from_voidp Interrupt.T.t buf)) + | `FUSE_BMAP -> Bmap (!@ (from_voidp Bmap.T.t buf)) + | `FUSE_BATCH_FORGET -> + let batch_forget = !@ (from_voidp Batch_forget.T.t buf) in + let forgets = + match UInt32.to_int (getf batch_forget Batch_forget.T.count) with + | 0 -> [] + | k -> + let head = coerce (ptr void) (ptr Batch_forget.T.t) buf in + let p = to_voidp (head +@ 1) in + let first = coerce (ptr void) (ptr Struct.Forget_one.T.t) p in + CArray.(to_list (from_ptr first k)) + in + Batch_forget forgets + | `FUSE_DESTROY -> Destroy + + | `CUSE_INIT -> Other opcode + | `FUSE_NOTIFY_REPLY -> Other opcode + | `FUSE_RENAME2 -> Other opcode + | `FUSE_READDIRPLUS -> Other opcode + | `FUSE_FALLOCATE -> Other opcode + | `FUSE_IOCTL -> Other opcode + | `FUSE_POLL -> Other opcode + + | `Unknown i -> unknown i + )} + + let string_of_mode req mode = + let sys_stat = req.chan.host.Host.sys_stat in + let host = sys_stat.Sys_stat.Host.mode in + let open Sys_stat.Mode in + Printf.sprintf "%s (%x)" + (to_string ~host (of_code_exn ~host mode)) + mode + + let string_of_perms req perms = + let sys_stat = req.chan.host.Host.sys_stat in + let host = sys_stat.Sys_stat.Host.file_perm in + let open Sys_stat.File_perm in + to_string ~host (full_of_code ~host perms) + + let describe req = + let module Hdr = Hdr.T in + Printf.sprintf "%Ld (%Ld) %s.p%ld.u%ld.g%ld %s" + (UInt64.to_int64 (getf req.hdr Hdr.unique)) + (UInt64.to_int64 (getf req.hdr Hdr.nodeid)) + (Opcode.to_string (Opcode.of_uint32 (getf req.hdr Hdr.opcode))) + (UInt32.to_int32 (getf req.hdr Hdr.pid)) + (UInt32.to_int32 (getf req.hdr Hdr.uid)) + (UInt32.to_int32 (getf req.hdr Hdr.gid)) + (match req.pkt with + | Init i -> + Printf.sprintf "version=%d.%d max_readahead=%d flags=0x%lX" + (UInt32.to_int (getf i Init.T.major)) + (UInt32.to_int (getf i Init.T.minor)) + (UInt32.to_int (getf i Init.T.max_readahead)) + (Unsigned.UInt32.to_int32 (getf i Init.T.flags)) + | Getattr | Readlink | Statfs | Destroy -> "" + | Symlink (name,target) -> name ^ " -> " ^ target + | Forget f -> + Int64.to_string (UInt64.to_int64 (getf f Forget.T.nlookup)) + | Lookup name -> name + | Mkdir (m,name) -> + Printf.sprintf "mode=%s umask=0o%o %s" + (string_of_perms req (UInt32.to_int (getf m Mkdir.T.mode))) + (UInt32.to_int (getf m Mkdir.T.umask)) + name + | Mknod (m,name) -> + Printf.sprintf "mode=%s rdev=%ld umask=0o%o %s" + (string_of_mode req (UInt32.to_int (getf m Mknod.T.mode))) + (Unsigned.UInt32.to_int32 (getf m Mknod.T.rdev)) + (UInt32.to_int (getf m Mknod.T.umask)) + name + | Create (c,name) -> + let host = req.chan.host.Host.fcntl.Fcntl.Host.oflags in + let flags_code = UInt32.to_int (getf c Create.T.flags) in + let flags = Fcntl.Oflags.of_code ~host flags_code in + let flags_s = + String.concat " " (List.map Fcntl.Oflags.to_string flags) + in + Printf.sprintf "flags=[%s] mode=%s %s" + flags_s + (string_of_mode req (UInt32.to_int (getf c Create.T.mode))) + name + | Opendir o + | Open o -> + let host = req.chan.host.Host.fcntl.Fcntl.Host.oflags in + let flags_code = UInt32.to_int (getf o Open.T.flags) in + let flags = Fcntl.Oflags.of_code ~host flags_code in + let flags_s = + String.concat " " (List.map Fcntl.Oflags.to_string flags) + in + Printf.sprintf "flags=[%s]" flags_s + | Setattr s -> + let host = req.chan.host.Host.sys_stat.Sys_stat.Host.file_perm in + Printf.sprintf "0x%lX[%s]" + (UInt32.to_int32 (getf s Setattr.T.valid)) + (String.concat " " (Setattr.to_string_list ~host s)) + | Access a -> + let code = getf a Access.T.mask in + (*let phost = Fuse.(req.chan.host.unistd.Unix_unistd.access) in + let perms = Unix_unistd.Access.(of_code ~host:phost code) in + (List.fold_left Unix.(fun s -> function + | R_OK -> s^"R" | W_OK -> s^"W" | X_OK -> s^"X" | F_OK -> s^"F" + ) "" perms) + *) + (* TODO: fix symbolic host map *) + let perms = string_of_int (UInt32.to_int code) in + let uid = getf req.hdr Hdr.uid in + let gid = getf req.hdr Hdr.gid in + Printf.sprintf "uid:%ld gid:%ld (%s)" + (UInt32.to_int32 uid) + (UInt32.to_int32 gid) + perms + | Unlink name | Rmdir name -> name + | Rename (r,src,dest) -> + let newdir = UInt64.to_string (getf r Rename.T.newdir) in + Printf.sprintf "%s -> %s %s" src newdir dest + | Read r -> + let fh = getf r Read.T.fh in + let offset = getf r Read.T.offset in + let size = getf r Read.T.size in + Printf.sprintf "fh=%Ld offset=%Ld size=%ld" + (UInt64.to_int64 fh) + (UInt64.to_int64 offset) + (UInt32.to_int32 size) + | Write (w,_) -> + let fh = getf w Write.T.fh in + let offset = getf w Write.T.offset in + let size = getf w Write.T.size in + let flags = getf w Write.T.write_flags in + Printf.sprintf "fh=%Ld offset=%Ld size=%ld flags=0x%lx" + (UInt64.to_int64 fh) + (UInt64.to_int64 offset) + (UInt32.to_int32 size) + (UInt32.to_int32 flags) + | Interrupt i -> + let unique = UInt64.to_int64 (getf i Interrupt.T.unique) in + Printf.sprintf "request %Ld" unique + | Readdir r -> + let fh = getf r Read.T.fh in + let offset = getf r Read.T.offset in + let size = getf r Read.T.size in + Printf.sprintf "fh=%Ld offset=%Ld size=%ld" + (UInt64.to_int64 fh) + (UInt64.to_int64 offset) + (UInt32.to_int32 size) + | Release r + | Releasedir r -> + let fh = getf r Release.T.fh in + let flags = getf r Release.T.flags in + let rflags = getf r Release.T.release_flags in + let lock_owner = getf r Release.T.lock_owner in + Printf.sprintf "fh=%s flags=%s release_flags=%s lock_owner=%s" + (UInt64.to_string fh) + (UInt32.to_string flags) + (UInt32.to_string rflags) + (UInt64.to_string lock_owner) + | Getxattr (r, name) -> + let size = getf r Getxattr.T.size in + Printf.sprintf "name=%s size=%ld" + name + (UInt32.to_int32 size) + | Setxattr (r, name) -> + let size = getf r Setxattr.T.size in + let flags = getf r Setxattr.T.flags in + Printf.sprintf "name=%s size=%ld flags=%ld" + name + (UInt32.to_int32 size) + (UInt32.to_int32 flags) + | Listxattr r -> + let size = getf r Getxattr.T.size in + Printf.sprintf "size=%ld" + (UInt32.to_int32 size) + | Removexattr name -> name + | Getlk t -> + Lk.describe t + | Setlk t -> + Lk.describe t + | Setlkw t -> + Lk.describe t + | Link (l,n) -> + Printf.sprintf "oldnodeid=%s %s" + (UInt64.to_string (getf l Link.T.oldnodeid)) + n + | Flush _r -> "FIXME" + | Fsyncdir _r -> "FIXME" + | Fsync _r -> "FIXME" + | Bmap _r -> "FIXME" + | Batch_forget b -> + let forgets = String.concat ", " (List.map (fun forget -> + let id = getf forget Struct.Forget_one.T.nodeid in + let n = getf forget Struct.Forget_one.T.nlookup in + Printf.sprintf "%Ld: %Ld" + (UInt64.to_int64 id) + (UInt64.to_int64 n) + ) b) in + Printf.sprintf "[%s]" forgets + | Other opcode -> "OTHER "^(Opcode.to_string opcode) + | Unknown i -> "UNKNOWN "^(Int32.to_string i) + ) + + end +end + +module Out = struct + module T = Types.Out + + module Hdr = struct + module T = T.Hdr + + module Notify_code = + struct + module T = T.Notify_code + + type t = T.t + + let to_string = function + | `FUSE_NOTIFY_DELETE -> "FUSE_NOTIFY_DELETE" + | `FUSE_NOTIFY_INVAL_ENTRY -> "FUSE_NOTIFY_INVAL_ENTRY" + | `FUSE_NOTIFY_INVAL_INODE -> "FUSE_NOTIFY_INVAL_INODE" + | `FUSE_NOTIFY_POLL -> "FUSE_NOTIFY_POLL" + | `FUSE_NOTIFY_RETRIEVE -> "FUSE_NOTIFY_RETRIEVE" + | `FUSE_NOTIFY_STORE -> "FUSE_NOTIFY_STORE" + + let of_int32 = + let l = List.map (fun (k, v) -> (v, k)) T.enum_values in + fun i -> ListLabels.assoc i l + + let to_int32 v = ListLabels.assoc v T.enum_values + end + + let hdrsz = sizeof T.t + let sz = hdrsz + + let packet ?(nerrno=0l) ~count req = + let bodysz = count in + let count = hdrsz + bodysz in + let pkt = allocate_n char ~count in + let hdr = !@ (coerce (ptr char) (ptr T.t) pkt) in + setf hdr T.len (UInt32.of_int count); + setf hdr T.error nerrno; + setf hdr T.unique (getf req.hdr In.Hdr.T.unique); + CArray.from_ptr (pkt +@ hdrsz) bodysz + + let make req st = + let count = sizeof st in + let pkt = packet ~count req in + !@ (coerce (ptr char) (ptr st) (CArray.start pkt)) + + let set_size pkt sz = + let pktsz = hdrsz + sz in + let hdr = + !@ (coerce (ptr char) (ptr T.t) ((CArray.start pkt) -@ hdrsz)) + in + setf hdr T.len (UInt32.of_int pktsz); + CArray.from_ptr (CArray.start pkt) sz + end + + module Notify = struct + let packet ~code ~count = + let bodysz = count in + let count = Hdr.sz + bodysz in + let pkt = allocate_n char ~count in + let hdr = !@ (coerce (ptr char) (ptr Hdr.T.t) pkt) in + setf hdr Hdr.T.len (UInt32.of_int count); + setf hdr Hdr.T.error code; + setf hdr Hdr.T.unique UInt64.zero; + CArray.from_ptr (pkt +@ Hdr.sz) bodysz + + module Inval_entry = struct + module T = T.Notify_inval_entry + + let hdrsz = sizeof T.t + let struct_size = hdrsz + let size name = hdrsz + (String.length name) + 1 + + let create parent filename = + let code = Hdr.T.Notify_code.fuse_notify_inval_entry in + let pkt = packet ~code ~count:(size filename) in + let p = CArray.start pkt in + let s = !@ (coerce (ptr char) (ptr T.t) p) in + setf s T.parent parent; + setf s T.namelen (UInt32.of_int (String.length filename)); + Memcpy.(unsafe_memcpy ocaml_bytes pointer) + ~src:(Bytes.of_string filename) ~src_off:0 + ~dst:p ~dst_off:hdrsz ~len:(String.length filename); + pkt + + let name p = + (* TODO: check namelen valid? *) + coerce (ptr char) string ((from_voidp char p) +@ struct_size) + + let describe pkt = + Printf.sprintf "under %Ld" (UInt64.to_int64 (getf pkt T.parent)) + end + + module Inval_inode = struct + module T = T.Notify_inval_inode + + let create nodeid offset length = + let code = Hdr.T.Notify_code.fuse_notify_inval_inode in + let pkt = packet ~code ~count:(sizeof T.t) in + let p = CArray.start pkt in + let s = !@ (coerce (ptr char) (ptr T.t) p) in + setf s T.ino nodeid; + setf s T.off offset; + setf s T.len length; + pkt + + let describe pkt = + Printf.sprintf "node %Ld from %Ld for %Ld" + (UInt64.to_int64 (getf pkt T.ino)) + (getf pkt T.off) + (getf pkt T.len) + end + + module Delete = struct + module T = T.Notify_delete + + let hdrsz = sizeof T.t + let struct_size = hdrsz + let size name = hdrsz + (String.length name) + 1 + + let create parent child filename = + let code = Hdr.T.Notify_code.fuse_notify_delete in + let pkt = packet ~code ~count:(size filename) in + let p = CArray.start pkt in + let s = !@ (coerce (ptr char) (ptr T.t) p) in + setf s T.parent parent; + setf s T.child child; + setf s T.namelen (UInt32.of_int (String.length filename)); + Memcpy.(unsafe_memcpy ocaml_bytes pointer) + ~src:(Bytes.of_string filename) ~src_off:0 + ~dst:p ~dst_off:hdrsz ~len:(String.length filename); + pkt + + let name p = + (* TODO: check namelen valid? *) + coerce (ptr char) string ((from_voidp char p) +@ struct_size) + + let describe pkt = + Printf.sprintf "as %Ld / %Ld" + (UInt64.to_int64 (getf pkt T.parent)) + (UInt64.to_int64 (getf pkt T.child)) + end + + type t = + | Delete of string * Delete.T.t structure + | Inval_entry of string * Inval_entry.T.t structure + | Inval_inode of Inval_inode.T.t structure + | Poll (* TODO: do *) + | Retrieve (* TODO: do *) + | Store (* TODO: do *) + + let parse chan hdr len p = + let unique = UInt64.to_int64 (getf hdr Hdr.T.unique) in + assert (unique = 0_L); (* TODO: really?? *) + let code = Hdr.Notify_code.of_int32 (getf hdr Hdr.T.error) in + { chan; hdr; pkt=(match code with + | `FUSE_NOTIFY_DELETE -> + let name = Delete.name p in + let s = !@ (from_voidp Delete.T.t p) in + Delete (name, s) + | `FUSE_NOTIFY_INVAL_INODE -> + let s = !@ (from_voidp Inval_inode.T.t p) in + Inval_inode s + | `FUSE_NOTIFY_POLL -> Poll + | `FUSE_NOTIFY_RETRIEVE -> Retrieve + | `FUSE_NOTIFY_STORE -> Store + | `FUSE_NOTIFY_INVAL_ENTRY -> + let name = Inval_entry.name p in + let s = !@ (from_voidp Inval_entry.T.t p) in + Inval_entry (name, s) + )} + + let describe ({ chan; pkt }) = + match pkt with + | Delete (name, d) -> + Printf.sprintf "DELETE %s %s" name (Delete.describe d) + | Inval_entry (name, i) -> + Printf.sprintf "INVAL_ENTRY %s %s" name (Inval_entry.describe i) + | Inval_inode i -> + Printf.sprintf "INVAL_INODE %s" (Inval_inode.describe i) + | Poll -> "POLL FIXME" (* TODO: more *) + | Retrieve -> "RETRIEVE FIXME" (* TODO: more *) + | Store -> "STORE FIXME" (* TODO: more *) + end + + module Dirent = struct + module T = Struct.T.Dirent + + let hdrsz = sizeof T.t + let struct_size = hdrsz + let size name = hdrsz + 8 * (((String.length name) + 7) / 8) + + let filter_listing listing offset read_limit = + let rec loop acc ~read ~emit = function + | [] -> + acc, read + | (_,_,name,_) :: l when read + size name > read_limit -> + acc, read + | ((_,_,name,_) as ent)::l when offset = 0 || emit -> + loop (ent :: acc) ~read:(read + size name) ~emit l + | (off,_,_,_) :: l -> + loop acc ~read ~emit:(off = offset) l + in loop [] ~read:0 ~emit:false listing + + let store ~ino ~off ~name ~typ dirent = + let p = coerce (ptr T.t) (ptr char) (addr dirent) in + begin + setf dirent T.ino (UInt64.of_int64 ino); + setf dirent T.off (UInt64.of_int off); + setf dirent T.namelen (UInt32.of_int (String.length name)); + setf dirent T.typ (UInt32.of_int (int_of_char typ)); + Memcpy.(unsafe_memcpy ocaml_bytes pointer) + ~src:(Bytes.of_string name) ~src_off:0 + ~dst:p ~dst_off:hdrsz ~len:(String.length name) + end + + let of_list ~host listing offset read_size req = + let phost = host.Host.dirent.Dirent.Host.file_kind in + let listing, count = filter_listing listing offset read_size in + let pkt = Hdr.packet ~count req in + let buf = CArray.start pkt in + let ep = List.fold_left (fun p (off,ino,name,typ) -> + let sz = size name in + let typ = Dirent.File_kind.(to_code ~host:phost typ) in + store ~ino ~off ~name ~typ !@(coerce (ptr char) (ptr T.t) p); + p +@ sz + ) buf (List.rev listing) in + assert (ptr_diff buf ep = count); + pkt + + let to_string ~host dirent = + let phost = host.Host.dirent.Dirent.Host.file_kind in + let ino = UInt64.to_string (getf dirent T.ino) in + let off = UInt64.to_string (getf dirent T.off) in + let typ_i = char_of_int (UInt32.to_int (getf dirent T.typ)) in + let typ = Dirent.File_kind.(to_string (of_code_exn ~host:phost typ_i)) in + let length = UInt32.to_int (getf dirent T.namelen) in + let name = string_from_ptr (CArray.start (getf dirent T.name)) ~length in + Printf.sprintf "{ ino=%s; off=%s; typ=%s; name=\"%s\" }" ino off typ name + + let describe ~host p = + let size = CArray.length p in + let rec collect_dirents dirents p off = + let dirent = !@ (coerce (ptr char) (ptr T.t) p) in + let namelen = UInt32.to_int (getf dirent T.namelen) in + if off = size + then List.rev dirents + else + let length = hdrsz + 8 * ((namelen + 7) / 8) in + collect_dirents (dirent::dirents) (p +@ length) (off + length) + in + let dirents = collect_dirents [] (CArray.start p) 0 in + Printf.sprintf "%d:[ %s ]" + size (String.concat "; " (List.map (to_string ~host) dirents)) + end + + module Readlink = struct + let create ~target req = + let count = String.length target in + let pkt = Hdr.packet ~count req in + let sp = CArray.start pkt in + Memcpy.(unsafe_memcpy ocaml_bytes pointer) + ~src:(Bytes.of_string target) ~src_off:0 + ~dst:sp ~dst_off:0 ~len:count; + pkt + end + + module Read = struct + let allocate ~size req = + Hdr.packet ~count:size req + + let finalize ~size pkt _req = + Hdr.set_size pkt size + + let describe carray = string_of_int (CArray.length carray) + end + + module Write = struct + module T = T.Write + + let create ~size req = + let pkt = Hdr.make req T.t in + setf pkt T.size size; + CArray.from_ptr (coerce (ptr T.t) (ptr char) (addr pkt)) (sizeof T.t) + + let describe pkt = + let size = getf pkt T.size in + Printf.sprintf "size=%ld" (UInt32.to_int32 size) + end + + module Statfs = struct + module T = T.Statfs + + let create + ~blocks ~bfree ~bavail ~files ~ffree ~bsize ~namelen ~frsize req = + let pkt = Hdr.make req T.t in + let st = getf pkt T.st in + Struct.Kstatfs.store + ~blocks ~bfree ~bavail ~files ~ffree ~bsize ~namelen ~frsize st; + CArray.from_ptr (coerce (ptr T.t) (ptr char) (addr pkt)) (sizeof T.t) + + let describe pkt = + let kstatfs = getf pkt T.st in + Struct.Kstatfs.describe kstatfs + end + + module Open = struct + module T = T.Open + + module Flags = struct + module T = T.Flags + type t = { + direct_io : bool; + keep_cache : bool; + nonseekable : bool; + } + + let zero = { direct_io = false; keep_cache = false; nonseekable = false } + + let to_string { direct_io; keep_cache; nonseekable } = + Printf.sprintf "{ direct_io = %b; keep_cache = %b; nonseekable = %b }" + direct_io keep_cache nonseekable + + let to_uint32 { direct_io; keep_cache; nonseekable } = + let open Unsigned.UInt32 in + let open Infix in + (if direct_io then T.fopen_direct_io else zero) lor + (if keep_cache then T.fopen_keep_cache else zero) lor + (if nonseekable then T.fopen_nonseekable else zero) + + let of_uint32 i = + let open Unsigned in + let open UInt32.Infix in + { + direct_io = UInt32.(compare zero (i land T.fopen_direct_io)) = 0; + keep_cache = UInt32.(compare zero (i land T.fopen_keep_cache)) = 0; + nonseekable = UInt32.(compare zero (i land T.fopen_nonseekable)) = 0; + } + end + + let store ~fh ~open_flags mem req = + setf mem T.fh fh; + setf mem T.open_flags (Flags.to_uint32 open_flags); + () + + let create ~fh ~open_flags req = + let pkt = Hdr.make req T.t in + store ~fh ~open_flags pkt req; + CArray.from_ptr (coerce (ptr T.t) (ptr char) (addr pkt)) (sizeof T.t) + + let describe pkt = + Printf.sprintf + "fh=%Ld flags=0x%x" + (UInt64.to_int64 (getf pkt T.fh)) + (UInt32.to_int (getf pkt T.open_flags)) + end + + module Init = struct + module T = T.Init + + let create ~major ~minor ~max_readahead ~flags ~max_write req = + let pkt = Hdr.make req T.t in + setf pkt T.major major; + setf pkt T.minor minor; + setf pkt T.max_readahead max_readahead; + setf pkt T.flags flags; + setf pkt T.max_write max_write; + CArray.from_ptr (coerce (ptr T.t) (ptr char) (addr pkt)) (sizeof T.t) + + let describe pkt = + Printf.sprintf + "version=%d.%d max_readahead=%d flags=0x%lX max_write=%d" + (UInt32.to_int (getf pkt T.major)) + (UInt32.to_int (getf pkt T.minor)) + (UInt32.to_int (getf pkt T.max_readahead)) + (UInt32.to_int32 (getf pkt T.flags)) + (UInt32.to_int (getf pkt T.max_write)) + end + + module Entry = struct + module T = T.Entry + + let sz = sizeof T.t + + let store ~nodeid ~generation ~entry_valid ~attr_valid + ~entry_valid_nsec ~attr_valid_nsec ~store_attr mem req = + setf mem T.nodeid nodeid; + setf mem T.generation generation; + setf mem T.entry_valid entry_valid; + setf mem T.attr_valid attr_valid; + setf mem T.entry_valid_nsec entry_valid_nsec; + setf mem T.attr_valid_nsec attr_valid_nsec; + store_attr (getf mem T.attr); + () + + let create ~nodeid ~generation ~entry_valid ~attr_valid + ~entry_valid_nsec ~attr_valid_nsec ~store_attr req = + let pkt = Hdr.make req T.t in + store ~nodeid ~generation ~entry_valid ~attr_valid + ~entry_valid_nsec ~attr_valid_nsec ~store_attr pkt req; + CArray.from_ptr (coerce (ptr T.t) (ptr char) (addr pkt)) (sizeof T.t) + + let describe ~host pkt = + (* TODO: times? *) + Printf.sprintf + "nodeid=%Ld.%Ld valid=%Ld.%09lds attr={%s}" + (UInt64.to_int64 (getf pkt T.generation)) + (UInt64.to_int64 (getf pkt T.nodeid)) + (UInt64.to_int64 (getf pkt T.entry_valid)) + (UInt32.to_int32 (getf pkt T.entry_valid_nsec)) + (Struct.Attr.describe ~host (getf pkt T.attr)) + end + + module Attr = struct + module T = T.Attr + + let create ~attr_valid ~attr_valid_nsec ~store_attr req = + let pkt = Hdr.make req T.t in + setf pkt T.attr_valid attr_valid; + setf pkt T.attr_valid_nsec attr_valid_nsec; + store_attr (getf pkt T.attr); + CArray.from_ptr (coerce (ptr T.t) (ptr char) (addr pkt)) (sizeof T.t) + + let describe ~host pkt = + Printf.sprintf + "attr_valid=%Ld.%09lds attr={%s}" + (Unsigned.UInt64.to_int64 (getf pkt T.attr_valid)) + (Unsigned.UInt32.to_int32 (getf pkt T.attr_valid_nsec)) + (Struct.Attr.describe ~host (getf pkt T.attr)) + end + + module Create = struct + module T = struct + (* No fuse_create_out structure exists so we synthesize it. *) + type t + let t : t structure typ = structure "fuse_create_out" + let ( -:* ) s x = field t s x + let entry = "entry" -:* Entry.T.t + let open_ = "open" -:* Open.T.t + let () = seal t + end + + let create ~store_entry ~store_open req = + let pkt = Hdr.make req T.t in + store_entry (getf pkt T.entry) req; + store_open (getf pkt T.open_) req; + CArray.from_ptr (coerce (ptr T.t) (ptr char) (addr pkt)) (sizeof T.t) + end + + module Message = struct + type t = + | Init of Init.T.t structure + | Getattr of Attr.T.t structure + | Lookup of Entry.T.t structure + | Opendir of Open.T.t structure + | Readdir of char CArray.t + | Releasedir + | Fsyncdir (* TODO: do *) + | Rmdir + | Mkdir of Entry.T.t structure + | Getxattr (* TODO: do *) + | Setxattr (* TODO: do *) + | Listxattr (* TODO: do *) + | Removexattr (* TODO: do *) + | Access + | Forget (* TODO: should never happen? *) + | Readlink of string + | Open of Open.T.t structure + | Read of char CArray.t + | Write of Write.T.t structure + | Statfs of Struct.Kstatfs.T.t structure + | Flush + | Release + | Fsync + | Unlink + | Create of Entry.T.t structure * Open.T.t structure + | Mknod of Entry.T.t structure + | Setattr of Attr.T.t structure + | Link of Entry.T.t structure + | Symlink of Entry.T.t structure + | Rename + | Getlk (* TODO: do *) + | Setlk (* TODO: do *) + | Setlkw (* TODO: do *) + | Interrupt (* TODO: do *) + | Bmap (* TODO: do *) + | Destroy + | Other of In.Opcode.t + | Unknown of int32 * int * unit ptr + + let unknown opcode len buf = Unknown (opcode, len, buf) + + let parse ({ chan } as req) hdr len buf = + let opcode = In.Opcode.of_uint32 In.Hdr.(getf req.hdr T.opcode) in + {chan; hdr; pkt=In.Opcode.(match opcode with + | `FUSE_INIT -> Init (!@ (from_voidp Init.T.t buf)) + | `FUSE_GETATTR -> Getattr (!@ (from_voidp Attr.T.t buf)) + | `FUSE_LOOKUP -> Lookup (!@ (from_voidp Entry.T.t buf)) + | `FUSE_OPENDIR -> Opendir (!@ (from_voidp Open.T.t buf)) + | `FUSE_READDIR -> + Readdir (CArray.from_ptr (from_voidp char buf) len) + | `FUSE_RELEASEDIR -> Releasedir + | `FUSE_FSYNCDIR -> Fsyncdir + | `FUSE_RMDIR -> Rmdir + | `FUSE_MKDIR -> Mkdir (!@ (from_voidp Entry.T.t buf)) + | `FUSE_GETXATTR -> Getxattr + | `FUSE_SETXATTR -> Setxattr + | `FUSE_LISTXATTR -> Listxattr + | `FUSE_REMOVEXATTR -> Removexattr + | `FUSE_ACCESS -> Access + | `FUSE_FORGET -> Forget + | `FUSE_READLINK -> Readlink (coerce (ptr void) string buf) + | `FUSE_OPEN -> Open (!@ (from_voidp Open.T.t buf)) + | `FUSE_READ -> + Read (CArray.from_ptr (from_voidp char buf) len) + | `FUSE_WRITE -> Write (!@ (from_voidp Write.T.t buf)) + | `FUSE_STATFS -> + let statfs_pkt = !@ (from_voidp Statfs.T.t buf) in + Statfs (getf statfs_pkt Statfs.T.st) + | `FUSE_FLUSH -> Flush + | `FUSE_RELEASE -> Release + | `FUSE_FSYNC -> Fsync + | `FUSE_UNLINK -> Unlink + | `FUSE_CREATE -> + let entry = !@ (from_voidp Entry.T.t buf) in + let ptr = (coerce (ptr void) (ptr char) buf) +@ Entry.sz in + let open_ = !@ (from_voidp Open.T.t (to_voidp ptr)) in + Create (entry, open_) + | `FUSE_MKNOD -> Mknod (!@ (from_voidp Entry.T.t buf)) + | `FUSE_SETATTR -> Setattr (!@ (from_voidp Attr.T.t buf)) + | `FUSE_LINK -> Link (!@ (from_voidp Entry.T.t buf)) + | `FUSE_SYMLINK -> Symlink (!@ (from_voidp Entry.T.t buf)) + | `FUSE_RENAME -> Rename + | `FUSE_GETLK -> Getlk + | `FUSE_SETLK -> Setlk + | `FUSE_SETLKW -> Setlkw + | `FUSE_INTERRUPT -> Interrupt + | `FUSE_BMAP -> Bmap + | `FUSE_DESTROY -> Destroy + + | `CUSE_INIT -> Other opcode + | `FUSE_NOTIFY_REPLY -> Other opcode + | `FUSE_BATCH_FORGET -> Other opcode + | `FUSE_RENAME2 -> Other opcode + | `FUSE_READDIRPLUS -> Other opcode + | `FUSE_FALLOCATE -> Other opcode + | `FUSE_IOCTL -> Other opcode + | `FUSE_POLL -> Other opcode + + | `Unknown opcode -> unknown opcode len buf + )} + + let pnum = ref 0 + let deserialize req len buf = + (*let ca = CArray.from_ptr buf len in + let str = Bytes.create len in + for i = 0 to len - 1 do Bytes.set str i (CArray.get ca i) done; + let fd = Unix.( + openfile ("deserialized_packet_"^(string_of_int !pnum)) + [O_WRONLY;O_CREAT] 0o600 + ) in + let logn = Unix.write fd str 0 len in + assert (logn = len); + let () = Unix.close fd in + incr pnum; + *) + + let hdr_ptr = coerce (ptr char) (ptr Hdr.T.t) buf in + let hdr = !@ hdr_ptr in + let sz = UInt32.to_int (getf hdr Hdr.T.len) in + if len <> sz + then raise ( + ProtocolError + (req.chan, + (Printf.sprintf "Packet has %d bytes but only provided %d" + sz len)) + ); + parse req hdr (sz - Hdr.sz) (to_voidp (buf +@ Hdr.sz)) + + let describe ({ chan; pkt }) = + let host = chan.host in + match pkt with + | Init i -> Init.describe i + | Getattr a -> Attr.describe ~host a + | Lookup e -> Entry.describe ~host e + | Opendir o -> Open.describe o + | Readdir r -> Dirent.describe ~host r + | Releasedir -> "RELEASEDIR" + | Fsyncdir -> "FSYNCDIR" + | Rmdir -> "RMDIR" + | Mkdir e -> Entry.describe ~host e + | Getxattr -> "GETXATTR" + | Setxattr -> "SETXATTR" + | Listxattr -> "LISTXATTR" + | Removexattr -> "REMOVEXATTR" + | Access -> "ACCESS" + | Forget -> "FORGET" + | Readlink r -> r + | Open o -> Open.describe o + | Read r -> Read.describe r + | Write w -> Write.describe w + | Statfs s -> Struct.Kstatfs.describe s + | Flush -> "FLUSH" + | Release -> "RELEASE" + | Fsync -> "FSYNC" + | Unlink -> "UNLINK" + | Create (entry,open_) -> + Printf.sprintf "[%s][%s]" + (Entry.describe ~host entry) (Open.describe open_) + | Mknod e -> Entry.describe ~host e + | Setattr a -> Attr.describe ~host a + | Link e -> Entry.describe ~host e + | Symlink e -> Entry.describe ~host e + | Rename -> "RENAME" + | Getlk -> "GETLK" + | Setlk -> "SETLK" + | Setlkw -> "SETLKW" + | Interrupt -> "INTERRUPT" + | Bmap -> "BMAP" + | Destroy -> "DESTROY" + | Other opcode -> "OTHER ("^(In.Opcode.to_string opcode)^")" + | Unknown (o,l,b) -> "UNKNOWN FIXME" (* TODO: more *) + + end +end + +type 'a request = (In.Hdr.T.t, 'a) packet diff --git a/lib/profuse_7_26.mli b/lib/profuse_7_26.mli new file mode 100644 index 0000000..667b20a --- /dev/null +++ b/lib/profuse_7_26.mli @@ -0,0 +1,641 @@ +include Profuse_signatures.S + +module Types : sig + type 'a structure = 'a Ctypes_static.structure + + open Profuse_signatures.Types_7_23 + module Struct : sig + open Struct + module Kstatfs : Kstatfs + module File_lock : File_lock + module Attr : Attr + module Dirent : Dirent + module Forget_one : Forget_one + end + + module Out : sig + open Out + module Hdr : Hdr + module Notify_inval_entry : Notify_inval_entry + module Notify_inval_inode : Notify_inval_inode + module Notify_delete : Notify_delete + module Write : Write + module Open : Open + module Init : Init + module Entry : Entry with type struct_attr_t := Struct.Attr.t + module Attr : Attr with type struct_attr_t := Struct.Attr.t + module Statfs : Statfs with type struct_kstatfs_t := Struct.Kstatfs.t + module Getxattr : Getxattr + module Lk : Lk with type struct_file_lock_t := Struct.File_lock.t + module Bmap : Bmap + end + + module In : sig + open In + module Opcode : Opcode + module Hdr : Hdr + module Init : Init + module Open : Open + module Read : Read + module Release : Release + module Access : Access + module Forget : Forget + module Flush : Flush + module Create : Create + module Mknod : Mknod + module Mkdir : Mkdir + module Rename : Rename + module Link : Link + module Write : Write + module Fsync : Fsync + module Lk : Lk with type struct_file_lock_t := Struct.File_lock.t + module Interrupt : Interrupt + module Bmap : Bmap + module Setattr : Setattr + module Getxattr : Getxattr + module Setxattr : Setxattr + end +end + +type 'a structure = 'a Types.structure + +module Struct : sig + module T = Types.Struct + module Kstatfs : sig + module T = T.Kstatfs + + val store : + blocks:Unsigned.uint64 -> + bfree:Unsigned.uint64 -> + bavail:Unsigned.uint64 -> + files:Unsigned.uint64 -> + ffree:Unsigned.uint64 -> + bsize:Unsigned.uint32 -> + namelen:Unsigned.uint32 -> + frsize:Unsigned.uint32 -> + T.t structure -> unit + + val create : + blocks:Unsigned.uint64 -> + bfree:Unsigned.uint64 -> + bavail:Unsigned.uint64 -> + files:Unsigned.uint64 -> + ffree:Unsigned.uint64 -> + bsize:Unsigned.uint32 -> + namelen:Unsigned.uint32 -> + frsize:Unsigned.uint32 -> + unit -> T.t structure + end + + module File_lock : sig + module T = T.File_lock + end + + module Attr : sig + module T = T.Attr + + val store : + ino:Unsigned.uint64 -> + size:Unsigned.uint64 -> + blocks:Unsigned.uint64 -> + atime:Unsigned.uint64 -> + mtime:Unsigned.uint64 -> + ctime:Unsigned.uint64 -> + atimensec:Unsigned.uint32 -> + mtimensec:Unsigned.uint32 -> + ctimensec:Unsigned.uint32 -> + mode:Unsigned.uint32 -> + nlink:Unsigned.uint32 -> + uid:Unsigned.uint32 -> + gid:Unsigned.uint32 -> + rdev:Unsigned.uint32 -> + blksize:Unsigned.uint32 -> + T.t structure -> unit + + val create : + ino:Unsigned.uint64 -> + size:Unsigned.uint64 -> + blocks:Unsigned.uint64 -> + atime:Unsigned.uint64 -> + mtime:Unsigned.uint64 -> + ctime:Unsigned.uint64 -> + atimensec:Unsigned.uint32 -> + mtimensec:Unsigned.uint32 -> + ctimensec:Unsigned.uint32 -> + mode:Unsigned.uint32 -> + nlink:Unsigned.uint32 -> + uid:Unsigned.uint32 -> + gid:Unsigned.uint32 -> + rdev:Unsigned.uint32 -> + blksize:Unsigned.uint32 -> + unit -> T.t structure + + val describe : host:Host.t -> T.t structure -> string + + end + + module Forget_one : sig + module T = T.Forget_one + end +end + +module In : sig + module T = Types.In + + module Opcode : sig + module T = T.Opcode + + type t = T.t + + val to_string : t -> string + + val returns : t -> bool + + val of_uint32 : Unsigned.uint32 -> t + + val to_uint32 : t -> Unsigned.uint32 + end + + module Hdr : sig + module T = T.Hdr + + val sz : int + + val packet : + opcode:Opcode.t -> + unique:Unsigned.uint64 -> + nodeid:Unsigned.uint64 -> + uid:Unsigned.uint32 -> + gid:Unsigned.uint32 -> + pid:Unsigned.uint32 -> count:int -> char Ctypes.CArray.t + + val make : + opcode:Opcode.t -> + unique:Unsigned.uint64 -> + nodeid:Unsigned.uint64 -> + uid:Unsigned.uint32 -> + gid:Unsigned.uint32 -> pid:Unsigned.uint32 -> 'a Ctypes.typ -> 'a + + val memcpy : + dest:unit Ctypes.ptr -> src:unit Ctypes.ptr -> int -> unit + + val packet_from_hdr : + T.t structure -> + count:int -> char Ctypes.CArray.t + + val make_from_hdr : + T.t structure -> 'a Ctypes.typ -> 'a + end + + module Init : sig + module T = T.Init + end + + module Open : sig + module T = T.Open + end + + module Read : sig + module T = T.Read + end + + module Release : sig + module T = T.Release + end + + module Access : sig + module T = T.Access + end + + module Forget : sig + module T = T.Forget + end + + module Flush : sig + module T = T.Flush + end + + module Create : sig + module T = T.Create + + val name : unit Ctypes.ptr -> string + end + + module Mknod : sig + module T = T.Mknod + + val name : unit Ctypes.ptr -> string + end + + module Mkdir : sig + module T = T.Mkdir + + val name : unit Ctypes.ptr -> string + end + + module Rename : sig + module T = T.Rename + + val source_destination : unit Ctypes.ptr -> string * string + end + + module Link : sig + module T = T.Link + + val name : unit Ctypes.ptr -> string + end + + module Write : sig + module T = T.Write + end + + module Fsync : sig + module T = T.Fsync + end + + module Lk : sig + module T = T.Lk + end + + module Interrupt : sig + module T = T.Interrupt + end + + module Bmap : sig + module T = T.Bmap + end + + module Setattr : sig + module T = T.Setattr + + module Valid : sig + module T = T.Valid + + type t = { + mode : bool; + uid : bool; + gid : bool; + size : bool; + atime : bool; + mtime : bool; + fh : bool; + unknown : int32; + atime_now : bool; + mtime_now : bool; + lock_owner : bool; + ctime : bool; + } + + val to_string_list : t -> string list + + val of_uint32 : Unsigned.uint32 -> t + + val to_uint32 : t -> Unsigned.uint32 + end + + val create_from_hdr : + valid:Unsigned.uint32 -> + fh:Unsigned.uint64 -> + size:Unsigned.uint64 -> + atime:Unsigned.uint64 -> + mtime:Unsigned.uint64 -> + atimensec:Unsigned.uint32 -> + mtimensec:Unsigned.uint32 -> + mode:Unsigned.uint32 -> + uid:Unsigned.uint32 -> + gid:Unsigned.uint32 -> + lock_owner:Unsigned.uint64 -> + ctime:Unsigned.uint64 -> + ctimensec:Unsigned.uint32 -> + Hdr.T.t structure -> char Ctypes.CArray.t + end + + module Getxattr : sig + module T = T.Getxattr + + val create_from_hdr : + size:Unsigned.uint32 -> + Hdr.T.t structure -> char Ctypes.CArray.t + end + + module Setxattr : sig + module T = T.Setxattr + + val create_from_hdr : + size:Unsigned.uint32 -> + flags:Unsigned.uint32 -> + Hdr.T.t structure -> char Ctypes.CArray.t + end + + module Message : sig + type t = + | Init of Init.T.t Ctypes.structure + | Getattr + | Lookup of string + | Opendir of Open.T.t Ctypes.structure + | Readdir of Read.T.t Ctypes.structure + | Releasedir of Release.T.t Ctypes.structure + | Fsyncdir of Fsync.T.t Ctypes.structure + | Rmdir of string + | Getxattr of Getxattr.T.t Ctypes.structure * string + | Setxattr of Setxattr.T.t Ctypes.structure * string + | Listxattr of Getxattr.T.t Ctypes.structure + | Removexattr of string + | Access of Access.T.t Ctypes.structure + | Forget of Forget.T.t Ctypes.structure + | Readlink + | Open of Open.T.t Ctypes.structure + | Read of Read.T.t Ctypes.structure + | Write of Write.T.t structure * char Ctypes.ptr + | Statfs + | Flush of Flush.T.t Ctypes.structure + | Release of Release.T.t Ctypes.structure + | Fsync of Fsync.T.t Ctypes.structure + | Unlink of string + | Create of Create.T.t Ctypes.structure * string + | Mknod of Mknod.T.t Ctypes.structure * string + | Mkdir of Mkdir.T.t Ctypes.structure * string + | Setattr of Setattr.T.t Ctypes.structure + | Link of Link.T.t Ctypes.structure * string + | Symlink of string * string + | Rename of Rename.T.t Ctypes.structure * string * string + | Getlk of Lk.T.t Ctypes.structure + | Setlk of Lk.T.t Ctypes.structure + | Setlkw of Lk.T.t Ctypes.structure + | Interrupt of Interrupt.T.t Ctypes.structure + | Bmap of Bmap.T.t Ctypes.structure + | Batch_forget of Struct.Forget_one.T.t structure list + | Destroy + | Other of Opcode.t + | Unknown of int32 + + val parse : + chan -> Hdr.T.t Ctypes.structure -> int -> unit Ctypes.ptr + -> (Hdr.T.t, t) packet + + val describe : (Hdr.T.t, t) packet -> string + end +end + +type 'a request = (In.Hdr.T.t, 'a) packet + +module Out : sig + module T = Types.Out + + module Hdr : sig + module T = T.Hdr + + module Notify_code : sig + module T = T.Notify_code + + type t = T.t + + val of_int32 : int32 -> t + val to_int32 : t -> int32 + val to_string : t -> string + end + + val sz : int + + val packet : + ?nerrno:int32 -> + count:int -> 'a request -> char Ctypes.CArray.t + + val make : 'a request -> 'b Ctypes.typ -> 'b + + val set_size : char Ctypes.CArray.t -> int -> char Ctypes.CArray.t + end + + module Notify : sig + module Inval_entry : sig + module T = T.Notify_inval_entry + + val struct_size : int + val size : string -> int + + val create : Unsigned.UInt64.t -> string -> char Ctypes.CArray.t + end + + module Inval_inode : sig + module T = T.Notify_inval_inode + + val create : Unsigned.UInt64.t -> int64 -> int64 -> char Ctypes.CArray.t + end + + module Delete : sig + module T = T.Notify_delete + + val struct_size : int + val size : string -> int + + val create : + Unsigned.UInt64.t -> Unsigned.UInt64.t -> string -> + char Ctypes.CArray.t + end + + type t = + | Delete of string * Delete.T.t structure + | Inval_entry of string * Inval_entry.T.t structure + | Inval_inode of Inval_inode.T.t structure + | Poll (* TODO: do *) + | Retrieve (* TODO: do *) + | Store (* TODO: do *) + + val packet : code:int32 -> count:int -> char Ctypes.CArray.t + + val parse : + chan -> Hdr.T.t Ctypes.structure -> int -> unit Ctypes.ptr + -> (Hdr.T.t, t) packet + + val describe : ('a, t) packet -> string + end + + module Dirent : sig + module T = Struct.T.Dirent + + val struct_size : int + + val size : string -> int + + val of_list : + host:Host.t -> + (int * int64 * string * Dirent.File_kind.t) list -> + int -> int -> 'a request -> char Ctypes.CArray.t + end + + module Readlink : sig + val create : + target:string -> 'a request -> char Ctypes.CArray.t + end + + module Read : sig + val allocate : size:int -> 'a request -> char Ctypes.CArray.t + + val finalize : + size:int -> char Ctypes.CArray.t -> 'a request -> char Ctypes.CArray.t + + val describe : char Ctypes.CArray.t -> string + end + + module Write : sig + module T = T.Write + + val create : size:Unsigned.uint32 -> 'a request -> char Ctypes.CArray.t + end + + module Statfs : sig + module T = T.Statfs + + val create : + blocks:Unsigned.uint64 -> + bfree:Unsigned.uint64 -> + bavail:Unsigned.uint64 -> + files:Unsigned.uint64 -> + ffree:Unsigned.uint64 -> + bsize:Unsigned.uint32 -> + namelen:Unsigned.uint32 -> + frsize:Unsigned.uint32 -> + 'a request -> char Ctypes.CArray.t + end + + module Open : sig + module T = T.Open + + module Flags : sig + module T = T.Flags + type t = { + direct_io : bool; + keep_cache : bool; + nonseekable : bool; + } + + val zero : t + + val of_uint32 : Unsigned.uint32 -> t + val to_uint32 : t -> Unsigned.uint32 + val to_string : t -> string + end + + val store : + fh:Unsigned.uint64 -> + open_flags:Flags.t -> + T.t structure -> 'a -> unit + + val create : + fh:Unsigned.uint64 -> + open_flags:Flags.t -> + 'a request -> char Ctypes.CArray.t + end + + module Init : sig + module T = T.Init + + val create : + major:Unsigned.uint32 -> + minor:Unsigned.uint32 -> + max_readahead:Unsigned.uint32 -> + flags:Unsigned.uint32 -> + max_write:Unsigned.uint32 -> + 'a request -> char Ctypes.CArray.t + val describe : T.t structure -> string + end + + module Entry : sig + module T = T.Entry + + val store : + nodeid:Unsigned.uint64 -> + generation:Unsigned.uint64 -> + entry_valid:Unsigned.uint64 -> + attr_valid:Unsigned.uint64 -> + entry_valid_nsec:Unsigned.uint32 -> + attr_valid_nsec:Unsigned.uint32 -> + store_attr:(Types.Struct.Attr.t structure -> unit) -> + T.t structure -> 'a -> unit + + val create : + nodeid:Unsigned.uint64 -> + generation:Unsigned.uint64 -> + entry_valid:Unsigned.uint64 -> + attr_valid:Unsigned.uint64 -> + entry_valid_nsec:Unsigned.uint32 -> + attr_valid_nsec:Unsigned.uint32 -> + store_attr:(Types.Struct.Attr.t structure -> unit) -> + 'a request -> char Ctypes.CArray.t + + val describe : host:Host.t -> T.t structure -> string + end + + module Attr : sig + module T = T.Attr + + val create : + attr_valid:Unsigned.uint64 -> + attr_valid_nsec:Unsigned.uint32 -> + store_attr:(Types.Struct.Attr.t structure -> unit) -> + 'a request -> char Ctypes.CArray.t + end + + module Create : sig + module T : sig + type t + val t : t structure Ctypes.typ + + val entry : (Types.Out.Entry.t structure, t structure) Ctypes.field + val open_ : (Types.Out.Open.t structure, t structure) Ctypes.field + end + + val create : + store_entry:(Entry.T.t structure -> 'a request -> unit) + -> store_open:(Open.T.t structure -> 'a request -> unit) + -> 'a request -> char Ctypes.CArray.t + end + + module Message : sig + type t = + | Init of Init.T.t structure + | Getattr of Attr.T.t structure + | Lookup of Entry.T.t structure + | Opendir of Open.T.t structure + | Readdir of char Ctypes.CArray.t + | Releasedir + | Fsyncdir (* TODO: do *) + | Rmdir + | Mkdir of Entry.T.t structure + | Getxattr (* TODO: do *) + | Setxattr (* TODO: do *) + | Listxattr (* TODO: do *) + | Removexattr (* TODO: do *) + | Access + | Forget (* TODO: should never happen? *) + | Readlink of string + | Open of Open.T.t structure + | Read of char Ctypes.CArray.t + | Write of Write.T.t structure + | Statfs of Struct.Kstatfs.T.t structure + | Flush + | Release + | Fsync + | Unlink + | Create of Entry.T.t structure * Open.T.t structure + | Mknod of Entry.T.t structure + | Setattr of Attr.T.t structure + | Link of Entry.T.t structure + | Symlink of Entry.T.t structure + | Rename + | Getlk (* TODO: do *) + | Setlk (* TODO: do *) + | Setlkw (* TODO: do *) + | Interrupt (* TODO: do *) + | Bmap (* TODO: do *) + | Destroy + | Other of In.Opcode.t + | Unknown of int32 * int * unit Ctypes.ptr + + val deserialize : + (In.Hdr.T.t, 'a) packet -> int -> char Ctypes.ptr + -> (Hdr.T.t, t) packet + + val describe : ('a,t) packet -> string + end +end From 6dfbfd78c0e4f7c284736384879a5ad4de0f927b Mon Sep 17 00:00:00 2001 From: David Scott Date: Thu, 25 Jan 2018 17:26:35 +0000 Subject: [PATCH 5/7] Expose a Profuse_7_26 signature The new operation (`lseek`) is not yet implemented. Signed-off-by: David Scott --- lib/profuse_7_26.ml | 6 ++- lib/profuse_7_26.mli | 2 +- lib/profuse_signatures.ml | 92 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/lib/profuse_7_26.ml b/lib/profuse_7_26.ml index 34e40ac..98a4e17 100644 --- a/lib/profuse_7_26.ml +++ b/lib/profuse_7_26.ml @@ -17,7 +17,7 @@ open Ctypes open Unsigned -module Types = Profuse_types_7_23.C(Profuse_types_detected_7_23) +module Types = Profuse_types_7_26.C(Profuse_types_detected_7_26) type 'a structure = 'a Types.structure @@ -245,6 +245,7 @@ module In = struct | `FUSE_SYMLINK -> "FUSE_SYMLINK" | `FUSE_UNLINK -> "FUSE_UNLINK" | `FUSE_WRITE -> "FUSE_WRITE" + | `FUSE_LSEEK -> "FUSE_LSEEK" | `Unknown i -> "UnknownOpcode("^(Int32.to_string i)^")" let returns = function @@ -773,7 +774,7 @@ module In = struct | `FUSE_FALLOCATE -> Other opcode | `FUSE_IOCTL -> Other opcode | `FUSE_POLL -> Other opcode - + | `FUSE_LSEEK -> Other opcode | `Unknown i -> unknown i )} @@ -1502,6 +1503,7 @@ module Out = struct | `FUSE_FALLOCATE -> Other opcode | `FUSE_IOCTL -> Other opcode | `FUSE_POLL -> Other opcode + | `FUSE_LSEEK -> Other opcode | `Unknown opcode -> unknown opcode len buf )} diff --git a/lib/profuse_7_26.mli b/lib/profuse_7_26.mli index 667b20a..4bceb56 100644 --- a/lib/profuse_7_26.mli +++ b/lib/profuse_7_26.mli @@ -3,7 +3,7 @@ include Profuse_signatures.S module Types : sig type 'a structure = 'a Ctypes_static.structure - open Profuse_signatures.Types_7_23 + open Profuse_signatures.Types_7_26 module Struct : sig open Struct module Kstatfs : Kstatfs diff --git a/lib/profuse_signatures.ml b/lib/profuse_signatures.ml index f01d853..d1966c6 100644 --- a/lib/profuse_signatures.ml +++ b/lib/profuse_signatures.ml @@ -710,3 +710,95 @@ struct module type Bmap = Bmap end end + + +module Types_7_26 = +struct + type 'a structure = 'a Ctypes_static.structure + module Struct = Types_7_23.Struct + + module In = + struct + open Types_7_23.In + type opcode_t = [ + Types_7_23.In.opcode_t + | `FUSE_LSEEK + ] + module type Opcode_ops = + sig + include Opcode_ops + val fuse_lseek : Unsigned.uint32 + end + module type Opcode = sig + type t = opcode_t + include Opcode_ops + + end + module type Hdr = Hdr + module type Init_flags = sig + include Init_flags + val fuse_parallel_dirops : Unsigned.uint32 + val fuse_handle_killpriv : Unsigned.uint32 + val fuse_posix_acl : Unsigned.uint32 + end + module type Init = sig + module Flags : Init_flags + include Types_7_8.In.Init_ + end + module type Open = Open + module type Read = Read + module type Release = Release + module type Access = Access + module type Forget = Forget + module type Flush = Flush + module type Create = Create + module type Mknod = Mknod + module type Mkdir = Mkdir + module type Rename = Rename + module type Link = Link + module type Write = Write + module type Fsync = Fsync + module type Lk = Lk + module type Interrupt = Interrupt + module type Bmap = Bmap + module type Setattr_valid = Setattr_valid + module type Setattr = Setattr + module type Getxattr = Getxattr + module type Setxattr = Setxattr + module type Lseek = sig + type t + val t : t structure Ctypes.typ + + val fh : (Unsigned.uint64, t structure) Ctypes.field + val offset : (Unsigned.uint64, t structure) Ctypes.field + val whence : (Unsigned.uint32, t structure) Ctypes.field + val padding : (Unsigned.uint32, t structure) Ctypes.field + end + end + module Out = + struct + open Types_7_23.Out + + module type Hdr = Hdr + + module type Notify_inval_entry = Notify_inval_entry + module type Notify_inval_inode = Notify_inval_inode + module type Notify_delete = Notify_delete + module type Write = Write + module type Open_flags = Open_flags + module type Open = Open + module type Init = Init + module type Entry = Entry + module type Attr = Attr + module type Statfs = Statfs + module type Getxattr = Getxattr + module type Lk = Lk + module type Bmap = Bmap + module type Lseek = sig + type t + val t : t structure Ctypes.typ + + val offset : (Unsigned.uint64, t structure) Ctypes.field + end + end +end From 6804c5f0129c930ea0f01ba7c712b8857e40041f Mon Sep 17 00:00:00 2001 From: David Scott Date: Thu, 25 Jan 2018 17:40:58 +0000 Subject: [PATCH 6/7] Set the default version to 7.26 Signed-off-by: David Scott --- lib/fuse.ml | 2 +- lib/fuse.mli | 2 +- lwt/fuse_lwt.ml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/fuse.ml b/lib/fuse.ml index 970c882..55f518a 100644 --- a/lib/fuse.ml +++ b/lib/fuse.ml @@ -15,7 +15,7 @@ * *) -module Profuse = Profuse_7_23 +module Profuse = Profuse_7_26 module Nodes = Nodes diff --git a/lib/fuse.mli b/lib/fuse.mli index 7e29662..23ec998 100644 --- a/lib/fuse.mli +++ b/lib/fuse.mli @@ -1,5 +1,5 @@ -module Profuse = Profuse_7_23 +module Profuse = Profuse_7_26 module Nodes = Nodes diff --git a/lwt/fuse_lwt.ml b/lwt/fuse_lwt.ml index 91021ee..2f34954 100644 --- a/lwt/fuse_lwt.ml +++ b/lwt/fuse_lwt.ml @@ -1,7 +1,7 @@ open Lwt open Ctypes open Unsigned -module Profuse = Profuse_7_23 +module Profuse = Profuse_7_26 open Profuse module type IO_LWT = Fuse.IO with type 'a t = 'a Lwt.t From 343937a9dd4bc8d1b43429f088e7f033f1f4cda1 Mon Sep 17 00:00:00 2001 From: David Scott Date: Thu, 25 Jan 2018 17:50:00 +0000 Subject: [PATCH 7/7] fusedump: set version to 7.26 Signed-off-by: David Scott --- src/fusedump.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fusedump.ml b/src/fusedump.ml index a82a7b8..568b4ba 100644 --- a/src/fusedump.ml +++ b/src/fusedump.ml @@ -17,7 +17,7 @@ let version = "0.5.0" -module Profuse = Profuse_7_23 +module Profuse = Profuse_7_26 type request = Profuse.In.Message.t Profuse.request type reply = (Profuse.Out.Hdr.T.t, Profuse.Out.Message.t) Profuse.packet @@ -204,8 +204,8 @@ let parse_session filename = let minor = int_of_char header.[7] in (if major <> 7 then failf "only FUSE major version 7 supported (not %d)" major - else if minor <> 23 - then failf "only FUSE version 7.23 supported (not 7.%d)" minor); + else if minor <> 26 + then failf "only FUSE version 7.26 supported (not 7.%d)" minor); let host = match header.[5] with | 'L' -> Profuse.Host.linux_4_0_5 | c -> failf "unknown host type '%c'" c