From dd666079b6ad22909c111ad88bc28184350f510e Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Tue, 10 Jun 2014 17:00:22 -0400 Subject: [PATCH] add {read,write}_buf functions. closes #15 --- src/mergerfs.cpp | 6 ++- src/read_buf.cpp | 125 ++++++++++++++++++++++++++++++++++++++++++++++ src/read_buf.hpp | 36 +++++++++++++ src/write_buf.cpp | 109 ++++++++++++++++++++++++++++++++++++++++ src/write_buf.hpp | 35 +++++++++++++ 5 files changed, 309 insertions(+), 2 deletions(-) create mode 100644 src/read_buf.cpp create mode 100644 src/read_buf.hpp create mode 100644 src/write_buf.cpp create mode 100644 src/write_buf.hpp diff --git a/src/mergerfs.cpp b/src/mergerfs.cpp index df7d732e..da4baccd 100644 --- a/src/mergerfs.cpp +++ b/src/mergerfs.cpp @@ -51,6 +51,7 @@ #include "mknod.hpp" #include "open.hpp" #include "read.hpp" +#include "read_buf.hpp" #include "readdir.hpp" #include "readlink.hpp" #include "release.hpp" @@ -64,6 +65,7 @@ #include "unlink.hpp" #include "utimens.hpp" #include "write.hpp" +#include "write_buf.hpp" static struct fuse_operations @@ -101,7 +103,7 @@ get_fuse_operations() ops.opendir = NULL; ops.poll = NULL; ops.read = mergerfs::read::read; - ops.read_buf = NULL; + ops.read_buf = mergerfs::read_buf::read_buf; ops.readdir = mergerfs::readdir::readdir; ops.readlink = mergerfs::readlink::readlink; ops.release = mergerfs::release::release; @@ -117,7 +119,7 @@ get_fuse_operations() ops.utime = NULL; /* deprecated; use utimens() */ ops.utimens = mergerfs::utimens::utimens; ops.write = mergerfs::write::write; - ops.write_buf = NULL; + ops.write_buf = mergerfs::write_buf::write_buf; return ops; } diff --git a/src/read_buf.cpp b/src/read_buf.cpp new file mode 100644 index 00000000..28469f87 --- /dev/null +++ b/src/read_buf.cpp @@ -0,0 +1,125 @@ +/* + 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 +#include +#include + +#include "config.hpp" +#include "ugid.hpp" +#include "fileinfo.hpp" + +using std::string; + +static +void * +memdup(const void *src, + const size_t len) +{ + void *dst; + + dst = malloc(len); + if(dst == NULL) + return NULL; + + memcpy(dst, src, len); + + return dst; +} + +static +int +_read_buf_controlfile(const string readstr, + struct fuse_bufvec **bufp, + const size_t size) +{ + struct fuse_bufvec *src; + + src = (fuse_bufvec*)malloc(sizeof(struct fuse_bufvec)); + if(src == NULL) + return -ENOMEM; + + *src = FUSE_BUFVEC_INIT(std::min(size,readstr.size())); + + src->buf->mem = memdup(readstr.data(),readstr.size()); + if(src->buf->mem == NULL) + return -ENOMEM; + + *bufp = src; + + return 0; +} + +static +int +_read_buf(const int fd, + struct fuse_bufvec **bufp, + const size_t size, + const off_t offset) +{ + struct fuse_bufvec *src; + + src = (fuse_bufvec*)malloc(sizeof(struct fuse_bufvec)); + if(src == NULL) + return -ENOMEM; + + *src = FUSE_BUFVEC_INIT(size); + + src->buf->flags = (fuse_buf_flags)(FUSE_BUF_IS_FD|FUSE_BUF_FD_SEEK|FUSE_BUF_FD_RETRY); + src->buf->fd = fd; + src->buf->pos = offset; + + *bufp = src; + + return 0; +} + +namespace mergerfs +{ + namespace read_buf + { + int + read_buf(const char *fusepath, + struct fuse_bufvec **bufp, + size_t size, + off_t offset, + struct fuse_file_info *fi) + { + const ugid::SetResetGuard ugid; + const config::Config &config = config::get(); + + if(fusepath == config.controlfile) + return _read_buf_controlfile(config.readstr, + bufp, + size); + + return _read_buf(((FileInfo*)fi->fh)->fd, + bufp, + size, + offset); + } + } +} diff --git a/src/read_buf.hpp b/src/read_buf.hpp new file mode 100644 index 00000000..5b11fa5a --- /dev/null +++ b/src/read_buf.hpp @@ -0,0 +1,36 @@ +/* + 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 read_buf + { + int + read_buf(const char *fusepath, + struct fuse_bufvec **buf, + size_t size, + off_t offset, + struct fuse_file_info *fi); + } +} diff --git a/src/write_buf.cpp b/src/write_buf.cpp new file mode 100644 index 00000000..6838d79d --- /dev/null +++ b/src/write_buf.cpp @@ -0,0 +1,109 @@ +/* + 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 +#include + +#include "config.hpp" +#include "ugid.hpp" +#include "fileinfo.hpp" +#include "write.hpp" + +using std::string; + +static +int +_write_buf_controlfile(const string controlfile, + struct fuse_bufvec *buf, + struct fuse_file_info *fi) +{ + int rv; + size_t size; + struct fuse_bufvec dst; + + size = fuse_buf_size(buf); + dst = FUSE_BUFVEC_INIT(size); + dst.buf->mem = malloc(size); + + rv = fuse_buf_copy(&dst,buf,(fuse_buf_copy_flags)0); + if(rv < 0) + { + free(dst.buf->mem); + return rv; + } + + rv = mergerfs::write::write(controlfile.c_str(), + (const char*)dst.buf->mem, + size, + 0, + fi); + free(dst.buf->mem); + + return rv; +} + +static +int +_write_buf(const int fd, + struct fuse_bufvec *buf, + const off_t offset) +{ + size_t size = fuse_buf_size(buf); + struct fuse_bufvec dest = FUSE_BUFVEC_INIT(size); + const fuse_buf_copy_flags cpflags = + (fuse_buf_copy_flags)(FUSE_BUF_SPLICE_MOVE|FUSE_BUF_SPLICE_NONBLOCK); + + dest.buf->flags = (fuse_buf_flags)(FUSE_BUF_IS_FD|FUSE_BUF_FD_SEEK); + dest.buf->fd = fd; + dest.buf->pos = offset; + + return fuse_buf_copy(&dest,buf,cpflags); +} + +namespace mergerfs +{ + namespace write_buf + { + int + write_buf(const char *fusepath, + struct fuse_bufvec *buf, + off_t offset, + struct fuse_file_info *fi) + { + const ugid::SetResetGuard ugid; + const config::Config &config = config::get(); + + if(fusepath == config.controlfile) + return _write_buf_controlfile(config.controlfile, + buf, + fi); + + return _write_buf(((FileInfo*)fi->fh)->fd, + buf, + offset); + } + } +} diff --git a/src/write_buf.hpp b/src/write_buf.hpp new file mode 100644 index 00000000..bce2de84 --- /dev/null +++ b/src/write_buf.hpp @@ -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 write_buf + { + int + write_buf(const char *fusepath, + struct fuse_bufvec *buf, + off_t offset, + struct fuse_file_info *fi); + } +}