Skip to content

Commit

Permalink
Switch to libfuse 3.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikratio committed Jul 8, 2017
1 parent 6cc86fc commit 3414644
Show file tree
Hide file tree
Showing 11 changed files with 373 additions and 342 deletions.
3 changes: 0 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ addons:
- clang
- gcc
- gcc-6
- fuse
- libfuse2
- libfuse-dev
install: test/travis-install.sh
script: test/travis-build.sh

5 changes: 5 additions & 0 deletions ChangeLog.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
Unreleased Changes
------------------

* sshfs now requires libfuse 3.0.0 or newer.
* When supported by the kernel, sshfs now uses writeback caching.
* The `cache` option has been renamed to `dir_cache` for clarity.
* Added unit tests
* --debug now behaves like -o debug_sshfs, i.e. it enables sshfs
debugging messages rather than libfuse debugging messages.
* Documented limited hardlink support.
* Added support for building with Meson.
* Added support for more SSH options.
Expand Down
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ endif

sshfs_LDADD = $(SSHFS_LIBS)
sshfs_CFLAGS = $(SSHFS_CFLAGS)
sshfs_CPPFLAGS = -D_REENTRANT -DFUSE_USE_VERSION=26 -DLIBDIR=\"$(libdir)\" \
sshfs_CPPFLAGS = -D_REENTRANT -DFUSE_USE_VERSION=30 -DLIBDIR=\"$(libdir)\" \
-DIDMAP_DEFAULT="\"$(IDMAP_DEFAULT)\""

EXTRA_DIST = sshfs.1.in meson.build
Expand Down
7 changes: 4 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ Installation

First, download the latest SSHFS release from
https://github.com/libfuse/sshfs/releases. On Linux and BSD, you will
also need to have libfuse_ installed. On OS-X, you need OSXFUSE_
instead. Finally, you need the Glib_ development package (which should
be available from your operating system's package manager).
also need to install libfuse_ 3.0.0 or newer. On OS-X, you need
OSXFUSE_ instead. Finally, you need the Glib_ library with development
headers (which should be available from your operating system's
package manager).

To build and install, we recommend to use Meson_ (version 0.38 or
newer) and Ninja_. After extracting the sshfs tarball, create a
Expand Down
107 changes: 50 additions & 57 deletions cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,25 @@ uint64_t cache_get_write_ctr(void)
return res;
}

static int cache_getattr(const char *path, struct stat *stbuf)
static void *cache_init(struct fuse_conn_info *conn,
struct fuse_config *cfg)
{
void *res;
res = cache.next_oper->init(conn, cfg);

// Cache requires a path for each request
cfg->nullpath_ok = 0;

return res;
}

static int cache_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi)
{
int err = cache_get_attr(path, stbuf);
if (err) {
uint64_t wrctr = cache_get_write_ctr();
err = cache.next_oper->getattr(path, stbuf);
err = cache.next_oper->getattr(path, stbuf, fi);
if (!err)
cache_add_attr(path, stbuf, wrctr);
}
Expand Down Expand Up @@ -319,13 +332,14 @@ static int cache_releasedir(const char *path, struct fuse_file_info *fi)
}

