mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-26 10:51:52 -04:00
commit
805bc2d2e6
9 changed files with 232 additions and 86 deletions
43
Makefile
43
Makefile
|
|
@ -27,6 +27,7 @@ MKDIR = $(shell which mkdir)
|
|||
TOUCH = $(shell which touch)
|
||||
CP = $(shell which cp)
|
||||
RM = $(shell which rm)
|
||||
LN = $(shell which ln)
|
||||
FIND = $(shell which find)
|
||||
INSTALL = $(shell which install)
|
||||
MKTEMP = $(shell which mktemp)
|
||||
|
|
@ -82,8 +83,8 @@ LDFLAGS = $(shell $(PKGCONFIG) fuse --libs)
|
|||
|
||||
BINDIR = $(PREFIX)/usr/bin
|
||||
MANDIR = $(PREFIX)/usr/share/man/man1
|
||||
INSTALLTARGET = $(DESTDIR)/$(BINDIR)/$(TARGET)
|
||||
MANTARGET = $(DESTDIR)/$(MANDIR)/$(MANPAGE)
|
||||
INSTALLBINDIR = $(DESTDIR)$(BINDIR)
|
||||
INSTALLMANDIR = $(DESTDIR)$(MANDIR)
|
||||
|
||||
ifeq ($(XATTR_AVAILABLE),0)
|
||||
$(warning "xattr not available: disabling")
|
||||
|
|
@ -98,7 +99,7 @@ ifeq ($(KERNEL),Darwin)
|
|||
CFLAGS += -DOSX
|
||||
endif
|
||||
|
||||
all: $(TARGET)
|
||||
all: $(TARGET) clonepath
|
||||
|
||||
help:
|
||||
@echo "usage: make"
|
||||
|
|
@ -107,6 +108,9 @@ help:
|
|||
$(TARGET): obj/obj-stamp $(OBJ)
|
||||
$(CXX) $(CFLAGS) $(OBJ) -o $@ $(LDFLAGS)
|
||||
|
||||
clonepath: $(TARGET)
|
||||
$(LN) -s $< $@
|
||||
|
||||
changelog:
|
||||
$(GIT) log --pretty --numstat --summary | git2cl > ChangeLog
|
||||
|
||||
|
|
@ -118,22 +122,37 @@ obj/%.o: src/%.cpp
|
|||
$(CXX) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) -rf obj "$(TARGET)" "$(MANPAGE)"
|
||||
$(RM) -rf obj
|
||||
$(RM) -f "$(TARGET)" "$(MANPAGE)" clonepath
|
||||
$(FIND) -name "*~" -delete
|
||||
|
||||
distclean: clean
|
||||
$(GIT) clean -fd
|
||||
|
||||
install: $(TARGET) $(MANPAGE)
|
||||
$(INSTALL) -m 0755 -D "$(TARGET)" "$(INSTALLTARGET)"
|
||||
$(INSTALL) -m 0644 -D "$(MANPAGE)" "$(MANTARGET)"
|
||||
install: install-base install-clonepath install-man
|
||||
|
||||
install-strip: install
|
||||
$(STRIP) "$(INSTALLTARGET)"
|
||||
install-base: $(TARGET)
|
||||
$(INSTALL) -v -m 0755 -D "$(TARGET)" "$(INSTALLBINDIR)/$(TARGET)"
|
||||
|
||||
uninstall:
|
||||
$(RM) "$(INSTALLTARGET)"
|
||||
$(RM) "$(MANTARGET)"
|
||||
install-clonepath: clonepath
|
||||
$(CP) -a $< "$(INSTALLBINDIR)/$<"
|
||||
|
||||
install-man: $(MANPAGE)
|
||||
$(INSTALL) -v -m 0644 -D "$(MANPAGE)" "$(INSTALLMANDIR)/$(MANPAGE)"
|
||||
|
||||
install-strip: install-base
|
||||
$(STRIP) "$(INSTALLBINDIR)/$(TARGET)"
|
||||
|
||||
uninstall: uninstall-base uninstall-clonepath uninstall-man
|
||||
|
||||
uninstall-base:
|
||||
$(RM) -f "$(INSTALLBINDIR)/$(TARGET)"
|
||||
|
||||
uninstall-clonepath:
|
||||
$(RM) -f "$(INSTALLBINDIR)/clonepath"
|
||||
|
||||
uninstall-man:
|
||||
$(RM) -f "$(INSTALLMANDIR)/$(MANPAGE")
|
||||
|
||||
$(MANPAGE): README.md
|
||||
$(PANDOC) -s -t man -o $(MANPAGE) README.md
|
||||
|
|
|
|||
54
src/clonepath.cpp
Normal file
54
src/clonepath.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
|
||||
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 <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "fs.hpp"
|
||||
|
||||
namespace clonepath
|
||||
{
|
||||
static
|
||||
void
|
||||
print_usage_and__exit(void)
|
||||
{
|
||||
std::cerr << "usage: clonepath "
|
||||
<< "<sourcedir> <destdir> <relativepath>"
|
||||
<< std::endl;
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(const int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
if(argc != 4)
|
||||
print_usage_and__exit();
|
||||
|
||||
return fs::clonepath(argv[1],
|
||||
argv[2],
|
||||
argv[3]);
|
||||
}
|
||||
}
|
||||
30
src/clonepath.hpp
Normal file
30
src/clonepath.hpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
|
||||
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 clonepath
|
||||
{
|
||||
int
|
||||
main(const int argc,
|
||||
char * const *argv);
|
||||
}
|
||||
|
|
@ -70,7 +70,10 @@ _create(const fs::SearchFunc searchFunc,
|
|||
return -errno;
|
||||
|
||||
if(createpath[0].base != existingpath[0].base)
|
||||
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
|
||||
{
|
||||
const mergerfs::ugid::SetResetGuard ugid(0,0);
|
||||
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
|
||||
}
|
||||
|
||||
path = fs::make_path(createpath[0].base,fusepath);
|
||||
|
||||
|
|
|
|||
|
|
@ -424,7 +424,14 @@ namespace fs
|
|||
topath = fs::make_path(tosrc,relative);
|
||||
rv = ::mkdir(topath.c_str(),st.st_mode);
|
||||
if(rv == -1)
|
||||
return -1;
|
||||
{
|
||||
if(errno != EEXIST)
|
||||
return -1;
|
||||
|
||||
rv = ::chmod(topath.c_str(),st.st_mode);
|
||||
if(rv == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = ::chown(topath.c_str(),st.st_uid,st.st_gid);
|
||||
if(rv == -1)
|
||||
|
|
|
|||
|
|
@ -73,7 +73,11 @@ _link(const fs::SearchFunc searchFunc,
|
|||
fs::find::ffwp(srcmounts,todir,topaths);
|
||||
if(topaths.size() > 0)
|
||||
{
|
||||
fs::clonepath(topaths[0].base,i->base,todir);
|
||||
{
|
||||
const mergerfs::ugid::SetResetGuard ugid(0,0);
|
||||
fs::clonepath(topaths[0].base,i->base,todir);
|
||||
}
|
||||
|
||||
lrv = ::link(pathfrom.c_str(),pathto.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
161
src/mergerfs.cpp
161
src/mergerfs.cpp
|
|
@ -33,6 +33,8 @@
|
|||
#include "resources.hpp"
|
||||
#include "fs.hpp"
|
||||
|
||||
#include "clonepath.hpp"
|
||||
|
||||
#include "access.hpp"
|
||||
#include "chmod.hpp"
|
||||
#include "chown.hpp"
|
||||
|
|
@ -71,87 +73,110 @@
|
|||
#include "write.hpp"
|
||||
#include "write_buf.hpp"
|
||||
|
||||
static
|
||||
struct fuse_operations
|
||||
get_fuse_operations()
|
||||
namespace local
|
||||
{
|
||||
struct fuse_operations ops = {0};
|
||||
|
||||
static
|
||||
std::string
|
||||
getappname(const int argc,
|
||||
char * const *argv)
|
||||
{
|
||||
return fs::basename(argv[0]);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
get_fuse_operations(struct fuse_operations &ops)
|
||||
{
|
||||
#if FLAG_NOPATH
|
||||
ops.flag_nopath = false;
|
||||
ops.flag_nopath = false;
|
||||
#endif
|
||||
ops.flag_nullpath_ok = false;
|
||||
ops.flag_nullpath_ok = false;
|
||||
|
||||
ops.access = mergerfs::access::access;
|
||||
ops.bmap = NULL;
|
||||
ops.chmod = mergerfs::chmod::chmod;
|
||||
ops.chown = mergerfs::chown::chown;
|
||||
ops.create = mergerfs::create::create;
|
||||
ops.destroy = mergerfs::destroy::destroy;
|
||||
ops.access = mergerfs::access::access;
|
||||
ops.bmap = NULL;
|
||||
ops.chmod = mergerfs::chmod::chmod;
|
||||
ops.chown = mergerfs::chown::chown;
|
||||
ops.create = mergerfs::create::create;
|
||||
ops.destroy = mergerfs::destroy::destroy;
|
||||
#if FALLOCATE
|
||||
ops.fallocate = mergerfs::fallocate::fallocate;
|
||||
ops.fallocate = mergerfs::fallocate::fallocate;
|
||||
#endif
|
||||
ops.fgetattr = mergerfs::fgetattr::fgetattr;
|
||||
ops.fgetattr = mergerfs::fgetattr::fgetattr;
|
||||
#if FLOCK
|
||||
ops.flock = NULL;
|
||||
ops.flock = NULL;
|
||||
#endif
|
||||
ops.flush = mergerfs::flush::flush;
|
||||
ops.fsync = mergerfs::fsync::fsync;
|
||||
ops.fsyncdir = NULL;
|
||||
ops.ftruncate = mergerfs::ftruncate::ftruncate;
|
||||
ops.getattr = mergerfs::getattr::getattr;
|
||||
ops.getdir = NULL; /* deprecated; use readdir */
|
||||
ops.getxattr = mergerfs::getxattr::getxattr;
|
||||
ops.init = mergerfs::init::init;
|
||||
ops.ioctl = mergerfs::ioctl::ioctl;
|
||||
ops.link = mergerfs::link::link;
|
||||
ops.listxattr = mergerfs::listxattr::listxattr;
|
||||
ops.lock = NULL;
|
||||
ops.mkdir = mergerfs::mkdir::mkdir;
|
||||
ops.mknod = mergerfs::mknod::mknod;
|
||||
ops.open = mergerfs::open::open;
|
||||
ops.opendir = mergerfs::opendir::opendir;
|
||||
ops.poll = NULL;
|
||||
ops.read = mergerfs::read::read;
|
||||
ops.flush = mergerfs::flush::flush;
|
||||
ops.fsync = mergerfs::fsync::fsync;
|
||||
ops.fsyncdir = NULL;
|
||||
ops.ftruncate = mergerfs::ftruncate::ftruncate;
|
||||
ops.getattr = mergerfs::getattr::getattr;
|
||||
ops.getdir = NULL; /* deprecated; use readdir */
|
||||
ops.getxattr = mergerfs::getxattr::getxattr;
|
||||
ops.init = mergerfs::init::init;
|
||||
ops.ioctl = mergerfs::ioctl::ioctl;
|
||||
ops.link = mergerfs::link::link;
|
||||
ops.listxattr = mergerfs::listxattr::listxattr;
|
||||
ops.lock = NULL;
|
||||
ops.mkdir = mergerfs::mkdir::mkdir;
|
||||
ops.mknod = mergerfs::mknod::mknod;
|
||||
ops.open = mergerfs::open::open;
|
||||
ops.opendir = mergerfs::opendir::opendir;
|
||||
ops.poll = NULL;
|
||||
ops.read = mergerfs::read::read;
|
||||
#if READ_BUF
|
||||
ops.read_buf = mergerfs::read_buf::read_buf;
|
||||
ops.read_buf = mergerfs::read_buf::read_buf;
|
||||
#endif
|
||||
ops.readdir = mergerfs::readdir::readdir;
|
||||
ops.readlink = mergerfs::readlink::readlink;
|
||||
ops.release = mergerfs::release::release;
|
||||
ops.releasedir = mergerfs::releasedir::releasedir;
|
||||
ops.removexattr = mergerfs::removexattr::removexattr;
|
||||
ops.rename = mergerfs::rename::rename;
|
||||
ops.rmdir = mergerfs::rmdir::rmdir;
|
||||
ops.setxattr = mergerfs::setxattr::setxattr;
|
||||
ops.statfs = mergerfs::statfs::statfs;
|
||||
ops.symlink = mergerfs::symlink::symlink;
|
||||
ops.truncate = mergerfs::truncate::truncate;
|
||||
ops.unlink = mergerfs::unlink::unlink;
|
||||
ops.utime = NULL; /* deprecated; use utimens() */
|
||||
ops.utimens = mergerfs::utimens::utimens;
|
||||
ops.write = mergerfs::write::write;
|
||||
ops.readdir = mergerfs::readdir::readdir;
|
||||
ops.readlink = mergerfs::readlink::readlink;
|
||||
ops.release = mergerfs::release::release;
|
||||
ops.releasedir = mergerfs::releasedir::releasedir;
|
||||
ops.removexattr = mergerfs::removexattr::removexattr;
|
||||
ops.rename = mergerfs::rename::rename;
|
||||
ops.rmdir = mergerfs::rmdir::rmdir;
|
||||
ops.setxattr = mergerfs::setxattr::setxattr;
|
||||
ops.statfs = mergerfs::statfs::statfs;
|
||||
ops.symlink = mergerfs::symlink::symlink;
|
||||
ops.truncate = mergerfs::truncate::truncate;
|
||||
ops.unlink = mergerfs::unlink::unlink;
|
||||
ops.utime = NULL; /* deprecated; use utimens() */
|
||||
ops.utimens = mergerfs::utimens::utimens;
|
||||
ops.write = mergerfs::write::write;
|
||||
#if WRITE_BUF
|
||||
ops.write_buf = mergerfs::write_buf::write_buf;
|
||||
ops.write_buf = mergerfs::write_buf::write_buf;
|
||||
#endif
|
||||
|
||||
return ops;
|
||||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
setup_resources(void)
|
||||
{
|
||||
std::srand(time(NULL));
|
||||
mergerfs::resources::reset_umask();
|
||||
mergerfs::resources::maxout_rlimit_nofile();
|
||||
mergerfs::resources::maxout_rlimit_fsize();
|
||||
}
|
||||
}
|
||||
|
||||
namespace mergerfs
|
||||
{
|
||||
int
|
||||
main(const struct fuse_args &args,
|
||||
config::Config &config)
|
||||
main(const int argc,
|
||||
char **argv)
|
||||
{
|
||||
struct fuse_operations ops;
|
||||
struct fuse_args args;
|
||||
struct fuse_operations ops = {0};
|
||||
mergerfs::config::Config config;
|
||||
|
||||
ops = get_fuse_operations();
|
||||
args.argc = argc;
|
||||
args.argv = argv;
|
||||
args.allocated = 0;
|
||||
|
||||
std::srand(time(NULL));
|
||||
resources::reset_umask();
|
||||
resources::maxout_rlimit_nofile();
|
||||
resources::maxout_rlimit_fsize();
|
||||
mergerfs::options::parse(args,config);
|
||||
|
||||
local::setup_resources();
|
||||
local::get_fuse_operations(ops);
|
||||
|
||||
return fuse_main(args.argc,
|
||||
args.argv,
|
||||
|
|
@ -161,16 +186,14 @@ namespace mergerfs
|
|||
}
|
||||
|
||||
int
|
||||
main(int argc,
|
||||
char *argv[])
|
||||
main(int argc,
|
||||
char **argv)
|
||||
{
|
||||
int rv;
|
||||
mergerfs::config::Config config;
|
||||
struct fuse_args args = FUSE_ARGS_INIT(argc,argv);
|
||||
std::string appname;
|
||||
|
||||
mergerfs::options::parse(args,config);
|
||||
appname = local::getappname(argc,argv);
|
||||
if(appname == "clonepath")
|
||||
return clonepath::main(argc,argv);
|
||||
|
||||
rv = mergerfs::main(args,config);
|
||||
|
||||
return rv;
|
||||
return mergerfs::main(argc,argv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,10 @@ _mkdir(const fs::SearchFunc searchFunc,
|
|||
|
||||
rv = createPathFunc(srcmounts,dirname,createpath);
|
||||
if(createpath[0].base != existingpath[0].base)
|
||||
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
|
||||
{
|
||||
const mergerfs::ugid::SetResetGuard ugid(0,0);
|
||||
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
|
||||
}
|
||||
|
||||
path = fs::make_path(createpath[0].base,fusepath);
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,10 @@ _mknod(const fs::SearchFunc searchFunc,
|
|||
|
||||
createPathFunc(srcmounts,dirname,createpath);
|
||||
if(existingpath[0].base != createpath[0].base)
|
||||
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
|
||||
{
|
||||
const mergerfs::ugid::SetResetGuard ugid(0,0);
|
||||
fs::clonepath(existingpath[0].base,createpath[0].base,dirname);
|
||||
}
|
||||
|
||||
path = fs::make_path(createpath[0].base,fusepath);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue