struct fuse_session *se;
-static void pc_init(void *userdata,
- struct fuse_conn_info *conn)
+// Define a structure to hold capability information
+struct cap_info {
+ uint64_t flag;
+ const char *name;
+};
+
+// Define an array of all capabilities
+static const struct cap_info capabilities[] = {
+ {FUSE_CAP_ASYNC_READ, "FUSE_CAP_ASYNC_READ"},
+ {FUSE_CAP_POSIX_LOCKS, "FUSE_CAP_POSIX_LOCKS"},
+ {FUSE_CAP_ATOMIC_O_TRUNC, "FUSE_CAP_ATOMIC_O_TRUNC"},
+ {FUSE_CAP_EXPORT_SUPPORT, "FUSE_CAP_EXPORT_SUPPORT"},
+ {FUSE_CAP_DONT_MASK, "FUSE_CAP_DONT_MASK"},
+ {FUSE_CAP_SPLICE_MOVE, "FUSE_CAP_SPLICE_MOVE"},
+ {FUSE_CAP_SPLICE_READ, "FUSE_CAP_SPLICE_READ"},
+ {FUSE_CAP_SPLICE_WRITE, "FUSE_CAP_SPLICE_WRITE"},
+ {FUSE_CAP_FLOCK_LOCKS, "FUSE_CAP_FLOCK_LOCKS"},
+ {FUSE_CAP_IOCTL_DIR, "FUSE_CAP_IOCTL_DIR"},
+ {FUSE_CAP_AUTO_INVAL_DATA, "FUSE_CAP_AUTO_INVAL_DATA"},
+ {FUSE_CAP_READDIRPLUS, "FUSE_CAP_READDIRPLUS"},
+ {FUSE_CAP_READDIRPLUS_AUTO, "FUSE_CAP_READDIRPLUS_AUTO"},
+ {FUSE_CAP_ASYNC_DIO, "FUSE_CAP_ASYNC_DIO"},
+ {FUSE_CAP_WRITEBACK_CACHE, "FUSE_CAP_WRITEBACK_CACHE"},
+ {FUSE_CAP_NO_OPEN_SUPPORT, "FUSE_CAP_NO_OPEN_SUPPORT"},
+ {FUSE_CAP_PARALLEL_DIROPS, "FUSE_CAP_PARALLEL_DIROPS"},
+ {FUSE_CAP_POSIX_ACL, "FUSE_CAP_POSIX_ACL"},
+ {FUSE_CAP_CACHE_SYMLINKS, "FUSE_CAP_CACHE_SYMLINKS"},
+ {FUSE_CAP_NO_OPENDIR_SUPPORT, "FUSE_CAP_NO_OPENDIR_SUPPORT"},
+ {FUSE_CAP_EXPLICIT_INVAL_DATA, "FUSE_CAP_EXPLICIT_INVAL_DATA"},
+ {FUSE_CAP_EXPIRE_ONLY, "FUSE_CAP_EXPIRE_ONLY"},
+ {FUSE_CAP_SETXATTR_EXT, "FUSE_CAP_SETXATTR_EXT"},
+ {FUSE_CAP_HANDLE_KILLPRIV, "FUSE_CAP_HANDLE_KILLPRIV"},
+ {FUSE_CAP_HANDLE_KILLPRIV_V2, "FUSE_CAP_HANDLE_KILLPRIV_V2"},
+ {FUSE_CAP_DIRECT_IO_ALLOW_MMAP, "FUSE_CAP_DIRECT_IO_ALLOW_MMAP"},
+ {FUSE_CAP_NO_EXPORT_SUPPORT, "FUSE_CAP_NO_EXPORT_SUPPORT"},
+ {FUSE_CAP_PASSTHROUGH, "FUSE_CAP_PASSTHROUGH"},
+ // Add any new capabilities here
+ {0, NULL} // Sentinel to mark the end of the array
+};
+
+static void print_capabilities(struct fuse_conn_info *conn)
+{
+ printf("Capabilities:\n");
+ for (const struct cap_info *cap = capabilities; cap->name != NULL; cap++) {
+ if (fuse_get_feature_flag(conn, cap->flag)) {
+ printf("\t%s\n", cap->name);
+ }
+ }
+}
+
+static void pc_init(void *userdata, struct fuse_conn_info *conn)
{
(void) userdata;
-
+
printf("Protocol version: %d.%d\n", conn->proto_major,
conn->proto_minor);
- printf("Capabilities:\n");
- if(conn->capable & FUSE_CAP_ASYNC_READ)
- printf("\tFUSE_CAP_ASYNC_READ\n");
- if(conn->capable & FUSE_CAP_POSIX_LOCKS)
- printf("\tFUSE_CAP_POSIX_LOCKS\n");
- if(conn->capable & FUSE_CAP_ATOMIC_O_TRUNC)
- printf("\tFUSE_CAP_ATOMIC_O_TRUNC\n");
- if(conn->capable & FUSE_CAP_EXPORT_SUPPORT)
- printf("\tFUSE_CAP_EXPORT_SUPPORT\n");
- if(conn->capable & FUSE_CAP_DONT_MASK)
- printf("\tFUSE_CAP_DONT_MASK\n");
- if(conn->capable & FUSE_CAP_SPLICE_MOVE)
- printf("\tFUSE_CAP_SPLICE_MOVE\n");
- if(conn->capable & FUSE_CAP_SPLICE_READ)
- printf("\tFUSE_CAP_SPLICE_READ\n");
- if(conn->capable & FUSE_CAP_SPLICE_WRITE)
- printf("\tFUSE_CAP_SPLICE_WRITE\n");
- if(conn->capable & FUSE_CAP_FLOCK_LOCKS)
- printf("\tFUSE_CAP_FLOCK_LOCKS\n");
- if(conn->capable & FUSE_CAP_IOCTL_DIR)
- printf("\tFUSE_CAP_IOCTL_DIR\n");
- if(conn->capable & FUSE_CAP_AUTO_INVAL_DATA)
- printf("\tFUSE_CAP_AUTO_INVAL_DATA\n");
- if(conn->capable & FUSE_CAP_READDIRPLUS)
- printf("\tFUSE_CAP_READDIRPLUS\n");
- if(conn->capable & FUSE_CAP_READDIRPLUS_AUTO)
- printf("\tFUSE_CAP_READDIRPLUS_AUTO\n");
- if(conn->capable & FUSE_CAP_ASYNC_DIO)
- printf("\tFUSE_CAP_ASYNC_DIO\n");
- if(conn->capable & FUSE_CAP_WRITEBACK_CACHE)
- printf("\tFUSE_CAP_WRITEBACK_CACHE\n");
- if(conn->capable & FUSE_CAP_NO_OPEN_SUPPORT)
- printf("\tFUSE_CAP_NO_OPEN_SUPPORT\n");
- if(conn->capable & FUSE_CAP_PARALLEL_DIROPS)
- printf("\tFUSE_CAP_PARALLEL_DIROPS\n");
- if(conn->capable & FUSE_CAP_POSIX_ACL)
- printf("\tFUSE_CAP_POSIX_ACL\n");
- if(conn->capable & FUSE_CAP_CACHE_SYMLINKS)
- printf("\tFUSE_CAP_CACHE_SYMLINKS\n");
- if(conn->capable & FUSE_CAP_NO_OPENDIR_SUPPORT)
- printf("\tFUSE_CAP_NO_OPENDIR_SUPPORT\n");
- if(conn->capable & FUSE_CAP_EXPLICIT_INVAL_DATA)
- printf("\tFUSE_CAP_EXPLICIT_INVAL_DATA\n");
- if(conn->capable & FUSE_CAP_EXPIRE_ONLY)
- printf("\tFUSE_CAP_EXPIRE_ONLY\n");
- if(conn->capable & FUSE_CAP_SETXATTR_EXT)
- printf("\tFUSE_CAP_SETXATTR_EXT\n");
- if(conn->capable & FUSE_CAP_HANDLE_KILLPRIV)
- printf("\tFUSE_CAP_HANDLE_KILLPRIV\n");
- if(conn->capable & FUSE_CAP_HANDLE_KILLPRIV_V2)
- printf("\tFUSE_CAP_HANDLE_KILLPRIV_V2\n");
- if(conn->capable & FUSE_CAP_DIRECT_IO_ALLOW_MMAP)
- printf("\tFUSE_CAP_DIRECT_IO_ALLOW_MMAP\n");
- if (conn->capable & FUSE_CAP_NO_EXPORT_SUPPORT)
- printf("\tFUSE_CAP_NO_EXPORT_SUPPORT\n");
+ print_capabilities(conn);
fuse_session_exit(se);
}
perror("mkdtemp");
return 1;
}
-
+
printf("FUSE library version %s\n", fuse_pkgversion());
fuse_lowlevel_version();
goto fallback;
if (se->conn.proto_minor < 14 ||
- !(se->conn.want & FUSE_CAP_SPLICE_WRITE))
+ !(se->conn.want_ext & FUSE_CAP_SPLICE_WRITE))
goto fallback;
llp = fuse_ll_get_pipe(se);
splice_flags = 0;
if ((flags & FUSE_BUF_SPLICE_MOVE) &&
- (se->conn.want & FUSE_CAP_SPLICE_MOVE))
+ (se->conn.want_ext & FUSE_CAP_SPLICE_MOVE))
splice_flags |= SPLICE_F_MOVE;
if (se->io != NULL && se->io->splice_send != NULL) {
if (req->se->op.open)
req->se->op.open(req, nodeid, &fi);
- else if (req->se->conn.want & FUSE_CAP_NO_OPEN_SUPPORT)
+ else if (req->se->conn.want_ext & FUSE_CAP_NO_OPEN_SUPPORT)
fuse_reply_err(req, ENOSYS);
else
fuse_reply_open(req, &fi);
if (req->se->op.opendir)
req->se->op.opendir(req, nodeid, &fi);
- else if (req->se->conn.want & FUSE_CAP_NO_OPENDIR_SUPPORT)
+ else if (req->se->conn.want_ext & FUSE_CAP_NO_OPENDIR_SUPPORT)
fuse_reply_err(req, ENOSYS);
else
fuse_reply_open(req, &fi);
static void do_setxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
struct fuse_session *se = req->se;
- unsigned int xattr_ext = !!(se->conn.want & FUSE_CAP_SETXATTR_EXT);
+ unsigned int xattr_ext = !!(se->conn.want_ext & FUSE_CAP_SETXATTR_EXT);
struct fuse_setxattr_in *arg = (struct fuse_setxattr_in *) inarg;
char *name = xattr_ext ? PARAM(arg) :
(char *)arg + FUSE_COMPAT_SETXATTR_IN_SIZE;
struct fuse_file_info fi;
if (flags & FUSE_IOCTL_DIR &&
- !(req->se->conn.want & FUSE_CAP_IOCTL_DIR)) {
+ !(req->se->conn.want_ext & FUSE_CAP_IOCTL_DIR)) {
fuse_reply_err(req, ENOTTY);
return;
}
return true;
}
+/**
+ * Get the wanted capability flags, converting from old format if necessary
+ * Also applies the first 32 bits of capable_ext to capable
+ *
+ */
+static inline int convert_to_conn_want_ext(struct fuse_conn_info *conn,
+ uint64_t want_ext_default)
+{
+ /* Convert want to want_ext if necessary */
+ if (conn->want != 0) {
+ if (conn->want_ext != want_ext_default) {
+ fuse_log(FUSE_LOG_ERR,
+ "fuse: both 'want' and 'want_ext' are set\n");
+ return -EINVAL;
+ }
+ conn->want_ext |= conn->want;
+ }
+
+ return 0;
+}
+
/* Prevent bogus data races (bogus since "init" is called before
* multi-threading becomes relevant */
static __attribute__((no_sanitize("thread")))
}
se->conn.proto_major = arg->major;
se->conn.proto_minor = arg->minor;
- se->conn.capable = 0;
- se->conn.want = 0;
+ se->conn.capable_ext = 0;
+ se->conn.want_ext = 0;
memset(&outarg, 0, sizeof(outarg));
outarg.major = FUSE_KERNEL_VERSION;
if (inargflags & FUSE_INIT_EXT)
inargflags = inargflags | (uint64_t) arg->flags2 << 32;
if (inargflags & FUSE_ASYNC_READ)
- se->conn.capable |= FUSE_CAP_ASYNC_READ;
+ se->conn.capable_ext |= FUSE_CAP_ASYNC_READ;
if (inargflags & FUSE_POSIX_LOCKS)
- se->conn.capable |= FUSE_CAP_POSIX_LOCKS;
+ se->conn.capable_ext |= FUSE_CAP_POSIX_LOCKS;
if (inargflags & FUSE_ATOMIC_O_TRUNC)
- se->conn.capable |= FUSE_CAP_ATOMIC_O_TRUNC;
+ se->conn.capable_ext |= FUSE_CAP_ATOMIC_O_TRUNC;
if (inargflags & FUSE_EXPORT_SUPPORT)
- se->conn.capable |= FUSE_CAP_EXPORT_SUPPORT;
+ se->conn.capable_ext |= FUSE_CAP_EXPORT_SUPPORT;
if (inargflags & FUSE_DONT_MASK)
- se->conn.capable |= FUSE_CAP_DONT_MASK;
+ se->conn.capable_ext |= FUSE_CAP_DONT_MASK;
if (inargflags & FUSE_FLOCK_LOCKS)
- se->conn.capable |= FUSE_CAP_FLOCK_LOCKS;
+ se->conn.capable_ext |= FUSE_CAP_FLOCK_LOCKS;
if (inargflags & FUSE_AUTO_INVAL_DATA)
- se->conn.capable |= FUSE_CAP_AUTO_INVAL_DATA;
+ se->conn.capable_ext |= FUSE_CAP_AUTO_INVAL_DATA;
if (inargflags & FUSE_DO_READDIRPLUS)
- se->conn.capable |= FUSE_CAP_READDIRPLUS;
+ se->conn.capable_ext |= FUSE_CAP_READDIRPLUS;
if (inargflags & FUSE_READDIRPLUS_AUTO)
- se->conn.capable |= FUSE_CAP_READDIRPLUS_AUTO;
+ se->conn.capable_ext |= FUSE_CAP_READDIRPLUS_AUTO;
if (inargflags & FUSE_ASYNC_DIO)
- se->conn.capable |= FUSE_CAP_ASYNC_DIO;
+ se->conn.capable_ext |= FUSE_CAP_ASYNC_DIO;
if (inargflags & FUSE_WRITEBACK_CACHE)
- se->conn.capable |= FUSE_CAP_WRITEBACK_CACHE;
+ se->conn.capable_ext |= FUSE_CAP_WRITEBACK_CACHE;
if (inargflags & FUSE_NO_OPEN_SUPPORT)
- se->conn.capable |= FUSE_CAP_NO_OPEN_SUPPORT;
+ se->conn.capable_ext |= FUSE_CAP_NO_OPEN_SUPPORT;
if (inargflags & FUSE_PARALLEL_DIROPS)
- se->conn.capable |= FUSE_CAP_PARALLEL_DIROPS;
+ se->conn.capable_ext |= FUSE_CAP_PARALLEL_DIROPS;
if (inargflags & FUSE_POSIX_ACL)
- se->conn.capable |= FUSE_CAP_POSIX_ACL;
+ se->conn.capable_ext |= FUSE_CAP_POSIX_ACL;
if (inargflags & FUSE_HANDLE_KILLPRIV)
- se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV;
+ se->conn.capable_ext |= FUSE_CAP_HANDLE_KILLPRIV;
if (inargflags & FUSE_HANDLE_KILLPRIV_V2)
- se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV_V2;
+ se->conn.capable_ext |= FUSE_CAP_HANDLE_KILLPRIV_V2;
if (inargflags & FUSE_CACHE_SYMLINKS)
- se->conn.capable |= FUSE_CAP_CACHE_SYMLINKS;
+ se->conn.capable_ext |= FUSE_CAP_CACHE_SYMLINKS;
if (inargflags & FUSE_NO_OPENDIR_SUPPORT)
- se->conn.capable |= FUSE_CAP_NO_OPENDIR_SUPPORT;
+ se->conn.capable_ext |= FUSE_CAP_NO_OPENDIR_SUPPORT;
if (inargflags & FUSE_EXPLICIT_INVAL_DATA)
- se->conn.capable |= FUSE_CAP_EXPLICIT_INVAL_DATA;
+ se->conn.capable_ext |= FUSE_CAP_EXPLICIT_INVAL_DATA;
if (inargflags & FUSE_SETXATTR_EXT)
- se->conn.capable |= FUSE_CAP_SETXATTR_EXT;
+ se->conn.capable_ext |= FUSE_CAP_SETXATTR_EXT;
if (!(inargflags & FUSE_MAX_PAGES)) {
size_t max_bufsize =
FUSE_DEFAULT_MAX_PAGES_PER_REQ * getpagesize()
buf_reallocable = false;
}
if (inargflags & FUSE_DIRECT_IO_ALLOW_MMAP)
- se->conn.capable |= FUSE_CAP_DIRECT_IO_ALLOW_MMAP;
+ se->conn.capable_ext |= FUSE_CAP_DIRECT_IO_ALLOW_MMAP;
if (arg->minor >= 38 || (inargflags & FUSE_HAS_EXPIRE_ONLY))
- se->conn.capable |= FUSE_CAP_EXPIRE_ONLY;
+ se->conn.capable_ext |= FUSE_CAP_EXPIRE_ONLY;
if (inargflags & FUSE_PASSTHROUGH)
- se->conn.capable |= FUSE_CAP_PASSTHROUGH;
+ se->conn.capable_ext |= FUSE_CAP_PASSTHROUGH;
if (inargflags & FUSE_NO_EXPORT_SUPPORT)
- se->conn.capable |= FUSE_CAP_NO_EXPORT_SUPPORT;
+ se->conn.capable_ext |= FUSE_CAP_NO_EXPORT_SUPPORT;
} else {
se->conn.max_readahead = 0;
}
#ifdef HAVE_SPLICE
#ifdef HAVE_VMSPLICE
if ((se->io == NULL) || (se->io->splice_send != NULL)) {
- se->conn.capable |= FUSE_CAP_SPLICE_WRITE | FUSE_CAP_SPLICE_MOVE;
+ se->conn.capable_ext |= FUSE_CAP_SPLICE_WRITE |
+ FUSE_CAP_SPLICE_MOVE;
}
#endif
if ((se->io == NULL) || (se->io->splice_receive != NULL)) {
- se->conn.capable |= FUSE_CAP_SPLICE_READ;
+ se->conn.capable_ext |= FUSE_CAP_SPLICE_READ;
}
#endif
}
if (se->conn.proto_minor >= 18)
- se->conn.capable |= FUSE_CAP_IOCTL_DIR;
+ se->conn.capable_ext |= FUSE_CAP_IOCTL_DIR;
/* Default settings for modern filesystems.
*
* we can finally enable them by default (as long as they're
* supported by the kernel).
*/
-#define LL_SET_DEFAULT(cond, cap) \
- if ((cond) && (se->conn.capable & (cap))) \
- se->conn.want |= (cap)
+#define LL_SET_DEFAULT(cond, cap) \
+ if ((cond)) \
+ fuse_set_feature_flag(&se->conn, cap)
+
LL_SET_DEFAULT(1, FUSE_CAP_ASYNC_READ);
LL_SET_DEFAULT(1, FUSE_CAP_AUTO_INVAL_DATA);
LL_SET_DEFAULT(1, FUSE_CAP_ASYNC_DIO);
se->conn.time_gran = 1;
se->got_init = 1;
- if (se->op.init)
+ if (se->op.init) {
+ uint32_t want_ext_default = se->conn.want_ext;
+ int rc;
+
+ // Apply the first 32 bits of capable_ext to capable
+ se->conn.capable =
+ (uint32_t)(se->conn.capable_ext & 0xFFFFFFFF);
+
se->op.init(se->userdata, &se->conn);
- if (!want_flags_valid(se->conn.capable, se->conn.want)) {
+ /*
+ * se->conn.want is 32-bit value and deprecated in favour of
+ * se->conn.want_ext
+ * Userspace might still use conn.want - we need to convert it
+ */
+ rc = convert_to_conn_want_ext(&se->conn, want_ext_default);
+ if (rc != 0) {
+ fuse_reply_err(req, EPROTO);
+ se->error = -EPROTO;
+ fuse_session_exit(se);
+ return;
+ }
+ }
+
+ if (!want_flags_valid(se->conn.capable_ext, se->conn.want_ext)) {
fuse_reply_err(req, EPROTO);
se->error = -EPROTO;
fuse_session_exit(se);
by the max_write option */
outargflags |= FUSE_BIG_WRITES;
- if (se->conn.want & FUSE_CAP_ASYNC_READ)
+ if (se->conn.want_ext & FUSE_CAP_ASYNC_READ)
outargflags |= FUSE_ASYNC_READ;
- if (se->conn.want & FUSE_CAP_POSIX_LOCKS)
+ if (se->conn.want_ext & FUSE_CAP_POSIX_LOCKS)
outargflags |= FUSE_POSIX_LOCKS;
- if (se->conn.want & FUSE_CAP_ATOMIC_O_TRUNC)
+ if (se->conn.want_ext & FUSE_CAP_ATOMIC_O_TRUNC)
outargflags |= FUSE_ATOMIC_O_TRUNC;
- if (se->conn.want & FUSE_CAP_EXPORT_SUPPORT)
+ if (se->conn.want_ext & FUSE_CAP_EXPORT_SUPPORT)
outargflags |= FUSE_EXPORT_SUPPORT;
- if (se->conn.want & FUSE_CAP_DONT_MASK)
+ if (se->conn.want_ext & FUSE_CAP_DONT_MASK)
outargflags |= FUSE_DONT_MASK;
- if (se->conn.want & FUSE_CAP_FLOCK_LOCKS)
+ if (se->conn.want_ext & FUSE_CAP_FLOCK_LOCKS)
outargflags |= FUSE_FLOCK_LOCKS;
- if (se->conn.want & FUSE_CAP_AUTO_INVAL_DATA)
+ if (se->conn.want_ext & FUSE_CAP_AUTO_INVAL_DATA)
outargflags |= FUSE_AUTO_INVAL_DATA;
- if (se->conn.want & FUSE_CAP_READDIRPLUS)
+ if (se->conn.want_ext & FUSE_CAP_READDIRPLUS)
outargflags |= FUSE_DO_READDIRPLUS;
- if (se->conn.want & FUSE_CAP_READDIRPLUS_AUTO)
+ if (se->conn.want_ext & FUSE_CAP_READDIRPLUS_AUTO)
outargflags |= FUSE_READDIRPLUS_AUTO;
- if (se->conn.want & FUSE_CAP_ASYNC_DIO)
+ if (se->conn.want_ext & FUSE_CAP_ASYNC_DIO)
outargflags |= FUSE_ASYNC_DIO;
- if (se->conn.want & FUSE_CAP_WRITEBACK_CACHE)
+ if (se->conn.want_ext & FUSE_CAP_WRITEBACK_CACHE)
outargflags |= FUSE_WRITEBACK_CACHE;
- if (se->conn.want & FUSE_CAP_PARALLEL_DIROPS)
+ if (se->conn.want_ext & FUSE_CAP_PARALLEL_DIROPS)
outargflags |= FUSE_PARALLEL_DIROPS;
- if (se->conn.want & FUSE_CAP_POSIX_ACL)
+ if (se->conn.want_ext & FUSE_CAP_POSIX_ACL)
outargflags |= FUSE_POSIX_ACL;
- if (se->conn.want & FUSE_CAP_HANDLE_KILLPRIV)
+ if (se->conn.want_ext & FUSE_CAP_HANDLE_KILLPRIV)
outargflags |= FUSE_HANDLE_KILLPRIV;
- if (se->conn.want & FUSE_CAP_HANDLE_KILLPRIV_V2)
+ if (se->conn.want_ext & FUSE_CAP_HANDLE_KILLPRIV_V2)
outargflags |= FUSE_HANDLE_KILLPRIV_V2;
- if (se->conn.want & FUSE_CAP_CACHE_SYMLINKS)
+ if (se->conn.want_ext & FUSE_CAP_CACHE_SYMLINKS)
outargflags |= FUSE_CACHE_SYMLINKS;
- if (se->conn.want & FUSE_CAP_EXPLICIT_INVAL_DATA)
+ if (se->conn.want_ext & FUSE_CAP_EXPLICIT_INVAL_DATA)
outargflags |= FUSE_EXPLICIT_INVAL_DATA;
- if (se->conn.want & FUSE_CAP_SETXATTR_EXT)
+ if (se->conn.want_ext & FUSE_CAP_SETXATTR_EXT)
outargflags |= FUSE_SETXATTR_EXT;
- if (se->conn.want & FUSE_CAP_DIRECT_IO_ALLOW_MMAP)
+ if (se->conn.want_ext & FUSE_CAP_DIRECT_IO_ALLOW_MMAP)
outargflags |= FUSE_DIRECT_IO_ALLOW_MMAP;
- if (se->conn.want & FUSE_CAP_PASSTHROUGH) {
+ if (se->conn.want_ext & FUSE_CAP_PASSTHROUGH) {
outargflags |= FUSE_PASSTHROUGH;
/*
* outarg.max_stack_depth includes the fuse stack layer,
*/
outarg.max_stack_depth = se->conn.max_backing_stack_depth + 1;
}
- if (se->conn.want & FUSE_CAP_NO_EXPORT_SUPPORT)
+ if (se->conn.want_ext & FUSE_CAP_NO_EXPORT_SUPPORT)
outargflags |= FUSE_NO_EXPORT_SUPPORT;
if (inargflags & FUSE_INIT_EXT) {
outarg.congestion_threshold);
fuse_log(FUSE_LOG_DEBUG, " time_gran=%u\n",
outarg.time_gran);
- if (se->conn.want & FUSE_CAP_PASSTHROUGH)
+ if (se->conn.want_ext & FUSE_CAP_PASSTHROUGH)
fuse_log(FUSE_LOG_DEBUG, " max_stack_depth=%u\n",
outarg.max_stack_depth);
}
if (!se)
return -EINVAL;
- if (!(se->conn.capable & FUSE_CAP_EXPIRE_ONLY))
+ if (!(se->conn.capable_ext & FUSE_CAP_EXPIRE_ONLY))
return -ENOSYS;
return fuse_lowlevel_notify_entry(se, parent, name, namelen, FUSE_LL_EXPIRE_ONLY);
struct fuse_buf tmpbuf;
if (se->conn.proto_minor < 14 ||
- !(se->conn.want & FUSE_CAP_SPLICE_READ))
+ !(se->conn.want_ext & FUSE_CAP_SPLICE_READ))
goto fallback;
llp = fuse_ll_get_pipe(se);