ffi-libfuse 0.0.1.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +1 -0
- data/README.md +100 -0
- data/lib/ffi/accessors.rb +145 -0
- data/lib/ffi/devt.rb +30 -0
- data/lib/ffi/flock.rb +47 -0
- data/lib/ffi/gnu_extensions.rb +115 -0
- data/lib/ffi/libfuse/ackbar.rb +112 -0
- data/lib/ffi/libfuse/adapter/context.rb +37 -0
- data/lib/ffi/libfuse/adapter/debug.rb +89 -0
- data/lib/ffi/libfuse/adapter/fuse2_compat.rb +91 -0
- data/lib/ffi/libfuse/adapter/fuse3_support.rb +87 -0
- data/lib/ffi/libfuse/adapter/interrupt.rb +37 -0
- data/lib/ffi/libfuse/adapter/pathname.rb +23 -0
- data/lib/ffi/libfuse/adapter/ruby.rb +334 -0
- data/lib/ffi/libfuse/adapter/safe.rb +58 -0
- data/lib/ffi/libfuse/adapter/thread_local_context.rb +36 -0
- data/lib/ffi/libfuse/adapter.rb +79 -0
- data/lib/ffi/libfuse/callbacks.rb +61 -0
- data/lib/ffi/libfuse/fuse2.rb +159 -0
- data/lib/ffi/libfuse/fuse3.rb +162 -0
- data/lib/ffi/libfuse/fuse_args.rb +166 -0
- data/lib/ffi/libfuse/fuse_buffer.rb +155 -0
- data/lib/ffi/libfuse/fuse_callbacks.rb +48 -0
- data/lib/ffi/libfuse/fuse_cmdline_opts.rb +44 -0
- data/lib/ffi/libfuse/fuse_common.rb +249 -0
- data/lib/ffi/libfuse/fuse_config.rb +205 -0
- data/lib/ffi/libfuse/fuse_conn_info.rb +211 -0
- data/lib/ffi/libfuse/fuse_context.rb +79 -0
- data/lib/ffi/libfuse/fuse_file_info.rb +100 -0
- data/lib/ffi/libfuse/fuse_loop_config.rb +43 -0
- data/lib/ffi/libfuse/fuse_operations.rb +870 -0
- data/lib/ffi/libfuse/fuse_opt.rb +54 -0
- data/lib/ffi/libfuse/fuse_poll_handle.rb +59 -0
- data/lib/ffi/libfuse/fuse_version.rb +43 -0
- data/lib/ffi/libfuse/job_pool.rb +53 -0
- data/lib/ffi/libfuse/main.rb +200 -0
- data/lib/ffi/libfuse/test/operations.rb +56 -0
- data/lib/ffi/libfuse/test.rb +3 -0
- data/lib/ffi/libfuse/thread_pool.rb +147 -0
- data/lib/ffi/libfuse/version.rb +8 -0
- data/lib/ffi/libfuse.rb +24 -0
- data/lib/ffi/ruby_object.rb +95 -0
- data/lib/ffi/stat/constants.rb +29 -0
- data/lib/ffi/stat/native.rb +50 -0
- data/lib/ffi/stat/time_spec.rb +137 -0
- data/lib/ffi/stat.rb +96 -0
- data/lib/ffi/stat_vfs.rb +81 -0
- data/lib/ffi/struct_array.rb +39 -0
- data/lib/ffi/struct_wrapper.rb +100 -0
- data/sample/memory_fs.rb +189 -0
- data/sample/no_fs.rb +69 -0
- metadata +165 -0
@@ -0,0 +1,205 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../accessors'
|
4
|
+
module FFI
|
5
|
+
module Libfuse
|
6
|
+
#
|
7
|
+
# Configuration of the high-level API
|
8
|
+
#
|
9
|
+
# This structure is initialized from the arguments passed to fuse_new(), and then passed to the file system's init()
|
10
|
+
# handler which should ensure that the configuration is compatible with the file system implementation.
|
11
|
+
#
|
12
|
+
class FuseConfig < FFI::Struct
|
13
|
+
include FFI::Accessors
|
14
|
+
layout(
|
15
|
+
{
|
16
|
+
# @!method set_gid?
|
17
|
+
# @return [Boolean]
|
18
|
+
# @!attribute [r] gid
|
19
|
+
# @return [Integer]
|
20
|
+
# If `set_gid?` is true the st_gid attribute of each file is overwritten with the value of `gid`.
|
21
|
+
#
|
22
|
+
set_gid: :int,
|
23
|
+
gid: :uint,
|
24
|
+
|
25
|
+
# @!method set_uid?
|
26
|
+
# @return [Boolean]
|
27
|
+
# @!attribute [r] uid
|
28
|
+
# @return [Integer]
|
29
|
+
# If `set_uid?' is true the st_uid attribute of each file is overwritten with the value of `uid`.
|
30
|
+
#
|
31
|
+
set_uid: :int,
|
32
|
+
uid: :uint,
|
33
|
+
|
34
|
+
# @!method set_mode?
|
35
|
+
# @return [Boolean]
|
36
|
+
# @!attribute [r] mode
|
37
|
+
# @return [Integer]
|
38
|
+
# If `set_mode?` is true, the any permissions bits set in `umask` are unset in the st_mode attribute of each
|
39
|
+
# file.
|
40
|
+
#
|
41
|
+
set_mode: :int,
|
42
|
+
umask: :uint,
|
43
|
+
#
|
44
|
+
# The timeout in seconds for which name lookups will be
|
45
|
+
# cached.
|
46
|
+
#
|
47
|
+
entry_timeout: :double,
|
48
|
+
#
|
49
|
+
# The timeout in seconds for which a negative lookup will be
|
50
|
+
# cached. This means, that if file did not exist (lookup
|
51
|
+
# retuned ENOENT), the lookup will only be redone after the
|
52
|
+
# timeout, and the file/directory will be assumed to not
|
53
|
+
# exist until then. A value of zero means that negative
|
54
|
+
# lookups are not cached.
|
55
|
+
#
|
56
|
+
negative_timeout: :double,
|
57
|
+
#
|
58
|
+
# The timeout in seconds for which file/directory attributes
|
59
|
+
# (as returned by e.g. the `getattr` handler) are cached.
|
60
|
+
#
|
61
|
+
attr_timeout: :double,
|
62
|
+
#
|
63
|
+
# Allow requests to be interrupted
|
64
|
+
#
|
65
|
+
intr: :int,
|
66
|
+
#
|
67
|
+
# Specify which signal number to send to the filesystem when
|
68
|
+
# a request is interrupted. The default is hardcoded to
|
69
|
+
# USR1.
|
70
|
+
#
|
71
|
+
intr_signal: :int,
|
72
|
+
#
|
73
|
+
# Normally, FUSE assigns inodes to paths only for as long as
|
74
|
+
# the kernel is aware of them. With this option inodes are
|
75
|
+
# instead remembered for at least this many seconds. This
|
76
|
+
# will require more memory, but may be necessary when using
|
77
|
+
# applications that make use of inode numbers.
|
78
|
+
#
|
79
|
+
# A number of -1 means that inodes will be remembered for the
|
80
|
+
# entire life-time of the file-system process.
|
81
|
+
#
|
82
|
+
remember: :int,
|
83
|
+
#
|
84
|
+
# The default behavior is that if an open file is deleted,
|
85
|
+
# the file is renamed to a hidden file (.fuse_hiddenXXX), and
|
86
|
+
# only removed when the file is finally released. This
|
87
|
+
# relieves the filesystem implementation of having to deal
|
88
|
+
# with this problem. This option disables the hiding
|
89
|
+
# behavior, and files are removed immediately in an unlink
|
90
|
+
# operation (or in a rename operation which overwrites an
|
91
|
+
# existing file).
|
92
|
+
#
|
93
|
+
# It is recommended that you not use the hard_remove
|
94
|
+
# option. When hard_remove is set, the following libc
|
95
|
+
# functions fail on unlinked files (returning errno of
|
96
|
+
# ENOENT): read(2), write(2), fsync(2), close(2), f*xattr(2),
|
97
|
+
# ftruncate(2), fstat(2), fchmod(2), fchown(2)
|
98
|
+
#
|
99
|
+
hard_remove: :int,
|
100
|
+
#
|
101
|
+
# Honor the st_ino field in the functions getattr() and
|
102
|
+
# fill_dir(). This value is used to fill in the st_ino field
|
103
|
+
# in the stat(2), lstat(2), fstat(2) functions and the d_ino
|
104
|
+
# field in the readdir(2) function. The filesystem does not
|
105
|
+
# have to guarantee uniqueness, however some applications
|
106
|
+
# rely on this value being unique for the whole filesystem.
|
107
|
+
#
|
108
|
+
# Note that this does *not* affect the inode that libfuse
|
109
|
+
# and the kernel use internally (also called the "nodeid").
|
110
|
+
#
|
111
|
+
use_ino: :int,
|
112
|
+
#
|
113
|
+
# If use_ino option is not given, still try to fill in the
|
114
|
+
# d_ino field in readdir(2). If the name was previously
|
115
|
+
# looked up, and is still in the cache, the inode number
|
116
|
+
# found there will be used. Otherwise it will be set to -1.
|
117
|
+
# If use_ino option is given, this option is ignored.
|
118
|
+
#
|
119
|
+
readdir_ino: :int,
|
120
|
+
#
|
121
|
+
# This option disables the use of page cache (file content cache)
|
122
|
+
# in the kernel for this filesystem. This has several affects:
|
123
|
+
#
|
124
|
+
# 1. Each read(2) or write(2) system call will initiate one
|
125
|
+
# or more read or write operations, data will not be
|
126
|
+
# cached in the kernel.
|
127
|
+
#
|
128
|
+
# 2. The return value of the read() and write() system calls
|
129
|
+
# will correspond to the return values of the read and
|
130
|
+
# write operations. This is useful for example if the
|
131
|
+
# file size is not known in advance (before reading it).
|
132
|
+
#
|
133
|
+
# Internally, enabling this option causes fuse to set the
|
134
|
+
# `direct_io` field of `struct fuse_file_info` - overwriting
|
135
|
+
# any value that was put there by the file system.
|
136
|
+
#
|
137
|
+
direct_io: :int,
|
138
|
+
#
|
139
|
+
# This option disables flushing the cache of the file
|
140
|
+
# contents on every open(2). This should only be enabled on
|
141
|
+
# filesystem where the file data is never changed
|
142
|
+
# externally (not through the mounted FUSE filesystem). Thus
|
143
|
+
# it is not suitable for network filesystem and other
|
144
|
+
# intermediate filesystem.
|
145
|
+
#
|
146
|
+
# NOTE: if this option is not specified (and neither
|
147
|
+
# direct_io) data is still cached after the open(2), so a
|
148
|
+
# read(2) system call will not always initiate a read
|
149
|
+
# operation.
|
150
|
+
#
|
151
|
+
# Internally, enabling this option causes fuse to set the
|
152
|
+
# `keep_cache` field of `struct fuse_file_info` - overwriting
|
153
|
+
# any value that was put there by the file system.
|
154
|
+
#
|
155
|
+
kernel_cache: :int,
|
156
|
+
#
|
157
|
+
# This option is an alternative to `kernel_cache`. Instead of
|
158
|
+
# unconditionally keeping cached data, the cached data is
|
159
|
+
# invalidated on open(2) if if the modification time or the
|
160
|
+
# size of the file has changed since it was last opened.
|
161
|
+
#
|
162
|
+
auto_cache: :int,
|
163
|
+
#
|
164
|
+
# The timeout in seconds for which file attributes are cached
|
165
|
+
# for the purpose of checking if auto_cache should flush the
|
166
|
+
# file data on open.
|
167
|
+
#
|
168
|
+
ac_attr_timeout_set: :int,
|
169
|
+
ac_attr_timeout: :double,
|
170
|
+
#
|
171
|
+
# If this option is given the file-system handlers for the
|
172
|
+
# following operations will not receive path information:
|
173
|
+
# read, write, flush, release, fsync, readdir, releasedir,
|
174
|
+
# fsyncdir, lock, ioctl and poll.
|
175
|
+
#
|
176
|
+
# For the truncate, getattr, chmod, chown and utimens
|
177
|
+
# operations the path will be provided only if the struct
|
178
|
+
# fuse_file_info argument is NULL.
|
179
|
+
#
|
180
|
+
nullpath_ok: :int,
|
181
|
+
#
|
182
|
+
# The remaining options are used by libfuse internally and
|
183
|
+
# should not be touched.
|
184
|
+
#
|
185
|
+
show_help: :int,
|
186
|
+
modules: :pointer,
|
187
|
+
debug: :int
|
188
|
+
}
|
189
|
+
)
|
190
|
+
|
191
|
+
BOOL_ATTRS = %i[
|
192
|
+
nullpath_ok ac_attr_timeout_set auto_cache kernel_cache direct_io
|
193
|
+
readdir_ino use_ino hard_remove intr set_mode set_uid set_gid
|
194
|
+
].freeze
|
195
|
+
|
196
|
+
ffi_attr_reader(*BOOL_ATTRS)
|
197
|
+
ffi_attr_writer(*BOOL_ATTRS) { |v| v && v != 0 ? 1 : 0 }
|
198
|
+
BOOL_ATTRS.each { |a| define_method("#{a}?") { send(a) != 0 } }
|
199
|
+
|
200
|
+
OTHER_ATTRS = %i[ac_attr_timeout remember intr_signal attr_timeout negative_timeout entry_timeout umask uid
|
201
|
+
gid].freeze
|
202
|
+
ffi_attr_accessor(*OTHER_ATTRS)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'fuse_version'
|
4
|
+
require_relative '../accessors'
|
5
|
+
|
6
|
+
module FFI
|
7
|
+
# Ruby FFI Binding for [libfuse](https://github.com/libfuse/libfuse)
|
8
|
+
module Libfuse
|
9
|
+
# These are constants in fuse_common.h but defined like bitmask
|
10
|
+
#
|
11
|
+
# FUSE_CAP_ASYNC_READ: filesystem supports asynchronous read requests
|
12
|
+
# FUSE_CAP_POSIX_LOCKS: filesystem supports "remote" locking
|
13
|
+
# FUSE_CAP_ATOMIC_O_TRUNC: filesystem handles the O_TRUNC open flag
|
14
|
+
# FUSE_CAP_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
|
15
|
+
# FUSE_CAP_BIG_WRITES: filesystem can handle write size larger than 4kB
|
16
|
+
# FUSE_CAP_DONT_MASK: don't apply umask to file mode on create operations
|
17
|
+
# FUSE_CAP_SPLICE_WRITE: ability to use splice() to write to the fuse device
|
18
|
+
# FUSE_CAP_SPLICE_MOVE: ability to move data to the fuse device with splice()
|
19
|
+
# FUSE_CAP_SPLICE_READ: ability to use splice() to read from the fuse device
|
20
|
+
# FUSE_CAP_FLOCK_LOCKS: ?
|
21
|
+
# FUSE_CAP_IOCTL_DIR: ioctl support on directories
|
22
|
+
|
23
|
+
# FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
|
24
|
+
# FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
|
25
|
+
# FUSE_IOCTL_RETRY: retry with new iovecs
|
26
|
+
# FUSE_IOCTL_DIR: is a directory
|
27
|
+
bitmask :fuse_ioctl, %i[compat unrestricted retry dir]
|
28
|
+
|
29
|
+
# #define FUSE_CAP_ASYNC_READ (1 << 0)
|
30
|
+
# #define FUSE_CAP_POSIX_LOCKS (1 << 1)
|
31
|
+
# #define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
|
32
|
+
# #define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
|
33
|
+
# #define FUSE_CAP_BIG_WRITES (1 << 5)
|
34
|
+
# #define FUSE_CAP_DONT_MASK (1 << 6)
|
35
|
+
# #define FUSE_CAP_SPLICE_WRITE (1 << 7)
|
36
|
+
# #define FUSE_CAP_SPLICE_MOVE (1 << 8)
|
37
|
+
# #define FUSE_CAP_SPLICE_READ (1 << 9)
|
38
|
+
# #define FUSE_CAP_FLOCK_LOCKS (1 << 10)
|
39
|
+
# #define FUSE_CAP_IOCTL_DIR (1 << 11)
|
40
|
+
|
41
|
+
if FUSE_MAJOR_VERSION >= 3
|
42
|
+
bitmask :fuse_cap, %i[
|
43
|
+
async_read posix_locks atomic_o_trunc export_support
|
44
|
+
big_writes dont_mask splice_write splice_move splice_read
|
45
|
+
flock_locks ioctl_dir
|
46
|
+
]
|
47
|
+
else
|
48
|
+
bitmask :fuse_cap, %i[
|
49
|
+
async_read posix_locks atomic_o_trunc export_support
|
50
|
+
dont_mask splice_write splice_move splice_read flock_locks ioctl_dir
|
51
|
+
auto_inval_data readdirplus readdirplus_auto async_dio writeback_cache no_open_support
|
52
|
+
parallel_dirops posix_acl handle_killpriv explicit_inval_data
|
53
|
+
]
|
54
|
+
end
|
55
|
+
#
|
56
|
+
# Connection information
|
57
|
+
#
|
58
|
+
# Some of the elements are read-write, these can be changed to
|
59
|
+
# indicate the value requested by the filesystem. The requested
|
60
|
+
# value must usually be smaller than the indicated value.
|
61
|
+
#
|
62
|
+
# @see FuseOperations#init
|
63
|
+
class FuseConnInfo < FFI::Struct
|
64
|
+
fuse_layout =
|
65
|
+
if FUSE_MAJOR_VERSION >= 3
|
66
|
+
{
|
67
|
+
proto_major: :uint,
|
68
|
+
proto_minor: :uint,
|
69
|
+
max_write: :uint,
|
70
|
+
max_read: :uint,
|
71
|
+
max_readahead: :uint,
|
72
|
+
#
|
73
|
+
# Capability flags that the kernel supports (read-only)
|
74
|
+
#
|
75
|
+
capable: :fuse_cap,
|
76
|
+
#
|
77
|
+
# Capability flags that the filesystem wants to enable.
|
78
|
+
#
|
79
|
+
# libfuse attempts to initialize this field with
|
80
|
+
# reasonable default values before calling the init() handler.
|
81
|
+
#
|
82
|
+
want: :fuse_cap,
|
83
|
+
#
|
84
|
+
# Maximum number of pending "background" requests. A
|
85
|
+
# background request is any type of request for which the
|
86
|
+
# total number is not limited by other means. As of kernel
|
87
|
+
# 4.8, only two types of requests fall into this category:
|
88
|
+
#
|
89
|
+
# 1. Read-ahead requests
|
90
|
+
# 2. Asynchronous direct I/O requests
|
91
|
+
#
|
92
|
+
# Read-ahead requests are generated (if max_readahead is
|
93
|
+
# non-zero) by the kernel to preemptively fill its caches
|
94
|
+
# when it anticipates that userspace will soon read more
|
95
|
+
# data.
|
96
|
+
#
|
97
|
+
# Asynchronous direct I/O requests are generated if
|
98
|
+
# FUSE_CAP_ASYNC_DIO is enabled and userspace submits a large
|
99
|
+
# direct I/O request. In this case the kernel will internally
|
100
|
+
# split it up into multiple smaller requests and submit them
|
101
|
+
# to the filesystem concurrently.
|
102
|
+
#
|
103
|
+
# Note that the following requests are *not* background
|
104
|
+
# requests: writeback requests (limited by the kernel's
|
105
|
+
# flusher algorithm), regular (i.e., synchronous and
|
106
|
+
# buffered) userspace read/write requests (limited to one per
|
107
|
+
# thread), asynchronous read requests (Linux's io_submit(2)
|
108
|
+
# call actually blocks, so these are also limited to one per
|
109
|
+
# thread).
|
110
|
+
#
|
111
|
+
max_background: :uint,
|
112
|
+
#
|
113
|
+
# Kernel congestion threshold parameter. If the number of pending
|
114
|
+
# background requests exceeds this number, the FUSE kernel module will
|
115
|
+
# mark the filesystem as "congested". This instructs the kernel to
|
116
|
+
# expect that queued requests will take some time to complete, and to
|
117
|
+
# adjust its algorithms accordingly (e.g. by putting a waiting thread
|
118
|
+
# to sleep instead of using a busy-loop).
|
119
|
+
#
|
120
|
+
congestion_threshold: :uint,
|
121
|
+
#
|
122
|
+
# When FUSE_CAP_WRITEBACK_CACHE is enabled, the kernel is responsible
|
123
|
+
# for updating mtime and ctime when write requests are received. The
|
124
|
+
# updated values are passed to the filesystem with setattr() requests.
|
125
|
+
# However, if the filesystem does not support the full resolution of
|
126
|
+
# the kernel timestamps (nanoseconds), the mtime and ctime values used
|
127
|
+
# by kernel and filesystem will differ (and result in an apparent
|
128
|
+
# change of times after a cache flush).
|
129
|
+
#
|
130
|
+
# To prevent this problem, this variable can be used to inform the
|
131
|
+
# kernel about the timestamp granularity supported by the file-system.
|
132
|
+
# The value should be power of 10. The default is 1, i.e. full
|
133
|
+
# nano-second resolution. Filesystems supporting only second resolution
|
134
|
+
# should set this to 1000000000.
|
135
|
+
#
|
136
|
+
time_gran: :uint,
|
137
|
+
#
|
138
|
+
# For future use.
|
139
|
+
#
|
140
|
+
reserved: [:uint, 22]
|
141
|
+
}
|
142
|
+
else
|
143
|
+
{
|
144
|
+
proto_major: :uint,
|
145
|
+
proto_minor: :uint,
|
146
|
+
async_read: :uint, # This slot is max_read in Fuse 3
|
147
|
+
max_write: :uint,
|
148
|
+
max_readahead: :uint,
|
149
|
+
capable: :fuse_cap,
|
150
|
+
want: :fuse_cap,
|
151
|
+
max_background: :uint,
|
152
|
+
congestion_threshold: :uint,
|
153
|
+
reserved: [:uint, 23]
|
154
|
+
}
|
155
|
+
end.freeze
|
156
|
+
|
157
|
+
include(FFI::Accessors)
|
158
|
+
|
159
|
+
layout fuse_layout
|
160
|
+
|
161
|
+
# @!attribute [r] proto_major
|
162
|
+
# @return [Integer] Major version of the protocol (read-only)
|
163
|
+
|
164
|
+
# @!attribute [r] proto_minor
|
165
|
+
# @return [Integer] Minor version of the protocol (read-only)
|
166
|
+
|
167
|
+
ffi_attr_reader :proto_major, :proto_minor
|
168
|
+
|
169
|
+
# Is asynchronous read supported (read-write)
|
170
|
+
ffi_attr_accessor :async_read if FUSE_MAJOR_VERSION < 3
|
171
|
+
|
172
|
+
# @!attribute [rw] max_read
|
173
|
+
# @return [Integer] Maximum size of read requests.
|
174
|
+
#
|
175
|
+
# A value of zero indicates no limit. However, even if the filesystem does not specify a limit, the maximum size
|
176
|
+
# of read requests will still be limited by the kernel.
|
177
|
+
#
|
178
|
+
# @note For the time being, the maximum size of read requests must be set both here *and* passed to
|
179
|
+
# using the ``-o max_read=<n>`` mount option. At some point in the future, specifying the mount
|
180
|
+
# option will no longer be necessary.
|
181
|
+
ffi_attr_accessor :max_read if FUSE_MAJOR_VERSION >= 3
|
182
|
+
|
183
|
+
# @!attribute [rw] max_write
|
184
|
+
# @return [Integer] Maximum size of the write buffer
|
185
|
+
|
186
|
+
# @!attribute [rw] max_readahead
|
187
|
+
# @return [Integer] Maximum size of the readahead buffer
|
188
|
+
|
189
|
+
ffi_attr_accessor :max_write, :max_readahead
|
190
|
+
|
191
|
+
# Capability flags that kernel supports
|
192
|
+
ffi_attr_reader :capable
|
193
|
+
|
194
|
+
# Is capable of all of these FUSE_CAPs
|
195
|
+
def capable?(*of)
|
196
|
+
of.all? { |c| self[:capable].include?(c) }
|
197
|
+
end
|
198
|
+
|
199
|
+
# Capability flags that the filesystem wants
|
200
|
+
ffi_attr_accessor :want
|
201
|
+
|
202
|
+
# Maximum number of backgrounded requests
|
203
|
+
ffi_attr_accessor :max_background
|
204
|
+
|
205
|
+
# Kernel congestion threshold parameter
|
206
|
+
ffi_attr_reader :congestion_threshold
|
207
|
+
|
208
|
+
ffi_attr_accessor :time_gran if FUSE_MAJOR_VERSION >= 3
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'fuse_common'
|
4
|
+
require_relative '../ruby_object'
|
5
|
+
require_relative '../accessors'
|
6
|
+
|
7
|
+
module FFI
|
8
|
+
# Ruby FFI Binding for [libfuse](https://github.com/libfuse/libfuse)
|
9
|
+
module Libfuse
|
10
|
+
# Context for each callback operation
|
11
|
+
# @see get
|
12
|
+
class FuseContext < FFI::Struct
|
13
|
+
include FFI::Accessors
|
14
|
+
base = { fuse: :fuse, uid: :uid_t, gid: :gid_t, pid: :pid_t, private_data: RubyObject }
|
15
|
+
base[:umask] = :mode_t if FUSE_VERSION >= 28
|
16
|
+
layout base
|
17
|
+
|
18
|
+
ffi_attr_reader(:uid, :gid, :pid, :mode, :private_data)
|
19
|
+
|
20
|
+
ffi_attr_reader(:umask) if FUSE_VERSION >= 28
|
21
|
+
|
22
|
+
# @!attribute [r] uid
|
23
|
+
# @return [Integer] user id of the calling process
|
24
|
+
|
25
|
+
# @!attribute [r] gid
|
26
|
+
# @return [Integer] group id of the calling process
|
27
|
+
|
28
|
+
# @!attribute [r] pid
|
29
|
+
# @return [Integer] process id of the calling thread
|
30
|
+
|
31
|
+
# @!attribute [r] private_data
|
32
|
+
# @return [Object] private filesystem data
|
33
|
+
# @see FuseOperations#init
|
34
|
+
|
35
|
+
# @!attribute [r] umask
|
36
|
+
# @return [Integer] umask of the calling process
|
37
|
+
|
38
|
+
# @return [Boolean]
|
39
|
+
# @see Libfuse.fuse_interrupted?
|
40
|
+
def interrupted?
|
41
|
+
Libfuse.fuse_interrupted?
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [void]
|
45
|
+
# @raise [Errno::EINTR]
|
46
|
+
# @see Libfuse.raise_interrupt
|
47
|
+
def raise_interrupt
|
48
|
+
Libfuse.raise_interrupt
|
49
|
+
end
|
50
|
+
|
51
|
+
class << self
|
52
|
+
# @return [FuseContext] the context for the current filesystem operation
|
53
|
+
def fuse_get_context
|
54
|
+
Libfuse.fuse_get_context
|
55
|
+
end
|
56
|
+
alias get fuse_get_context
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
attach_function :fuse_get_context, [], FuseContext.by_ref
|
61
|
+
attach_function :fuse_interrupted, [], :int
|
62
|
+
class << self
|
63
|
+
# @return [Boolean] if the fuse request is marked as interrupted
|
64
|
+
def fuse_interrupted?
|
65
|
+
fuse_interrupted != 0
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [void]
|
69
|
+
# @raise [Errno::EINTR] if fuse request is marked as interrupted
|
70
|
+
def raise_interrupt
|
71
|
+
raise Errno::EINTR if fuse_interrupted?
|
72
|
+
end
|
73
|
+
|
74
|
+
# @!visibility private
|
75
|
+
# @!method fuse_get_context
|
76
|
+
# @!method fuse_interrupted
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|