Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support fuse3 #664

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ endif()
# Check for FUSE.
find_package (FUSE REQUIRED)
include_directories (${FUSE_INCLUDE_DIR})
add_definitions (-D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=29)
add_definitions (-D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=39)
if (CYGWIN)
# Cygwin build is intended to use WinFsp
add_definitions(-DCYGFUSE)
Expand Down
4 changes: 2 additions & 2 deletions cmake/FindFUSE.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ if (APPLE)
set (FUSE_NAMES libosxfuse.dylib fuse)
set (FUSE_SUFFIXES osxfuse fuse)
else ()
set (FUSE_NAMES fuse refuse)
set (FUSE_SUFFIXES fuse refuse)
set (FUSE_NAMES fuse3)
set (FUSE_SUFFIXES fuse3)
endif ()

# find include
Expand Down
29 changes: 26 additions & 3 deletions encfs/DirNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <cstring>
#ifdef __linux__
#include <sys/fsuid.h>
#include <sys/types.h>
#endif
#include <pthread.h>
#include <sys/stat.h>
Expand Down Expand Up @@ -199,7 +200,7 @@ bool RenameOp::apply() {
}

if (preserve_mtime) {
struct utimbuf ut;
::utimbuf ut;
ut.actime = st.st_atime;
ut.modtime = st.st_mtime;
::utime(last->newCName.c_str(), &ut);
Expand Down Expand Up @@ -555,7 +556,8 @@ int DirNode::mkdir(const char *plaintextPath, mode_t mode, uid_t uid,
return res;
}

int DirNode::rename(const char *fromPlaintext, const char *toPlaintext) {
int DirNode::rename(const char *fromPlaintext, const char *toPlaintext, const int flags) {
(void)flags;
Lock _lock(mutex);

string fromCName = rootDir + naming->encodePath(fromPlaintext);
Expand All @@ -565,6 +567,27 @@ int DirNode::rename(const char *fromPlaintext, const char *toPlaintext) {

VLOG(1) << "rename " << fromCName << " -> " << toCName;

if ((flags & (RENAME_NOREPLACE | RENAME_EXCHANGE)) == (RENAME_NOREPLACE | RENAME_EXCHANGE))
{
return -EINVAL;
}
if (flags & RENAME_NOREPLACE)
{
if (encfs::fileExists(toCName.c_str()))
{
RLOG(WARNING) << "rename aborted, " << toPlaintext << " (" << toCName << ") exists and RENAME_NOREPLACE used";
return -EEXIST;
}
}
if (flags & RENAME_EXCHANGE)
{
// TODO: implement this operation:
// If `RENAME_EXCHANGE` is specified, the filesystem
// must atomically exchange the two files, i.e. both must
// exist and neither may be deleted.
return -EINVAL;
}

std::shared_ptr<FileNode> toNode = findOrCreate(toPlaintext);

std::shared_ptr<RenameOp> renameOp;
Expand Down Expand Up @@ -614,7 +637,7 @@ int DirNode::rename(const char *fromPlaintext, const char *toPlaintext) {
}
#endif
if (preserve_mtime) {
struct utimbuf ut;
::utimbuf ut;
ut.actime = st.st_atime;
ut.modtime = st.st_mtime;
::utime(toCName.c_str(), &ut);
Expand Down
2 changes: 1 addition & 1 deletion encfs/DirNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class DirNode {
int mkdir(const char *plaintextPath, mode_t mode, uid_t uid = 0,
gid_t gid = 0);

int rename(const char *fromPlaintext, const char *toPlaintext);
int rename(const char *fromPlaintext, const char *toPlaintext, const int flags);

int link(const char *to, const char *from);

Expand Down
19 changes: 14 additions & 5 deletions encfs/FileUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1733,9 +1733,13 @@ RootPtr initFS(EncFS_Context *ctx, const std::shared_ptr<EncFS_Opts> &opts) {
return rootInfo;
}

void unmountFS(const char *mountPoint) {
// fuse_unmount returns void, is assumed to succeed
fuse_unmount(mountPoint, nullptr);
bool unmountFS(const char *mountPoint) {
#ifdef __linux__
std::string cmd = "fusermount3 -u '";
cmd += mountPoint;
cmd += '\'';
return system(cmd.c_str()) == 0;
#endif
#ifdef __APPLE__
// fuse_unmount does not work on Mac OS, see #428
// However it makes encfs to hang, so we must unmount
Expand All @@ -1744,7 +1748,9 @@ void unmountFS(const char *mountPoint) {
if (eno != EINVAL) { //[EINVAL] The requested directory is not in the mount table.
RLOG(ERROR) << "Filesystem unmount failed: " << strerror(eno);
}
return false;
}
return true;
#endif
#ifdef __CYGWIN__
pid_t pid;
Expand All @@ -1758,7 +1764,11 @@ void unmountFS(const char *mountPoint) {
if (pid > 0) {
waitpid(pid, &status, 0);
}
return true;
#endif

RLOG(ERROR) << "unknown system, Filesystem unmount failed";
return false;
}

int remountFS(EncFS_Context *ctx) {
Expand All @@ -1783,8 +1793,7 @@ bool unmountFS(EncFS_Context *ctx) {
}
// Time to unmount!
RLOG(INFO) << "Filesystem inactive, unmounting: " << ctx->opts->unmountPoint;
unmountFS(ctx->opts->unmountPoint.c_str());
return true;
return unmountFS(ctx->opts->unmountPoint.c_str());
}

} // namespace encfs
3 changes: 2 additions & 1 deletion encfs/FileUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ class EncFS_Context;

RootPtr initFS(EncFS_Context *ctx, const std::shared_ptr<EncFS_Opts> &opts);

void unmountFS(const char *mountPoint);
// return true if unmount of @p mountPoint was successful.
bool unmountFS(const char *mountPoint);

RootPtr createV6Config(EncFS_Context *ctx,
const std::shared_ptr<EncFS_Opts> &opts);
Expand Down
50 changes: 12 additions & 38 deletions encfs/encfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,17 +224,13 @@ int _do_getattr(FileNode *fnode, struct stat *stbuf) {
return res;
}

int encfs_getattr(const char *path, struct stat *stbuf) {
return withFileNode("getattr", path, nullptr, bind(_do_getattr, _1, stbuf));
}

int encfs_fgetattr(const char *path, struct stat *stbuf,
int encfs_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi) {
return withFileNode("fgetattr", path, fi, bind(_do_getattr, _1, stbuf));
}

int encfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *finfo) {
off_t offset, struct fuse_file_info *finfo, enum fuse_readdir_flags) {
EncFS_Context *ctx = context();

//unused parameters
Expand Down Expand Up @@ -264,13 +260,9 @@ int encfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
st.st_mode = fileType << 12;

// TODO: add offset support.
#if defined(fuse_fill_dir_flags)
if (filler(buf, name.c_str(), &st, 0, 0)) break;
#else
if (filler(buf, name.c_str(), &st, 0) != 0) {
if (filler(buf, name.c_str(), &st, 0, FUSE_FILL_DIR_PLUS)) {
break;
}
#endif

name = dt.nextPlaintextName(&fileType, &inode);
}
Expand Down Expand Up @@ -528,7 +520,7 @@ int encfs_link(const char *to, const char *from) {
return res;
}

int encfs_rename(const char *from, const char *to) {
int encfs_rename(const char *from, const char *to, unsigned int flags) {
EncFS_Context *ctx = context();

if (isReadOnly(ctx)) {
Expand All @@ -542,7 +534,7 @@ int encfs_rename(const char *from, const char *to) {
}

try {
res = FSRoot->rename(from, to);
res = FSRoot->rename(from, to, flags);
} catch (encfs::Error &err) {
RLOG(ERROR) << "error caught in rename: " << err.what();
}
Expand All @@ -553,7 +545,8 @@ int _do_chmod(EncFS_Context *, const string &cipherPath, mode_t mode) {
return chmod(cipherPath.c_str(), mode);
}

int encfs_chmod(const char *path, mode_t mode) {
int encfs_chmod(const char *path, mode_t mode, struct fuse_file_info *fi) {
(void)fi;
EncFS_Context *ctx = context();
if (isReadOnly(ctx)) {
return -EROFS;
Expand All @@ -566,7 +559,8 @@ int _do_chown(EncFS_Context *, const string &cyName, uid_t u, gid_t g) {
return (res == -1) ? -errno : ESUCCESS;
}

int encfs_chown(const char *path, uid_t uid, gid_t gid) {
int encfs_chown(const char *path, uid_t uid, gid_t gid, struct fuse_file_info *fi) {
(void)fi;
EncFS_Context *ctx = context();
if (isReadOnly(ctx)) {
return -EROFS;
Expand All @@ -576,35 +570,14 @@ int encfs_chown(const char *path, uid_t uid, gid_t gid) {

int _do_truncate(FileNode *fnode, off_t size) { return fnode->truncate(size); }

int encfs_truncate(const char *path, off_t size) {
EncFS_Context *ctx = context();
if (isReadOnly(ctx)) {
return -EROFS;
}
return withFileNode("truncate", path, nullptr, bind(_do_truncate, _1, size));
}

int encfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) {
int encfs_truncate(const char *path, off_t size, struct fuse_file_info *fi) {
EncFS_Context *ctx = context();
if (isReadOnly(ctx)) {
return -EROFS;
}
return withFileNode("ftruncate", path, fi, bind(_do_truncate, _1, size));
}

int _do_utime(EncFS_Context *, const string &cyName, struct utimbuf *buf) {
int res = utime(cyName.c_str(), buf);
return (res == -1) ? -errno : ESUCCESS;
}

int encfs_utime(const char *path, struct utimbuf *buf) {
EncFS_Context *ctx = context();
if (isReadOnly(ctx)) {
return -EROFS;
}
return withCipherPath("utime", path, bind(_do_utime, _1, _2, buf));
}

int _do_utimens(EncFS_Context *, const string &cyName,
const struct timespec ts[2]) {
#ifdef HAVE_UTIMENSAT
Expand All @@ -621,7 +594,8 @@ int _do_utimens(EncFS_Context *, const string &cyName,
return (res == -1) ? -errno : ESUCCESS;
}

int encfs_utimens(const char *path, const struct timespec ts[2]) {
int encfs_utimens(const char *path, const struct timespec ts[2], struct fuse_file_info *fi) {
(void)fi;
EncFS_Context *ctx = context();
if (isReadOnly(ctx)) {
return -EROFS;
Expand Down
19 changes: 7 additions & 12 deletions encfs/encfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,19 @@ static __inline int setfsgid(gid_t gid) {
}
#endif

int encfs_getattr(const char *path, struct stat *stbuf);
int encfs_fgetattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi);
int encfs_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi);
int encfs_readlink(const char *path, char *buf, size_t size);
int encfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *finfo);
int encfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *finfo, enum fuse_readdir_flags);
int encfs_mknod(const char *path, mode_t mode, dev_t rdev);
int encfs_mkdir(const char *path, mode_t mode);
int encfs_unlink(const char *path);
int encfs_rmdir(const char *path);
int encfs_symlink(const char *from, const char *to);
int encfs_rename(const char *from, const char *to);
int encfs_rename(const char *from, const char *to, unsigned int flags);
int encfs_link(const char *to, const char *from);
int encfs_chmod(const char *path, mode_t mode);
int encfs_chown(const char *path, uid_t uid, gid_t gid);
int encfs_truncate(const char *path, off_t size);
int encfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi);
int encfs_utime(const char *path, struct utimbuf *buf);
int encfs_chmod(const char *path, mode_t mode, struct fuse_file_info *fi);
int encfs_chown(const char *path, uid_t uid, gid_t gid, struct fuse_file_info *fi);
int encfs_truncate(const char *path, off_t size, struct fuse_file_info *fi);
int encfs_open(const char *path, struct fuse_file_info *info);
int encfs_create(const char *path, mode_t mode, struct fuse_file_info *info);
int encfs_release(const char *path, struct fuse_file_info *info);
Expand Down Expand Up @@ -105,7 +100,7 @@ int encfs_listxattr(const char *path, char *list, size_t size);
int encfs_removexattr(const char *path, const char *name);
#endif

int encfs_utimens(const char *path, const struct timespec ts[2]);
int encfs_utimens(const char *path, const struct timespec ts[2], struct fuse_file_info *fi);

} // namespace encfs

Expand Down
4 changes: 2 additions & 2 deletions encfs/encfs.pod
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,15 @@ Same as B<--nocache> but for data only.

=item B<--no-default-flags>

B<Encfs> adds the FUSE flags "use_ino" and "default_permissions" by default, as
B<Encfs> adds the FUSE flag "default_permissions" by default, as
of version 1.2.2, because that improves compatibility with some programs. If
for some reason you need to disable one or both of these flags, use the option
B<--no-default-flags>.

The following command lines produce the same result:

encfs raw crypt
encfs --no-default-flags raw crypt -- -o use_ino,default_permissions
encfs --no-default-flags raw crypt -- -o default_permissions

=item B<-o FUSE_ARG>

Expand Down
18 changes: 5 additions & 13 deletions encfs/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,6 @@ static bool processArgs(int argc, char *argv[],
// Add default flags unless --no-default-flags was passed
if (useDefaultFlags) {

// Expose the underlying stable inode number
PUSHARG("-o");
PUSHARG("use_ino");

// "default_permissions" comes with a performance cost, and only makes
// sense if "allow_other"" is used.
// But it works around the issues "open_readonly_workaround" causes,
Expand Down Expand Up @@ -615,12 +611,12 @@ static bool processArgs(int argc, char *argv[],

static void *idleMonitor(void *);

void *encfs_init(fuse_conn_info *conn) {
// \todo use the cfg object to configure EncFS behavior.
void *encfs_init(fuse_conn_info *conn, struct fuse_config *cfg) {
(void)conn;
(void)cfg;
auto *ctx = (EncFS_Context *)fuse_get_context()->private_data;

// set fuse connection options
conn->async_read = 1u;

#ifdef __CYGWIN__
// WinFsp needs this to partially handle read-only FS
// See https://github.com/billziss-gh/winfsp/issues/157 for details
Expand Down Expand Up @@ -679,8 +675,7 @@ int main(int argc, char *argv[]) {
if (encfsArgs->opts->unmount) {
// We use cout here to avoid logging to stderr (and to mess-up tests output)
cout << "Filesystem unmounting: " << encfsArgs->opts->unmountPoint << endl;
unmountFS(encfsArgs->opts->unmountPoint.c_str());
return 0;
return unmountFS(encfsArgs->opts->unmountPoint.c_str()) ? 0 : EXIT_FAILURE;
}

VLOG(1) << "Root directory: " << encfsArgs->opts->rootDir;
Expand All @@ -705,7 +700,6 @@ int main(int argc, char *argv[]) {
encfs_oper.chmod = encfs_chmod;
encfs_oper.chown = encfs_chown;
encfs_oper.truncate = encfs_truncate;
encfs_oper.utime = encfs_utime; // deprecated for utimens
encfs_oper.open = encfs_open;
encfs_oper.read = encfs_read;
encfs_oper.write = encfs_write;
Expand All @@ -726,8 +720,6 @@ int main(int argc, char *argv[]) {
encfs_oper.init = encfs_init;
// encfs_oper.access = encfs_access;
encfs_oper.create = encfs_create;
encfs_oper.ftruncate = encfs_ftruncate;
encfs_oper.fgetattr = encfs_fgetattr;
// encfs_oper.lock = encfs_lock;
encfs_oper.utimens = encfs_utimens;
// encfs_oper.bmap = encfs_bmap;
Expand Down
Loading