This patch adds the initial infrastructure to implement the LOOKUP_HANDLE operation. It simply defines the new operation and the extra fuse_init_out field to set the maximum handle size. Signed-off-by: Luis Henriques --- fs/fuse/fuse_i.h | 4 ++++ fs/fuse/inode.c | 9 ++++++++- include/uapi/linux/fuse.h | 8 +++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 1792ee6f5da6..fad05fae7e54 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -909,6 +909,10 @@ struct fuse_conn { /* Is synchronous FUSE_INIT allowed? */ unsigned int sync_init:1; + /** Is LOOKUP_HANDLE implemented by fs? */ + unsigned int lookup_handle:1; + unsigned int max_handle_sz; + /* Use io_uring for communication */ unsigned int io_uring; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index ef63300c634f..bc84e7ed1e3d 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1465,6 +1465,13 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args, if (flags & FUSE_REQUEST_TIMEOUT) timeout = arg->request_timeout; + + if ((flags & FUSE_HAS_LOOKUP_HANDLE) && + (arg->max_handle_sz > 0) && + (arg->max_handle_sz <= FUSE_MAX_HANDLE_SZ)) { + fc->lookup_handle = 1; + fc->max_handle_sz = arg->max_handle_sz; + } } else { ra_pages = fc->max_read / PAGE_SIZE; fc->no_lock = 1; @@ -1515,7 +1522,7 @@ static struct fuse_init_args *fuse_new_init(struct fuse_mount *fm) FUSE_SECURITY_CTX | FUSE_CREATE_SUPP_GROUP | FUSE_HAS_EXPIRE_ONLY | FUSE_DIRECT_IO_ALLOW_MMAP | FUSE_NO_EXPORT_SUPPORT | FUSE_HAS_RESEND | FUSE_ALLOW_IDMAP | - FUSE_REQUEST_TIMEOUT; + FUSE_REQUEST_TIMEOUT | FUSE_LOOKUP_HANDLE; #ifdef CONFIG_FUSE_DAX if (fm->fc->dax) flags |= FUSE_MAP_ALIGNMENT; diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index c13e1f9a2f12..4acf71b407c9 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -495,6 +495,7 @@ struct fuse_file_lock { #define FUSE_ALLOW_IDMAP (1ULL << 40) #define FUSE_OVER_IO_URING (1ULL << 41) #define FUSE_REQUEST_TIMEOUT (1ULL << 42) +#define FUSE_HAS_LOOKUP_HANDLE (1ULL << 43) /** * CUSE INIT request/reply flags @@ -663,6 +664,7 @@ enum fuse_opcode { FUSE_TMPFILE = 51, FUSE_STATX = 52, FUSE_COPY_FILE_RANGE_64 = 53, + FUSE_LOOKUP_HANDLE = 54, /* CUSE specific operations */ CUSE_INIT = 4096, @@ -908,6 +910,9 @@ struct fuse_init_in { uint32_t unused[11]; }; +/* Same value as MAX_HANDLE_SZ */ +#define FUSE_MAX_HANDLE_SZ 128 + #define FUSE_COMPAT_INIT_OUT_SIZE 8 #define FUSE_COMPAT_22_INIT_OUT_SIZE 24 @@ -925,7 +930,8 @@ struct fuse_init_out { uint32_t flags2; uint32_t max_stack_depth; uint16_t request_timeout; - uint16_t unused[11]; + uint16_t max_handle_sz; + uint16_t unused[10]; }; #define CUSE_INIT_INFO_MAX 4096