From 075d62d647316bfe8e67fcd5580fe587a8366d16 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Fri, 26 Sep 2014 18:31:22 -0400 Subject: [PATCH] add support for ioctl on directories. closes #27 --- src/config.cpp | 10 ++++--- src/config.hpp | 3 +++ src/destroy.cpp | 35 ++++++++++++++++++++++++ src/destroy.hpp | 32 ++++++++++++++++++++++ src/init.cpp | 41 ++++++++++++++++++++++++++++ src/init.hpp | 32 ++++++++++++++++++++++ src/ioctl.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++ src/mergerfs.cpp | 12 ++++++--- src/opendir.cpp | 40 ++++++++++++++++++++++++++++ src/opendir.hpp | 33 +++++++++++++++++++++++ src/releasedir.cpp | 38 ++++++++++++++++++++++++++ src/releasedir.hpp | 33 +++++++++++++++++++++++ 12 files changed, 368 insertions(+), 7 deletions(-) create mode 100644 src/destroy.cpp create mode 100644 src/destroy.hpp create mode 100644 src/init.cpp create mode 100644 src/init.hpp create mode 100644 src/opendir.cpp create mode 100644 src/opendir.hpp create mode 100644 src/releasedir.cpp create mode 100644 src/releasedir.hpp diff --git a/src/config.cpp b/src/config.cpp index ce7695eca..b0d764591 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -22,8 +22,6 @@ THE SOFTWARE. */ -#include - #include #include @@ -57,10 +55,16 @@ namespace mergerfs search = &Policy::ff; } + const Config& + get(const struct fuse_context *fc) + { + return *((Config*)fc->private_data); + } + const Config& get(void) { - return (*((Config*)fuse_get_context()->private_data)); + return get(fuse_get_context()); } Config& diff --git a/src/config.hpp b/src/config.hpp index 7646b46ca..a4f4f428c 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -25,6 +25,8 @@ #ifndef __CONFIG_HPP__ #define __CONFIG_HPP__ +#include + #include #include @@ -56,6 +58,7 @@ namespace mergerfs const std::string controlfile; }; + const Config &get(const struct fuse_context *fc); const Config &get(void); Config &get_writable(void); } diff --git a/src/destroy.cpp b/src/destroy.cpp new file mode 100644 index 000000000..0edf5847e --- /dev/null +++ b/src/destroy.cpp @@ -0,0 +1,35 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +namespace mergerfs +{ + namespace destroy + { + void + destroy(void *) + { + + } + } +} diff --git a/src/destroy.hpp b/src/destroy.hpp new file mode 100644 index 000000000..dbe0aa31f --- /dev/null +++ b/src/destroy.hpp @@ -0,0 +1,32 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +namespace mergerfs +{ + namespace destroy + { + void + destroy(void *); + } +} diff --git a/src/init.cpp b/src/init.cpp new file mode 100644 index 000000000..8507ebc68 --- /dev/null +++ b/src/init.cpp @@ -0,0 +1,41 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include + +#include "config.hpp" + +namespace mergerfs +{ + namespace init + { + void * + init(struct fuse_conn_info *conn) + { + conn->want |= FUSE_CAP_IOCTL_DIR; + + return &config::get_writable(); + } + } +} diff --git a/src/init.hpp b/src/init.hpp new file mode 100644 index 000000000..34a46aee7 --- /dev/null +++ b/src/init.hpp @@ -0,0 +1,32 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +namespace mergerfs +{ + namespace init + { + void * + init(struct fuse_conn_info *conn); + } +} diff --git a/src/ioctl.cpp b/src/ioctl.cpp index ef381ab20..de8cbb503 100644 --- a/src/ioctl.cpp +++ b/src/ioctl.cpp @@ -25,12 +25,20 @@ #include #include +#include #include #include #include +#include "config.hpp" #include "fileinfo.hpp" +#include "ugid.hpp" +#include "rwlock.hpp" + +using std::string; +using std::vector; +using namespace mergerfs; static int @@ -72,6 +80,57 @@ _ioctl(const int fd, return ((rv == -1) ? -errno : rv); } +static +int +_ioctl_dir_base(const fs::SearchFunc searchFunc, + const vector &srcmounts, + const string fusepath, + const int cmd, + void *arg, + const unsigned int flags, + void *data) +{ + int fd; + int rv; + fs::PathVector paths; + + rv = searchFunc(srcmounts,fusepath,paths); + if(rv == -1) + return -errno; + + fd = ::open(paths[0].full.c_str(),flags); + if(fd == -1) + return -errno; + + rv = _ioctl(fd,cmd,arg,flags,data); + + close(fd); + + return rv; +} + +static +int +_ioctl_dir(const string fusepath, + const int cmd, + void *arg, + const unsigned int flags, + void *data) +{ + const struct fuse_context *fc = fuse_get_context(); + const config::Config &config = config::get(fc); + const ugid::SetResetGuard ugid(fc->uid,fc->gid); + const rwlock::ReadGuard readlock(&config.srcmountslock); + + return _ioctl_dir_base(*config.search, + config.srcmounts, + fusepath, + cmd, + arg, + flags, + data); +} + namespace mergerfs { namespace ioctl @@ -86,6 +145,13 @@ namespace mergerfs { const FileInfo *fileinfo = (FileInfo*)ffi->fh; + if(flags & FUSE_IOCTL_DIR) + return _ioctl_dir(fusepath, + cmd, + arg, + flags, + data); + return _ioctl(fileinfo->fd, cmd, arg, diff --git a/src/mergerfs.cpp b/src/mergerfs.cpp index 1133d89b7..06a3ecaa7 100644 --- a/src/mergerfs.cpp +++ b/src/mergerfs.cpp @@ -38,6 +38,7 @@ #include "chmod.hpp" #include "chown.hpp" #include "create.hpp" +#include "destroy.hpp" #include "fallocate.hpp" #include "fgetattr.hpp" #include "flush.hpp" @@ -45,17 +46,20 @@ #include "ftruncate.hpp" #include "getattr.hpp" #include "getxattr.hpp" +#include "init.hpp" #include "ioctl.hpp" #include "link.hpp" #include "listxattr.hpp" #include "mkdir.hpp" #include "mknod.hpp" #include "open.hpp" +#include "opendir.hpp" #include "read.hpp" #include "read_buf.hpp" #include "readdir.hpp" #include "readlink.hpp" #include "release.hpp" +#include "releasedir.hpp" #include "removexattr.hpp" #include "rename.hpp" #include "rmdir.hpp" @@ -82,7 +86,7 @@ get_fuse_operations() ops.chmod = mergerfs::chmod::chmod; ops.chown = mergerfs::chown::chown; ops.create = mergerfs::create::create; - ops.destroy = NULL; + ops.destroy = mergerfs::destroy::destroy; ops.fallocate = mergerfs::fallocate::fallocate; ops.fgetattr = mergerfs::fgetattr::fgetattr; ops.flock = NULL; @@ -93,7 +97,7 @@ get_fuse_operations() ops.getattr = mergerfs::getattr::getattr; ops.getdir = NULL; /* deprecated; use readdir */ ops.getxattr = mergerfs::getxattr::getxattr; - ops.init = NULL; + ops.init = mergerfs::init::init; ops.ioctl = mergerfs::ioctl::ioctl; ops.link = mergerfs::link::link; ops.listxattr = mergerfs::listxattr::listxattr; @@ -101,14 +105,14 @@ get_fuse_operations() ops.mkdir = mergerfs::mkdir::mkdir; ops.mknod = mergerfs::mknod::mknod; ops.open = mergerfs::open::open; - ops.opendir = NULL; + ops.opendir = mergerfs::opendir::opendir; ops.poll = NULL; ops.read = mergerfs::read::read; ops.read_buf = mergerfs::read_buf::read_buf; ops.readdir = mergerfs::readdir::readdir; ops.readlink = mergerfs::readlink::readlink; ops.release = mergerfs::release::release; - ops.releasedir = NULL; + ops.releasedir = mergerfs::releasedir::releasedir; ops.removexattr = mergerfs::removexattr::removexattr; ops.rename = mergerfs::rename::rename; ops.rmdir = mergerfs::rmdir::rmdir; diff --git a/src/opendir.cpp b/src/opendir.cpp new file mode 100644 index 000000000..fb3fd25b9 --- /dev/null +++ b/src/opendir.cpp @@ -0,0 +1,40 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include + +namespace mergerfs +{ + namespace opendir + { + int + opendir(const char *fusepath, + struct fuse_file_info *ffi) + { + ffi->fh = 0; + + return 0; + } + } +} diff --git a/src/opendir.hpp b/src/opendir.hpp new file mode 100644 index 000000000..020e25f01 --- /dev/null +++ b/src/opendir.hpp @@ -0,0 +1,33 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include + +namespace mergerfs +{ + namespace opendir + { + int opendir(const char *fusepath, struct fuse_file_info *ffi); + } +} diff --git a/src/releasedir.cpp b/src/releasedir.cpp new file mode 100644 index 000000000..689fec7be --- /dev/null +++ b/src/releasedir.cpp @@ -0,0 +1,38 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include + +namespace mergerfs +{ + namespace releasedir + { + int + releasedir(const char *fusepath, + struct fuse_file_info *ffi) + { + return 0; + } + } +} diff --git a/src/releasedir.hpp b/src/releasedir.hpp new file mode 100644 index 000000000..0e06653d6 --- /dev/null +++ b/src/releasedir.hpp @@ -0,0 +1,33 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include + +namespace mergerfs +{ + namespace releasedir + { + int releasedir(const char *fusepath, struct fuse_file_info *ffi); + } +}