From 6dcf6111af7f387898c2392f5e2d4eb793e19714 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Sat, 12 Aug 2023 01:50:37 -0500 Subject: [PATCH] Add callbacks for newer functions * setupmapping * removemapping * syncfs * tmpfile --- libfuse/include/fuse.h | 10 ++++ libfuse/include/fuse_lowlevel.h | 9 +++ libfuse/lib/fuse.c | 102 +++++++++++++++++++++++++++++++- libfuse/lib/fuse_lowlevel.c | 42 +++++++++++++ src/fuse_removemapping.cpp | 28 +++++++++ src/fuse_removemapping.hpp | 27 +++++++++ src/fuse_setupmapping.cpp | 35 +++++++++++ src/fuse_setupmapping.hpp | 31 ++++++++++ src/fuse_syncfs.cpp | 28 +++++++++ src/fuse_syncfs.hpp | 27 +++++++++ src/fuse_tmpfile.cpp | 32 ++++++++++ src/fuse_tmpfile.hpp | 32 ++++++++++ src/mergerfs.cpp | 8 +++ src/ugid.cpp | 2 +- 14 files changed, 411 insertions(+), 2 deletions(-) create mode 100644 src/fuse_removemapping.cpp create mode 100644 src/fuse_removemapping.hpp create mode 100644 src/fuse_setupmapping.cpp create mode 100644 src/fuse_setupmapping.hpp create mode 100644 src/fuse_syncfs.cpp create mode 100644 src/fuse_syncfs.hpp create mode 100644 src/fuse_tmpfile.cpp create mode 100644 src/fuse_tmpfile.hpp diff --git a/libfuse/include/fuse.h b/libfuse/include/fuse.h index c86c4536..2d615223 100644 --- a/libfuse/include/fuse.h +++ b/libfuse/include/fuse.h @@ -539,6 +539,16 @@ struct fuse_operations off_t offset_out, size_t size, int flags); + + ssize_t (*setupmapping)(uint64_t *fh_, + uint64_t foffset_, + uint64_t len_, + uint64_t flags_, + uint64_t moffset_); + + int (*removemapping)(); + int (*syncfs)(); + int (*tmpfile)(const char *, mode_t, fuse_file_info_t *); }; /** Extra context that may be needed by some filesystems diff --git a/libfuse/include/fuse_lowlevel.h b/libfuse/include/fuse_lowlevel.h index aedc1fcd..3b9d8c14 100644 --- a/libfuse/include/fuse_lowlevel.h +++ b/libfuse/include/fuse_lowlevel.h @@ -1007,6 +1007,15 @@ struct fuse_lowlevel_ops */ void (*copy_file_range)(fuse_req_t req, const struct fuse_in_header *hdr); + + void (*setupmapping)(fuse_req_t req, + const struct fuse_in_header *hdr); + void (*removemapping)(fuse_req_t req, + const struct fuse_in_header *hdr); + void (*syncfs)(fuse_req_t req, + const struct fuse_in_header *hdr); + void (*tmpfile)(fuse_req_t req, + const struct fuse_in_header *hdr); }; /** diff --git a/libfuse/lib/fuse.c b/libfuse/lib/fuse.c index 31dffbde..2589017d 100644 --- a/libfuse/lib/fuse.c +++ b/libfuse/lib/fuse.c @@ -636,7 +636,7 @@ rehash_name(struct fuse *f) static int hash_name(struct fuse *f, - node_t *node, + node_t *node, uint64_t parentid, const char *name) { @@ -753,6 +753,7 @@ find_node(struct fuse *f, if(f->conf.remember) inc_nlookup(node); + printf("hash_name = %s\n",name); if(hash_name(f,node,parent,name) == -1) { free_node(f,node); @@ -2877,6 +2878,101 @@ fuse_lib_copy_file_range(fuse_req_t req_, fuse_reply_err(req_,rv); } +static +void +fuse_lib_setupmapping(fuse_req_t req_, + const struct fuse_in_header *hdr_) +{ + fuse_reply_err(req_,ENOSYS); +} + +static +void +fuse_lib_removemapping(fuse_req_t req_, + const struct fuse_in_header *hdr_) +{ + fuse_reply_err(req_,ENOSYS); +} + +static +void +fuse_lib_syncfs(fuse_req_t req_, + const struct fuse_in_header *hdr_) +{ + fuse_reply_err(req_,ENOSYS); +} + +// TODO: This is just a copy of fuse_lib_create. Needs to be rewritten +// so a nameless node can be setup. +// name is always '/' +// nodeid is the base directory +static +void +fuse_lib_tmpfile(fuse_req_t req_, + const struct fuse_in_header *hdr_) +{ + int err; + char *path; + struct fuse *f; + const char *name; + fuse_file_info_t ffi = {0}; + struct fuse_entry_param e; + struct fuse_create_in *arg; + + arg = fuse_hdr_arg(hdr_); + name = PARAM(arg); + + ffi.flags = arg->flags; + + if(req_->f->conn.proto_minor >= 12) + req_->ctx.umask = arg->umask; + else + name = (char*)arg + sizeof(struct fuse_open_in); + + f = req_fuse_prepare(req_); + + err = get_path_name(f,hdr_->nodeid,name,&path); + if(!err) + { + err = f->fs->op.tmpfile(path,arg->mode,&ffi); + if(!err) + { + err = lookup_path(f,hdr_->nodeid,name,path,&e,&ffi); + if(err) + { + f->fs->op.release(&ffi); + } + else if(!S_ISREG(e.attr.st_mode)) + { + err = -EIO; + f->fs->op.release(&ffi); + forget_node(f,e.ino,1); + } + } + } + + if(!err) + { + pthread_mutex_lock(&f->lock); + get_node(f,e.ino)->open_count++; + pthread_mutex_unlock(&f->lock); + + if(fuse_reply_create(req_,&e,&ffi) == -ENOENT) + { + /* The open syscall was interrupted,so it + must be cancelled */ + fuse_do_release(f,e.ino,&ffi); + forget_node(f,e.ino,1); + } + } + else + { + fuse_reply_err(req_,err); + } + + free_path(f,hdr_->nodeid,path); +} + static lock_t* locks_conflict(node_t *node, @@ -3531,15 +3627,19 @@ static struct fuse_lowlevel_ops fuse_path_ops = .readlink = fuse_lib_readlink, .release = fuse_lib_release, .releasedir = fuse_lib_releasedir, + .removemapping = fuse_lib_removemapping, .removexattr = fuse_lib_removexattr, .rename = fuse_lib_rename, .retrieve_reply = NULL, .rmdir = fuse_lib_rmdir, .setattr = fuse_lib_setattr, .setlk = fuse_lib_setlk, + .setupmapping = fuse_lib_setupmapping, .setxattr = fuse_lib_setxattr, .statfs = fuse_lib_statfs, .symlink = fuse_lib_symlink, + .syncfs = fuse_lib_syncfs, + .tmpfile = fuse_lib_tmpfile, .unlink = fuse_lib_unlink, .write = fuse_lib_write, }; diff --git a/libfuse/lib/fuse_lowlevel.c b/libfuse/lib/fuse_lowlevel.c index 7ed57981..6e4e4788 100644 --- a/libfuse/lib/fuse_lowlevel.c +++ b/libfuse/lib/fuse_lowlevel.c @@ -1330,6 +1330,42 @@ do_copy_file_range(fuse_req_t req_, req_->f->op.copy_file_range(req_,hdr_); } +static +void +do_setupmapping(fuse_req_t req_, + struct fuse_in_header *hdr_) +{ + printf("setupmapping\n"); + req_->f->op.setupmapping(req_,hdr_); +} + +static +void +do_removemapping(fuse_req_t req_, + struct fuse_in_header *hdr_) +{ + printf("removemapping\n"); + req_->f->op.removemapping(req_,hdr_); +} + +static +void +do_syncfs(fuse_req_t req_, + struct fuse_in_header *hdr_) +{ + printf("syncfs\n"); + req_->f->op.syncfs(req_,hdr_); +} + +static +void +do_tmpfile(fuse_req_t req_, + struct fuse_in_header *hdr_) +{ + printf("tmpfile\n"); + req_->f->op.tmpfile(req_,hdr_); +} + static int send_notify_iov(struct fuse_ll *f, @@ -1643,6 +1679,10 @@ static struct { [FUSE_NOTIFY_REPLY] = { do_notify_reply, "NOTIFY_REPLY" }, [FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" }, [FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" }, + [FUSE_SETUPMAPPING] = { do_setupmapping, "SETUPMAPPING" }, + [FUSE_REMOVEMAPPING] = { do_removemapping, "REMOVEMAPPING" }, + [FUSE_SYNCFS] = { do_syncfs, "SYNCFS" }, + [FUSE_TMPFILE] = { do_tmpfile, "TMPFILE" } }; #define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0])) @@ -1815,6 +1855,8 @@ fuse_ll_buf_process_read(struct fuse_session *se_, in = (struct fuse_in_header*)msgbuf_->mem; + // printf("%d\n",in->opcode); + req = fuse_ll_alloc_req(se_->f); if(req == NULL) return fuse_send_enomem(se_->f,se_->ch,in->unique); diff --git a/src/fuse_removemapping.cpp b/src/fuse_removemapping.cpp new file mode 100644 index 00000000..fa55f767 --- /dev/null +++ b/src/fuse_removemapping.cpp @@ -0,0 +1,28 @@ +/* + ISC License + + Copyright (c) 2023, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or 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. +*/ + +#include "fuse_removemapping.hpp" + +#include + + +int +FUSE::removemapping() +{ + return -ENOSYS; +} diff --git a/src/fuse_removemapping.hpp b/src/fuse_removemapping.hpp new file mode 100644 index 00000000..392c603c --- /dev/null +++ b/src/fuse_removemapping.hpp @@ -0,0 +1,27 @@ +/* + ISC License + + Copyright (c) 2023, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or 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. +*/ + +#pragma once + +#include "fuse.h" + + +namespace FUSE +{ + int removemapping(); +} diff --git a/src/fuse_setupmapping.cpp b/src/fuse_setupmapping.cpp new file mode 100644 index 00000000..eb21d9ce --- /dev/null +++ b/src/fuse_setupmapping.cpp @@ -0,0 +1,35 @@ +/* + ISC License + + Copyright (c) 2023, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or 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. +*/ + +#include "fuse_setupmapping.hpp" + +#include +#include + +#include + + +ssize_t +FUSE::setupmapping(uint64_t *fh_, + uint64_t foffset_, + uint64_t len_, + uint64_t flags_, + uint64_t moffset_) +{ + return -ENOSYS; +} diff --git a/src/fuse_setupmapping.hpp b/src/fuse_setupmapping.hpp new file mode 100644 index 00000000..5b290b6b --- /dev/null +++ b/src/fuse_setupmapping.hpp @@ -0,0 +1,31 @@ +/* + ISC License + + Copyright (c) 2023, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or 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. +*/ + +#pragma once + +#include "fuse.h" + + +namespace FUSE +{ + ssize_t setupmapping(uint64_t *fh_, + uint64_t foffset_, + uint64_t len_, + uint64_t flags_, + uint64_t moffset_); +} diff --git a/src/fuse_syncfs.cpp b/src/fuse_syncfs.cpp new file mode 100644 index 00000000..6af031ef --- /dev/null +++ b/src/fuse_syncfs.cpp @@ -0,0 +1,28 @@ +/* + ISC License + + Copyright (c) 2023, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or 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. +*/ + +#include "fuse_syncfs.hpp" + +#include + + +int +FUSE::syncfs() +{ + return -ENOSYS; +} diff --git a/src/fuse_syncfs.hpp b/src/fuse_syncfs.hpp new file mode 100644 index 00000000..f1a73b6b --- /dev/null +++ b/src/fuse_syncfs.hpp @@ -0,0 +1,27 @@ +/* + ISC License + + Copyright (c) 2023, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or 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. +*/ + +#pragma once + +#include "fuse.h" + + +namespace FUSE +{ + int syncfs(); +} diff --git a/src/fuse_tmpfile.cpp b/src/fuse_tmpfile.cpp new file mode 100644 index 00000000..76888395 --- /dev/null +++ b/src/fuse_tmpfile.cpp @@ -0,0 +1,32 @@ +/* + ISC License + + Copyright (c) 2023, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or 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. +*/ + +#include "fuse_tmpfile.hpp" +#include "fuse_create.hpp" + +#include +#include + + +int +FUSE::tmpfile(const char *fusepath_, + mode_t mode_, + fuse_file_info_t *ffi_) +{ + return -ENOSYS; +} diff --git a/src/fuse_tmpfile.hpp b/src/fuse_tmpfile.hpp new file mode 100644 index 00000000..47a743d2 --- /dev/null +++ b/src/fuse_tmpfile.hpp @@ -0,0 +1,32 @@ +/* + ISC License + + Copyright (c) 2023, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or 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. +*/ + +#pragma once + +#include "fuse.h" + +#include + + +namespace FUSE +{ + int + tmpfile(const char *fusepath, + mode_t mode, + fuse_file_info_t *ffi); +} diff --git a/src/mergerfs.cpp b/src/mergerfs.cpp index 704e003f..1a04d824 100644 --- a/src/mergerfs.cpp +++ b/src/mergerfs.cpp @@ -63,12 +63,16 @@ #include "fuse_readlink.hpp" #include "fuse_release.hpp" #include "fuse_releasedir.hpp" +#include "fuse_removemapping.hpp" #include "fuse_removexattr.hpp" #include "fuse_rename.hpp" #include "fuse_rmdir.hpp" +#include "fuse_setupmapping.hpp" #include "fuse_setxattr.hpp" #include "fuse_statfs.hpp" #include "fuse_symlink.hpp" +#include "fuse_syncfs.hpp" +#include "fuse_tmpfile.hpp" #include "fuse_truncate.hpp" #include "fuse_unlink.hpp" #include "fuse_utimens.hpp" @@ -127,12 +131,16 @@ namespace l ops_.readlink = FUSE::readlink; ops_.release = FUSE::release; ops_.releasedir = FUSE::releasedir; + ops_.removemapping = FUSE::removemapping; ops_.removexattr = FUSE::removexattr; ops_.rename = FUSE::rename; ops_.rmdir = FUSE::rmdir; + ops_.setupmapping = FUSE::setupmapping; ops_.setxattr = FUSE::setxattr; ops_.statfs = FUSE::statfs; ops_.symlink = FUSE::symlink; + ops_.syncfs = FUSE::syncfs; + ops_.tmpfile = FUSE::tmpfile; ops_.truncate = FUSE::truncate; ops_.unlink = FUSE::unlink; ops_.utimens = FUSE::utimens; diff --git a/src/ugid.cpp b/src/ugid.cpp index 368bbf8c..5582ccd4 100644 --- a/src/ugid.cpp +++ b/src/ugid.cpp @@ -28,7 +28,7 @@ namespace ugid initgroups(const uid_t uid_, const gid_t gid_) { - static __thread gid_t_cache cache = {0}; + static thread_local gid_t_cache cache = {0}; cache.initgroups(uid_,gid_); }