static int cache_dirfill (void *buf, const char *name,
const struct stat *stbuf, off_t off)
const struct stat *stbuf, off_t off,
enum fuse_fill_dir_flags flags)
{
int err;
struct readdir_handle *ch;

ch = (struct readdir_handle*) buf;
err = ch->filler(ch->buf, name, stbuf, off);
err = ch->filler(ch->buf, name, stbuf, off, flags);
if (!err) {
g_ptr_array_add(ch->dir, g_strdup(name));
if (stbuf->st_mode & S_IFMT) {
Expand All @@ -341,7 +355,8 @@ static int cache_dirfill (void *buf, const char *name,
}

static int cache_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags flags)
{
struct readdir_handle ch;
struct file_handle *cfi;
Expand All @@ -358,7 +373,7 @@ static int cache_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
if (node->dir_valid - now >= 0) {
for(dir = node->dir; *dir != NULL; dir++)
// FIXME: What about st_mode?
filler(buf, *dir, 0, 0);
filler(buf, *dir, NULL, 0, 0);
pthread_mutex_unlock(&cache.lock);
return 0;
}
Expand All @@ -383,7 +398,7 @@ static int cache_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
ch.filler = filler;
ch.dir = g_ptr_array_new();
ch.wrctr = cache_get_write_ctr();
err = cache.next_oper->readdir(path, &ch, cache_dirfill, offset, fi);
err = cache.next_oper->readdir(path, &ch, cache_dirfill, offset, fi, flags);
g_ptr_array_add(ch.dir, NULL);
dir = (char **) ch.dir->pdata;
if (!err) {
Expand Down Expand Up @@ -436,9 +451,9 @@ static int cache_symlink(const char *from, const char *to)
return err;
}

static int cache_rename(const char *from, const char *to)
static int cache_rename(const char *from, const char *to, unsigned int flags)
{
int err = cache.next_oper->rename(from, to);
int err = cache.next_oper->rename(from, to, flags);
if (!err)
cache_do_rename(from, to);
return err;
Expand All @@ -454,33 +469,28 @@ static int cache_link(const char *from, const char *to)
return err;
}

static int cache_chmod(const char *path, mode_t mode)
{
int err = cache.next_oper->chmod(path, mode);
if (!err)
cache_invalidate(path);
return err;
}

static int cache_chown(const char *path, uid_t uid, gid_t gid)
static int cache_chmod(const char *path, mode_t mode,
struct fuse_file_info *fi)
{
int err = cache.next_oper->chown(path, uid, gid);
int err = cache.next_oper->chmod(path, mode, fi);
if (!err)
cache_invalidate(path);
return err;
}

static int cache_truncate(const char *path, off_t size)
static int cache_chown(const char *path, uid_t uid, gid_t gid,
struct fuse_file_info *fi)
{
int err = cache.next_oper->truncate(path, size);
int err = cache.next_oper->chown(path, uid, gid, fi);
if (!err)
cache_invalidate(path);
return err;
}

static int cache_utime(const char *path, struct utimbuf *buf)
static int cache_utimens(const char *path, const struct timespec tv[2],
struct fuse_file_info *fi)
{
int err = cache.next_oper->utime(path, buf);
int err = cache.next_oper->utimens(path, tv, fi);
if (!err)
cache_invalidate(path);
return err;
Expand All @@ -504,42 +514,27 @@ static int cache_create(const char *path, mode_t mode,
return err;
}

static int cache_ftruncate(const char *path, off_t size,
struct fuse_file_info *fi)
static int cache_truncate(const char *path, off_t size,
struct fuse_file_info *fi)
{
int err = cache.next_oper->ftruncate(path, size, fi);
int err = cache.next_oper->truncate(path, size, fi);
if (!err)
cache_invalidate(path);
return err;
}

static int cache_fgetattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi)
{
int err = cache_get_attr(path, stbuf);
if (err) {
uint64_t wrctr = cache_get_write_ctr();
err = cache.next_oper->fgetattr(path, stbuf, fi);
if (!err)
cache_add_attr(path, stbuf, wrctr);
}
return err;
}

static void cache_fill(struct fuse_operations *oper,
struct fuse_operations *cache_oper)
{
cache_oper->access = oper->access;
cache_oper->chmod = oper->chmod ? cache_chmod : NULL;
cache_oper->chown = oper->chown ? cache_chown : NULL;
cache_oper->create = oper->create ? cache_create : NULL;
cache_oper->fgetattr = oper->fgetattr ? cache_fgetattr : NULL;
cache_oper->flush = oper->flush;
cache_oper->fsync = oper->fsync;
cache_oper->ftruncate = oper->ftruncate ? cache_ftruncate : NULL;
cache_oper->getattr = oper->getattr ? cache_getattr : NULL;
cache_oper->getxattr = oper->getxattr;
cache_oper->init = oper->init;
cache_oper->init = cache_init;
cache_oper->link = oper->link ? cache_link : NULL;
cache_oper->listxattr = oper->listxattr;
cache_oper->mkdir = oper->mkdir ? cache_mkdir : NULL;
Expand All @@ -559,13 +554,11 @@ static void cache_fill(struct fuse_operations *oper,
cache_oper->symlink = oper->symlink ? cache_symlink : NULL;
cache_oper->truncate = oper->truncate ? cache_truncate : NULL;
cache_oper->unlink = oper->unlink ? cache_unlink : NULL;
cache_oper->utime = oper->utime ? cache_utime : NULL;
cache_oper->utimens = oper->utimens ? cache_utimens : NULL;
cache_oper->write = oper->write ? cache_write : NULL;
cache_oper->flag_nopath = 0;
cache_oper->flag_nullpath_ok = 0;
}

struct fuse_operations *cache_init(struct fuse_operations *oper)
struct fuse_operations *cache_wrap(struct fuse_operations *oper)
{
static struct fuse_operations cache_oper;
cache.next_oper = oper;
Expand All @@ -582,17 +575,17 @@ struct fuse_operations *cache_init(struct fuse_operations *oper)
}

static const struct fuse_opt cache_opts[] = {
{ "cache_timeout=%u", offsetof(struct cache, stat_timeout_secs), 0 },
{ "cache_timeout=%u", offsetof(struct cache, dir_timeout_secs), 0 },
{ "cache_timeout=%u", offsetof(struct cache, link_timeout_secs), 0 },
{ "cache_stat_timeout=%u", offsetof(struct cache, stat_timeout_secs), 0 },
{ "cache_dir_timeout=%u", offsetof(struct cache, dir_timeout_secs), 0 },
{ "cache_link_timeout=%u", offsetof(struct cache, link_timeout_secs), 0 },
{ "cache_max_size=%u", offsetof(struct cache, max_size), 0 },
{ "cache_clean_interval=%u", offsetof(struct cache,
clean_interval_secs), 0 },
{ "cache_min_clean_interval=%u", offsetof(struct cache,
min_clean_interval_secs), 0 },
{ "dcache_timeout=%u", offsetof(struct cache, stat_timeout_secs), 0 },
{ "dcache_timeout=%u", offsetof(struct cache, dir_timeout_secs), 0 },
{ "dcache_timeout=%u", offsetof(struct cache, link_timeout_secs), 0 },
{ "dcache_stat_timeout=%u", offsetof(struct cache, stat_timeout_secs), 0 },
{ "dcache_dir_timeout=%u", offsetof(struct cache, dir_timeout_secs), 0 },
{ "dcache_link_timeout=%u", offsetof(struct cache, link_timeout_secs), 0 },
{ "dcache_max_size=%u", offsetof(struct cache, max_size), 0 },
{ "dcache_clean_interval=%u", offsetof(struct cache,
clean_interval_secs), 0 },
{ "dcache_min_clean_interval=%u", offsetof(struct cache,
min_clean_interval_secs), 0 },
FUSE_OPT_END
};

Expand Down
2 changes: 1 addition & 1 deletion cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <fuse.h>
#include <fuse_opt.h>

struct fuse_operations *cache_init(struct fuse_operations *oper);
struct fuse_operations *cache_wrap(struct fuse_operations *oper);
int cache_parse_options(struct fuse_args *args);
void cache_add_attr(const char *path, const struct stat *stbuf, uint64_t wrctr);
void cache_invalidate(const char *path);
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ case "$target_os" in
esac

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
PKG_CHECK_MODULES([SSHFS], [fuse >= 2.3 glib-2.0 gthread-2.0])
PKG_CHECK_MODULES([SSHFS], [fuse >= 3.0 glib-2.0 gthread-2.0])
have_fuse_opt_parse=no
oldlibs="$LIBS"
LIBS="$LIBS $SSHFS_LIBS"
Expand Down
4 changes: 2 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ configure_file(input: 'sshfs.1.in',
configure_file(output: 'config.h',
configuration : cfg)

sshfs_deps = [ dependency('fuse', version: '>= 2.9'),
sshfs_deps = [ dependency('fuse3', version: '>= 3.0.0'),
dependency('glib-2.0'),
dependency('gthread-2.0') ]

executable('sshfs', sshfs_sources,
include_directories: include_dirs,
dependencies: sshfs_deps,
c_args: ['-DFUSE_USE_VERSION=26'],
c_args: ['-DFUSE_USE_VERSION=30'],
install: true,
install_dir: get_option('bindir'))

Expand Down
Loading

0 comments on commit 3414644

Please sign in to comment.