From 4df08719f3415cde6f802a755922b7f76e198cd7 Mon Sep 17 00:00:00 2001 From: Dharmendra Singh Date: Mon, 28 Feb 2022 11:15:06 +0000 Subject: [PATCH] Modify structures in libfuse to handle flags beyond 32 bits. In fuse kernel, 'commit 53db28933e95 ("fuse: extend init flags")' made the changes to handle flags going beyond 32 bits but i think changes were not done in libfuse to handle the same. This patch prepares the ground in libfuse for incoming FUSE kernel patches (Atomic open + lookup) where flags went beyond 32 bits. It makes struct same as in fuse kernel resulting in name change of few fields. --- include/fuse_kernel.h | 8 ++++- lib/fuse_lowlevel.c | 75 ++++++++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 35 deletions(-) --- a/include/fuse_kernel.h +++ b/include/fuse_kernel.h @@ -272,6 +272,7 @@ struct fuse_file_lock { #define FUSE_POSIX_ACL (1 << 20) #define FUSE_MAX_PAGES (1 << 22) #define FUSE_CACHE_SYMLINKS (1 << 23) +#define FUSE_INIT_EXT (1 << 30) /** * CUSE INIT request/reply flags @@ -596,6 +597,8 @@ struct fuse_init_in { uint32_t minor; uint32_t max_readahead; uint32_t flags; + uint32_t flags2; + uint32_t unused[11]; }; #define FUSE_COMPAT_INIT_OUT_SIZE 8 @@ -611,8 +614,9 @@ struct fuse_init_out { uint32_t max_write; uint32_t time_gran; uint16_t max_pages; - uint16_t padding; - uint32_t unused[8]; + uint16_t map_alignment; + uint32_t flags2; + uint32_t unused[7]; }; #define CUSE_INIT_INFO_MAX 4096 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -1819,7 +1819,8 @@ static void do_init(fuse_req_t req, fuse struct fuse_session *se = req->se; size_t bufsize = se->bufsize; size_t outargsize = sizeof(outarg); - + uint64_t inargflags = 0; + uint64_t outargflags = 0; (void) nodeid; if (se->debug) { fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor); @@ -1854,39 +1855,42 @@ static void do_init(fuse_req_t req, fuse if (arg->minor >= 6) { if (arg->max_readahead < se->conn.max_readahead) se->conn.max_readahead = arg->max_readahead; - if (arg->flags & FUSE_ASYNC_READ) + inargflags = arg->flags; + if (inargflags & FUSE_INIT_EXT) + inargflags = inargflags | (uint64_t) arg->flags2 << 32; + if (inargflags & FUSE_ASYNC_READ) se->conn.capable |= FUSE_CAP_ASYNC_READ; - if (arg->flags & FUSE_POSIX_LOCKS) + if (inargflags & FUSE_POSIX_LOCKS) se->conn.capable |= FUSE_CAP_POSIX_LOCKS; - if (arg->flags & FUSE_ATOMIC_O_TRUNC) + if (inargflags & FUSE_ATOMIC_O_TRUNC) se->conn.capable |= FUSE_CAP_ATOMIC_O_TRUNC; - if (arg->flags & FUSE_EXPORT_SUPPORT) + if (inargflags & FUSE_EXPORT_SUPPORT) se->conn.capable |= FUSE_CAP_EXPORT_SUPPORT; - if (arg->flags & FUSE_DONT_MASK) + if (inargflags & FUSE_DONT_MASK) se->conn.capable |= FUSE_CAP_DONT_MASK; - if (arg->flags & FUSE_FLOCK_LOCKS) + if (inargflags & FUSE_FLOCK_LOCKS) se->conn.capable |= FUSE_CAP_FLOCK_LOCKS; - if (arg->flags & FUSE_AUTO_INVAL_DATA) + if (inargflags & FUSE_AUTO_INVAL_DATA) se->conn.capable |= FUSE_CAP_AUTO_INVAL_DATA; - if (arg->flags & FUSE_DO_READDIRPLUS) + if (inargflags & FUSE_DO_READDIRPLUS) se->conn.capable |= FUSE_CAP_READDIRPLUS; - if (arg->flags & FUSE_READDIRPLUS_AUTO) + if (inargflags & FUSE_READDIRPLUS_AUTO) se->conn.capable |= FUSE_CAP_READDIRPLUS_AUTO; - if (arg->flags & FUSE_ASYNC_DIO) + if (inargflags & FUSE_ASYNC_DIO) se->conn.capable |= FUSE_CAP_ASYNC_DIO; - if (arg->flags & FUSE_WRITEBACK_CACHE) + if (inargflags & FUSE_WRITEBACK_CACHE) se->conn.capable |= FUSE_CAP_WRITEBACK_CACHE; - if (arg->flags & FUSE_NO_OPEN_SUPPORT) + if (inargflags & FUSE_NO_OPEN_SUPPORT) se->conn.capable |= FUSE_CAP_NO_OPEN_SUPPORT; - if (arg->flags & FUSE_PARALLEL_DIROPS) + if (inargflags & FUSE_PARALLEL_DIROPS) se->conn.capable |= FUSE_CAP_PARALLEL_DIROPS; - if (arg->flags & FUSE_POSIX_ACL) + if (inargflags & FUSE_POSIX_ACL) se->conn.capable |= FUSE_CAP_POSIX_ACL; - if (arg->flags & FUSE_HANDLE_KILLPRIV) + if (inargflags & FUSE_HANDLE_KILLPRIV) se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV; - if (arg->flags & FUSE_CACHE_SYMLINKS) + if (inargflags & FUSE_CACHE_SYMLINKS) se->conn.capable |= FUSE_CAP_CACHE_SYMLINKS; - if (!(arg->flags & FUSE_MAX_PAGES)) { + if (!(inargflags & FUSE_MAX_PAGES)) { size_t max_bufsize = FUSE_DEFAULT_MAX_PAGES_PER_REQ * getpagesize() + FUSE_BUFFER_HEADER_SIZE; @@ -1977,37 +1981,42 @@ static void do_init(fuse_req_t req, fuse outarg.flags |= FUSE_MAX_PAGES; outarg.max_pages = (se->conn.max_write - 1) / getpagesize() + 1; } - + outargflags = outarg.flags; /* Always enable big writes, this is superseded by the max_write option */ - outarg.flags |= FUSE_BIG_WRITES; + outargflags |= FUSE_BIG_WRITES; if (se->conn.want & FUSE_CAP_ASYNC_READ) - outarg.flags |= FUSE_ASYNC_READ; + outargflags |= FUSE_ASYNC_READ; if (se->conn.want & FUSE_CAP_POSIX_LOCKS) - outarg.flags |= FUSE_POSIX_LOCKS; + outargflags |= FUSE_POSIX_LOCKS; if (se->conn.want & FUSE_CAP_ATOMIC_O_TRUNC) - outarg.flags |= FUSE_ATOMIC_O_TRUNC; + outargflags |= FUSE_ATOMIC_O_TRUNC; if (se->conn.want & FUSE_CAP_EXPORT_SUPPORT) - outarg.flags |= FUSE_EXPORT_SUPPORT; + outargflags |= FUSE_EXPORT_SUPPORT; if (se->conn.want & FUSE_CAP_DONT_MASK) - outarg.flags |= FUSE_DONT_MASK; + outargflags |= FUSE_DONT_MASK; if (se->conn.want & FUSE_CAP_FLOCK_LOCKS) - outarg.flags |= FUSE_FLOCK_LOCKS; + outargflags |= FUSE_FLOCK_LOCKS; if (se->conn.want & FUSE_CAP_AUTO_INVAL_DATA) - outarg.flags |= FUSE_AUTO_INVAL_DATA; + outargflags |= FUSE_AUTO_INVAL_DATA; if (se->conn.want & FUSE_CAP_READDIRPLUS) - outarg.flags |= FUSE_DO_READDIRPLUS; + outargflags |= FUSE_DO_READDIRPLUS; if (se->conn.want & FUSE_CAP_READDIRPLUS_AUTO) - outarg.flags |= FUSE_READDIRPLUS_AUTO; + outargflags |= FUSE_READDIRPLUS_AUTO; if (se->conn.want & FUSE_CAP_ASYNC_DIO) - outarg.flags |= FUSE_ASYNC_DIO; + outargflags |= FUSE_ASYNC_DIO; if (se->conn.want & FUSE_CAP_WRITEBACK_CACHE) - outarg.flags |= FUSE_WRITEBACK_CACHE; + outargflags |= FUSE_WRITEBACK_CACHE; if (se->conn.want & FUSE_CAP_POSIX_ACL) - outarg.flags |= FUSE_POSIX_ACL; + outargflags |= FUSE_POSIX_ACL; if (se->conn.want & FUSE_CAP_CACHE_SYMLINKS) - outarg.flags |= FUSE_CACHE_SYMLINKS; + outargflags |= FUSE_CACHE_SYMLINKS; + + outarg.flags = outargflags; + + if (inargflags & FUSE_INIT_EXT) + outarg.flags2 = outargflags >> 32; outarg.max_readahead = se->conn.max_readahead; outarg.max_write = se->conn.max_write; if (se->conn.proto_minor >= 13) {