diff -pruN 3.6.0+repack-1/.appveyor.yml 3.6.0+repack+really2.10-0ubuntu1/.appveyor.yml
--- 3.6.0+repack-1/.appveyor.yml	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/.appveyor.yml	1970-01-01 00:00:00.000000000 +0000
@@ -1,19 +0,0 @@
-version: '{build}'
-
-install:
-
-# install WinFsp
-- appveyor DownloadFile https://github.com/billziss-gh/winfsp/releases/download/v1.4B2/winfsp-1.4.18211.msi
-- for %%f in ("winfsp-*.msi") do start /wait msiexec /i %%f /qn INSTALLLEVEL=1000
-
-# install FUSE for Cygwin (64-bit and 32-bit)
-- C:\cygwin64\bin\env.exe -i PATH=/bin bash "%ProgramFiles(x86)%\WinFsp\opt\cygfuse\install.sh"
-- C:\cygwin\bin\env.exe -i PATH=/bin bash "%ProgramFiles(x86)%\WinFsp\opt\cygfuse\install.sh"
-
-# install additional Cygwin packages (64-bit and 32-bit)
-- C:\cygwin64\setup-x86_64.exe -qnNdO -R C:\cygwin64 -s http://cygwin.mirror.constant.com -l C:\cygwin64\var\cache\setup -P libglib2.0-devel -P meson
-- C:\cygwin\setup-x86.exe -qnNdO -R C:\cygwin -s http://cygwin.mirror.constant.com -l C:\cygwin\var\cache\setup -P libglib2.0-devel -P meson
-
-build_script:
-- C:\cygwin64\bin\env.exe -i PATH=/bin bash test\appveyor-build.sh
-- C:\cygwin\bin\env.exe -i PATH=/bin bash test\appveyor-build.sh
diff -pruN 3.6.0+repack-1/AUTHORS 3.6.0+repack+really2.10-0ubuntu1/AUTHORS
--- 3.6.0+repack-1/AUTHORS	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/AUTHORS	2017-08-03 16:00:34.000000000 +0000
@@ -15,44 +15,21 @@ Contributors (autogenerated list)
 
 Alan Jenkins <alan.christopher.jenkins@gmail.com>
 Alexander Neumann <alexander@bumpern.de>
-Anatol Pomozov <anatol.pomozov@gmail.com>
 Benjamin Fleischer <fleiben@gmail.com>
 Berserker <berserker.troll@yandex.com>
 Bill Zissimopoulos <billziss@navimatics.com>
-Brandon Carter <b-carter@users.noreply.github.com>
 Chris Wolfe <cwolfe@chromium.org>
-Clayton G. Hobbs <clay@lakeserv.net>
-Daniel Lublin <daniel@lublin.se>
-DrDaveD <2129743+DrDaveD@users.noreply.github.com>
 gala <gala132@users.noreply.github.com>
-Galen Getsov <4815620+ggetsov@users.noreply.github.com>
 George Vlahavas <vlahavas@gmail.com>
-G.raud Meyer <graud@gmx.com>
-harrim4n <git@harrim4n.com>
 Jakub Jelen <jjelen@redhat.com>
-Josh Triplett <josh@joshtriplett.org>
 Julio Merino <jmmv@google.com>
 Julio Merino <jmmv@meroh.net>
-kalvdans <github@kalvdans.no-ip.org>
-Michael Forney <mforney@mforney.org>
 Mike Kelly <mike@pair.com>
-Mike Salvatore <mike.s.salvatore@gmail.com>
 Miklos Szeredi <miklos@szeredi.hu>
 Miklos Szeredi <mszeredi@suse.cz>
-mssalvatore <mike.s.salvatore@gmail.com>
 Nikolaus Rath <Nikolaus@rath.org>
 Percy Jahn <email@percyjahn.de>
 Qais Patankar <qaisjp@gmail.com>
-Quentin Rameau <quinq@fifth.space>
-Reid Wagner <wagnerreid@gmail.com>
 Rian Hunter <rian@alum.mit.edu>
-Rian Hunter <rianhunter@users.noreply.github.com>
-Samuel Murray <samuel.murray@outlook.com>
-S. D. Cloudt <s.d.cloudt@student.tue.nl>
-smheidrich <smheidrich@weltenfunktion.de>
-sunwire <50745572+sunwire@users.noreply.github.com>
-Tim Harder <radhermit@gmail.com>
-Timo Savola <timo.savola@iki.fi>
 tpoindessous <thomas@poindessous.com>
-Viktor Szakats <vszakats@users.noreply.github.com>
 Zoltan Kuscsik <zoltan.kuscsik@linaro.org>
diff -pruN 3.6.0+repack-1/cache.c 3.6.0+repack+really2.10-0ubuntu1/cache.c
--- 3.6.0+repack-1/cache.c	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/cache.c	2017-08-03 16:00:34.000000000 +0000
@@ -8,7 +8,6 @@
 
 #include "cache.h"
 #include <stdio.h>
-#include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
@@ -28,7 +27,7 @@ struct cache {
 	unsigned int max_size;
 	unsigned int clean_interval_secs;
 	unsigned int min_clean_interval_secs;
-	struct fuse_operations *next_oper;
+	struct fuse_cache_operations *next_oper;
 	GHashTable *table;
 	pthread_mutex_t lock;
 	time_t last_cleaned;
@@ -47,22 +46,14 @@ struct node {
 	time_t valid;
 };
 
-struct readdir_handle {
+struct fuse_cache_dirhandle {
 	const char *path;
-	void *buf;
-	fuse_fill_dir_t filler;
+	fuse_dirh_t h;
+	fuse_dirfil_t filler;
 	GPtrArray *dir;
 	uint64_t wrctr;
 };
 
-struct file_handle {
-	/* Did we send an open request to the underlying fs? */
-	int is_open;
-
-	/* If so, this will hold its handle */
-	unsigned long fs_fh;
-};
-
 static void free_node(gpointer node_)
 {
 	struct node *node = (struct node *) node_;
@@ -117,12 +108,15 @@ static void cache_purge_parent(const cha
 
 void cache_invalidate(const char *path)
 {
+	if (!cache.on)
+		return;
+
 	pthread_mutex_lock(&cache.lock);
 	cache_purge(path);
 	pthread_mutex_unlock(&cache.lock);
 }
 
-static void cache_invalidate_write(const char *path)
+void cache_invalidate_write(const char *path)
 {
 	pthread_mutex_lock(&cache.lock);
 	cache_purge(path);
@@ -174,6 +168,9 @@ void cache_add_attr(const char *path, co
 {
 	struct node *node;
 
+	if (!cache.on)
+		return;
+
 	pthread_mutex_lock(&cache.lock);
 	if (wrctr == cache.write_ctr) {
 		node = cache_get(path);
@@ -251,25 +248,12 @@ uint64_t cache_get_write_ctr(void)
 	return res;
 }
 
-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)
+static int cache_getattr(const char *path, struct stat *stbuf)
 {
 	int err = cache_get_attr(path, stbuf);
 	if (err) {
 		uint64_t wrctr = cache_get_write_ctr();
-		err = cache.next_oper->getattr(path, stbuf, fi);
+		err = cache.next_oper->oper.getattr(path, stbuf);
 		if (!err)
 			cache_add_attr(path, stbuf, wrctr);
 	}
@@ -293,53 +277,17 @@ static int cache_readlink(const char *pa
 		}
 	}
 	pthread_mutex_unlock(&cache.lock);
-	err = cache.next_oper->readlink(path, buf, size);
+	err = cache.next_oper->oper.readlink(path, buf, size);
 	if (!err)
 		cache_add_link(path, buf, size);
 
 	return err;
 }
 
-
-static int cache_opendir(const char *path, struct fuse_file_info *fi)
-{
-	(void) path;
-	struct file_handle *cfi;
-
-	cfi = malloc(sizeof(struct file_handle));
-	if(cfi == NULL)
-		return -ENOMEM;
-	cfi->is_open = 0;
-	fi->fh = (unsigned long) cfi;
-	return 0;
-}
-
-static int cache_releasedir(const char *path, struct fuse_file_info *fi)
+static int cache_dirfill(fuse_cache_dirh_t ch, const char *name,
+                         const struct stat *stbuf)
 {
-	int err;
-	struct file_handle *cfi;
-	
-	cfi = (struct file_handle*) fi->fh;
-	
-	if(cfi->is_open) {
-		fi->fh = cfi->fs_fh;
-		err = cache.next_oper->releasedir(path, fi);
-	} else
-		err = 0;
-
-	free(cfi);
-	return err;
-}
-
-static int cache_dirfill (void *buf, const char *name,
-			  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, flags);
+	int err = ch->filler(ch->h, name, 0, 0);
 	if (!err) {
 		g_ptr_array_add(ch->dir, g_strdup(name));
 		if (stbuf->st_mode & S_IFMT) {
@@ -354,66 +302,61 @@ static int cache_dirfill (void *buf, con
 	return err;
 }
 
-static int cache_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
-			 off_t offset, struct fuse_file_info *fi,
-			 enum fuse_readdir_flags flags)
+static int cache_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
 {
-	struct readdir_handle ch;
-	struct file_handle *cfi;
+	struct fuse_cache_dirhandle ch;
 	int err;
 	char **dir;
 	struct node *node;
 
-	assert(offset == 0);
-	
 	pthread_mutex_lock(&cache.lock);
 	node = cache_lookup(path);
 	if (node != NULL && node->dir != NULL) {
 		time_t now = time(NULL);
 		if (node->dir_valid - now >= 0) {
 			for(dir = node->dir; *dir != NULL; dir++)
-				// FIXME: What about st_mode?
-				filler(buf, *dir, NULL, 0, 0);
+				filler(h, *dir, 0, 0);
 			pthread_mutex_unlock(&cache.lock);
 			return 0;
 		}
 	}
 	pthread_mutex_unlock(&cache.lock);
 
-	cfi = (struct file_handle*) fi->fh;
-	if(cfi->is_open)
-		fi->fh = cfi->fs_fh;
-	else {
-		if(cache.next_oper->opendir) {
-			err = cache.next_oper->opendir(path, fi);
-			if(err)
-				return err;
-		}
-		cfi->is_open = 1;
-		cfi->fs_fh = fi->fh;
-	} 
-	
 	ch.path = path;
-	ch.buf = buf;
+	ch.h = h;
 	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, flags);
+	err = cache.next_oper->cache_getdir(path, &ch, cache_dirfill);
 	g_ptr_array_add(ch.dir, NULL);
 	dir = (char **) ch.dir->pdata;
-	if (!err) {
+	if (!err)
 		cache_add_dir(path, dir);
-	} else {
+	else
 		g_strfreev(dir);
-	}
 	g_ptr_array_free(ch.dir, FALSE);
-
 	return err;
 }
 
+static int cache_unity_dirfill(fuse_cache_dirh_t ch, const char *name,
+                               const struct stat *stbuf)
+{
+	(void) stbuf;
+	return ch->filler(ch->h, name, 0, 0);
+}
+
+static int cache_unity_getdir(const char *path, fuse_dirh_t h,
+                              fuse_dirfil_t filler)
+{
+	struct fuse_cache_dirhandle ch;
+	ch.h = h;
+	ch.filler = filler;
+	return cache.next_oper->cache_getdir(path, &ch, cache_unity_dirfill);
+}
+
 static int cache_mknod(const char *path, mode_t mode, dev_t rdev)
 {
-	int err = cache.next_oper->mknod(path, mode, rdev);
+	int err = cache.next_oper->oper.mknod(path, mode, rdev);
 	if (!err)
 		cache_invalidate_dir(path);
 	return err;
@@ -421,7 +364,7 @@ static int cache_mknod(const char *path,
 
 static int cache_mkdir(const char *path, mode_t mode)
 {
-	int err = cache.next_oper->mkdir(path, mode);
+	int err = cache.next_oper->oper.mkdir(path, mode);
 	if (!err)
 		cache_invalidate_dir(path);
 	return err;
@@ -429,7 +372,7 @@ static int cache_mkdir(const char *path,
 
 static int cache_unlink(const char *path)
 {
-	int err = cache.next_oper->unlink(path);
+	int err = cache.next_oper->oper.unlink(path);
 	if (!err)
 		cache_invalidate_dir(path);
 	return err;
@@ -437,7 +380,7 @@ static int cache_unlink(const char *path
 
 static int cache_rmdir(const char *path)
 {
-	int err = cache.next_oper->rmdir(path);
+	int err = cache.next_oper->oper.rmdir(path);
 	if (!err)
 		cache_invalidate_dir(path);
 	return err;
@@ -445,15 +388,15 @@ static int cache_rmdir(const char *path)
 
 static int cache_symlink(const char *from, const char *to)
 {
-	int err = cache.next_oper->symlink(from, to);
+	int err = cache.next_oper->oper.symlink(from, to);
 	if (!err)
 		cache_invalidate_dir(to);
 	return err;
 }
 
-static int cache_rename(const char *from, const char *to, unsigned int flags)
+static int cache_rename(const char *from, const char *to)
 {
-	int err = cache.next_oper->rename(from, to, flags);
+	int err = cache.next_oper->oper.rename(from, to);
 	if (!err)
 		cache_do_rename(from, to);
 	return err;
@@ -461,7 +404,7 @@ static int cache_rename(const char *from
 
 static int cache_link(const char *from, const char *to)
 {
-	int err = cache.next_oper->link(from, to);
+	int err = cache.next_oper->oper.link(from, to);
 	if (!err) {
 		cache_invalidate(from);
 		cache_invalidate_dir(to);
@@ -469,28 +412,33 @@ static int cache_link(const char *from,
 	return err;
 }
 
-static int cache_chmod(const char *path, mode_t mode,
-                       struct fuse_file_info *fi)
+static int cache_chmod(const char *path, mode_t mode)
+{
+	int err = cache.next_oper->oper.chmod(path, mode);
+	if (!err)
+		cache_invalidate(path);
+	return err;
+}
+
+static int cache_chown(const char *path, uid_t uid, gid_t gid)
 {
-	int err = cache.next_oper->chmod(path, mode, fi);
+	int err = cache.next_oper->oper.chown(path, uid, gid);
 	if (!err)
 		cache_invalidate(path);
 	return err;
 }
 
-static int cache_chown(const char *path, uid_t uid, gid_t gid,
-                       struct fuse_file_info *fi)
+static int cache_truncate(const char *path, off_t size)
 {
-	int err = cache.next_oper->chown(path, uid, gid, fi);
+	int err = cache.next_oper->oper.truncate(path, size);
 	if (!err)
 		cache_invalidate(path);
 	return err;
 }
 
-static int cache_utimens(const char *path, const struct timespec tv[2],
-			 struct fuse_file_info *fi)
+static int cache_utime(const char *path, struct utimbuf *buf)
 {
-	int err = cache.next_oper->utimens(path, tv, fi);
+	int err = cache.next_oper->oper.utime(path, buf);
 	if (!err)
 		cache_invalidate(path);
 	return err;
@@ -499,95 +447,140 @@ static int cache_utimens(const char *pat
 static int cache_write(const char *path, const char *buf, size_t size,
                        off_t offset, struct fuse_file_info *fi)
 {
-	int res = cache.next_oper->write(path, buf, size, offset, fi);
+	int res = cache.next_oper->oper.write(path, buf, size, offset, fi);
 	if (res >= 0)
 		cache_invalidate_write(path);
 	return res;
 }
 
+#if FUSE_VERSION >= 25
 static int cache_create(const char *path, mode_t mode,
                         struct fuse_file_info *fi)
 {
-	int err = cache.next_oper->create(path, mode, fi);
+	int err = cache.next_oper->oper.create(path, mode, fi);
 	if (!err)
 		cache_invalidate_dir(path);
 	return err;
 }
 
-static int cache_truncate(const char *path, off_t size,
-			  struct fuse_file_info *fi)
+static int cache_ftruncate(const char *path, off_t size,
+                           struct fuse_file_info *fi)
 {
-	int err = cache.next_oper->truncate(path, size, fi);
+	int err = cache.next_oper->oper.ftruncate(path, size, fi);
 	if (!err)
 		cache_invalidate(path);
 	return err;
 }
 
-static void cache_fill(struct fuse_operations *oper,
+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->oper.fgetattr(path, stbuf, fi);
+		if (!err)
+			cache_add_attr(path, stbuf, wrctr);
+	}
+	return err;
+}
+#endif
+
+static void cache_unity_fill(struct fuse_cache_operations *oper,
+                             struct fuse_operations *cache_oper)
+{
+#if FUSE_VERSION >= 23
+	cache_oper->init        = oper->oper.init;
+#endif
+	cache_oper->getattr     = oper->oper.getattr;
+	cache_oper->access	= oper->oper.access;
+	cache_oper->readlink    = oper->oper.readlink;
+	cache_oper->getdir      = cache_unity_getdir;
+	cache_oper->mknod       = oper->oper.mknod;
+	cache_oper->mkdir       = oper->oper.mkdir;
+	cache_oper->symlink     = oper->oper.symlink;
+	cache_oper->unlink      = oper->oper.unlink;
+	cache_oper->rmdir       = oper->oper.rmdir;
+	cache_oper->rename      = oper->oper.rename;
+	cache_oper->link        = oper->oper.link;
+	cache_oper->chmod       = oper->oper.chmod;
+	cache_oper->chown       = oper->oper.chown;
+	cache_oper->truncate    = oper->oper.truncate;
+	cache_oper->utime       = oper->oper.utime;
+	cache_oper->open        = oper->oper.open;
+	cache_oper->read        = oper->oper.read;
+	cache_oper->write       = oper->oper.write;
+	cache_oper->flush       = oper->oper.flush;
+	cache_oper->release     = oper->oper.release;
+	cache_oper->fsync       = oper->oper.fsync;
+	cache_oper->statfs      = oper->oper.statfs;
+	cache_oper->setxattr    = oper->oper.setxattr;
+	cache_oper->getxattr    = oper->oper.getxattr;
+	cache_oper->listxattr   = oper->oper.listxattr;
+	cache_oper->removexattr = oper->oper.removexattr;
+#if FUSE_VERSION >= 25
+	cache_oper->create      = oper->oper.create;
+	cache_oper->ftruncate   = oper->oper.ftruncate;
+	cache_oper->fgetattr    = oper->oper.fgetattr;
+#endif
+#if FUSE_VERSION >= 29
+	cache_oper->flag_nullpath_ok = oper->oper.flag_nullpath_ok;
+	cache_oper->flag_nopath  = oper->oper.flag_nopath;
+#endif
+}
+
+static void cache_fill(struct fuse_cache_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->flush    = oper->flush;
-	cache_oper->fsync    = oper->fsync;
-	cache_oper->getattr  = oper->getattr ? cache_getattr : NULL;
-	cache_oper->getxattr = oper->getxattr;
-	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;
-	cache_oper->mknod    = oper->mknod ? cache_mknod : NULL;
-	cache_oper->open     = oper->open;
-	cache_oper->opendir  = cache_opendir;
-	cache_oper->read     = oper->read;
-	cache_oper->readdir  = oper->readdir ? cache_readdir : NULL;
-	cache_oper->readlink = oper->readlink ? cache_readlink : NULL;
-	cache_oper->release  = oper->release;
-	cache_oper->releasedir = cache_releasedir;
-	cache_oper->removexattr = oper->removexattr;
-	cache_oper->rename   = oper->rename ? cache_rename : NULL;
-	cache_oper->rmdir    = oper->rmdir ? cache_rmdir : NULL;
-	cache_oper->setxattr = oper->setxattr;
-	cache_oper->statfs   = oper->statfs;
-	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->utimens  = oper->utimens ? cache_utimens : NULL;
-	cache_oper->write    = oper->write ? cache_write : NULL;
+	cache_oper->getattr  = oper->oper.getattr ? cache_getattr : NULL;
+	cache_oper->readlink = oper->oper.readlink ? cache_readlink : NULL;
+	cache_oper->getdir   = oper->cache_getdir ? cache_getdir : NULL;
+	cache_oper->mknod    = oper->oper.mknod ? cache_mknod : NULL;
+	cache_oper->mkdir    = oper->oper.mkdir ? cache_mkdir : NULL;
+	cache_oper->symlink  = oper->oper.symlink ? cache_symlink : NULL;
+	cache_oper->unlink   = oper->oper.unlink ? cache_unlink : NULL;
+	cache_oper->rmdir    = oper->oper.rmdir ? cache_rmdir : NULL;
+	cache_oper->rename   = oper->oper.rename ? cache_rename : NULL;
+	cache_oper->link     = oper->oper.link ? cache_link : NULL;
+	cache_oper->chmod    = oper->oper.chmod ? cache_chmod : NULL;
+	cache_oper->chown    = oper->oper.chown ? cache_chown : NULL;
+	cache_oper->truncate = oper->oper.truncate ? cache_truncate : NULL;
+	cache_oper->utime    = oper->oper.utime ? cache_utime : NULL;
+	cache_oper->write    = oper->oper.write ? cache_write : NULL;
+#if FUSE_VERSION >= 25
+	cache_oper->create   = oper->oper.create ? cache_create : NULL;
+	cache_oper->ftruncate = oper->oper.ftruncate ? cache_ftruncate : NULL;
+	cache_oper->fgetattr = oper->oper.fgetattr ? cache_fgetattr : NULL;
+#endif
+#if FUSE_VERSION >= 29
+	cache_oper->flag_nullpath_ok = 0;
+	cache_oper->flag_nopath = 0;
+#endif
+
 }
 
-struct fuse_operations *cache_wrap(struct fuse_operations *oper)
+struct fuse_operations *cache_init(struct fuse_cache_operations *oper)
 {
 	static struct fuse_operations cache_oper;
 	cache.next_oper = oper;
 
-	cache_fill(oper, &cache_oper);
-	pthread_mutex_init(&cache.lock, NULL);
-	cache.table = g_hash_table_new_full(g_str_hash, g_str_equal,
-					    g_free, free_node);
-	if (cache.table == NULL) {
-		fprintf(stderr, "failed to create cache\n");
-		return NULL;
+	cache_unity_fill(oper, &cache_oper);
+	if (cache.on) {
+		cache_fill(oper, &cache_oper);
+		pthread_mutex_init(&cache.lock, NULL);
+		cache.table = g_hash_table_new_full(g_str_hash, g_str_equal,
+						    g_free, free_node);
+		if (cache.table == NULL) {
+			fprintf(stderr, "failed to create cache\n");
+			return NULL;
+		}
 	}
 	return &cache_oper;
 }
 
 static const struct fuse_opt cache_opts[] = {
-	{ "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 },
-
-	/* For backwards compatibility */
+	{ "cache=yes", offsetof(struct cache, on), 1 },
+	{ "cache=no", offsetof(struct cache, on), 0 },
 	{ "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 },
@@ -596,9 +589,9 @@ static const struct fuse_opt cache_opts[
 	{ "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 },
+	                                      clean_interval_secs), 0 },
 	{ "cache_min_clean_interval=%u", offsetof(struct cache,
-						   min_clean_interval_secs), 0 },
+	                                          min_clean_interval_secs), 0 },
 	FUSE_OPT_END
 };
 
@@ -610,6 +603,7 @@ int cache_parse_options(struct fuse_args
 	cache.max_size = DEFAULT_MAX_CACHE_SIZE;
 	cache.clean_interval_secs = DEFAULT_CACHE_CLEAN_INTERVAL_SECS;
 	cache.min_clean_interval_secs = DEFAULT_MIN_CACHE_CLEAN_INTERVAL_SECS;
+	cache.on = 1;
 
 	return fuse_opt_parse(args, &cache, cache_opts, NULL);
 }
diff -pruN 3.6.0+repack-1/cache.h 3.6.0+repack+really2.10-0ubuntu1/cache.h
--- 3.6.0+repack-1/cache.h	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/cache.h	2017-08-03 16:00:34.000000000 +0000
@@ -9,7 +9,20 @@
 #include <fuse.h>
 #include <fuse_opt.h>
 
-struct fuse_operations *cache_wrap(struct fuse_operations *oper);
+#ifndef FUSE_VERSION
+#define FUSE_VERSION (FUSE_MAJOR_VERSION * 10 + FUSE_MINOR_VERSION)
+#endif
+
+typedef struct fuse_cache_dirhandle *fuse_cache_dirh_t;
+typedef int (*fuse_cache_dirfil_t) (fuse_cache_dirh_t h, const char *name,
+                                    const struct stat *stbuf);
+
+struct fuse_cache_operations {
+    struct fuse_operations oper;
+    int (*cache_getdir) (const char *, fuse_cache_dirh_t, fuse_cache_dirfil_t);
+};
+
+struct fuse_operations *cache_init(struct fuse_cache_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);
diff -pruN 3.6.0+repack-1/ChangeLog.rst 3.6.0+repack+really2.10-0ubuntu1/ChangeLog.rst
--- 3.6.0+repack-1/ChangeLog.rst	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/ChangeLog.rst	2017-08-03 16:00:34.000000000 +0000
@@ -1,95 +1,9 @@
-Release 3.6.0 (2019-11-03)
---------------------------
-
-* Added "-o direct_io" option.
-  This option disables the use of page cache in kernel.
-  This is useful for example if the file size is not known before reading it.
-  For example if you mount /proc dir from a remote host without the direct_io
-  option, the read always will return zero bytes instead of actual data.
-* Added --verbose option.
-* Fixed a number of compiler warnings.
-* Improved performance under OS X.
-
-
-Release 3.5.2 (2019-04-13)
---------------------------
-
-* Fixed "-o idmap=user" to map both UID and GID on all OSs.
-* Fixed improper handling of sequential spaces spaces in "ssh_command" option
-
-Release 3.5.1 (2018-12-22)
---------------------------
-
-* Documentation updates
-* Build system updates
-* Added "BindInterface" as valid "-o" option.
-
-Release 3.5.0 (2018-08-28)
---------------------------
-
-* Fixed error code returned by rename(), allowing proper fallback.
-* Port to Cygwin.
-
-Release 3.4.0 (2018-06-29)
---------------------------
-
-* Make utimens(NULL) result in timestamp "now" -- no more touched files
-  dated 1970-01-01
-* New `createmode` workaround.
-* Fix `fstat` workaround regression.
-
-Release 3.3.2 (2018-04-29)
---------------------------
-
-* New `renamexdev` workaround.
-
-Release 3.3.1 (2017-10-25)
---------------------------
-
-* Manpage is now installed in correct directory.
-* SSHFS now supports (or rather: ignores) some options that it may
-  receive as result of being mounted from ``/etc/mtab``. This includes
-  things like ``user``, ``netdev``, or ``auto``.
-
-SSHFS 3.3.0 (2017-09-20)
-------------------------
-
-* Dropped support for writeback caching (and, as a consequence,
-  "unreliable append" operation). As of kernel 4.14, the FUSE module's
-  writeback implementation is not compatible with network filesystems
-  and there are no imminent plans to change that.
-* Add support for mounting from /etc/fstab
-* Dropped support for building with autotools.
-* Added missing options to man page.
-
-Release 3.2.0 (2017-08-06)
---------------------------
-
-* Re-enabled writeback cache.
-* SSHFS now supports O_APPEND.
-
-Release 3.1.0 (2017-08-04)
---------------------------
-
-* Temporarily disabled the writeback cache feature, since there
-  have been reports of dataloss when appending to files when
-  writeback caching is enabled.
+Release 2.10 (2017-08-03)
+-------------------------
 
 * Fixed a crash due to a race condition when listing
   directory contents.
-
-* For improved backwards compatibility, SSHFS now also silently
-  accepts the old ``-o cache_*`` options.
-  
-Release 3.0.0 (2017-07-08)
---------------------------
-
-* sshfs now requires libfuse 3.1.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.
diff -pruN 3.6.0+repack-1/configure.ac 3.6.0+repack+really2.10-0ubuntu1/configure.ac
--- 3.6.0+repack-1/configure.ac	1970-01-01 00:00:00.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/configure.ac	2017-08-03 16:00:34.000000000 +0000
@@ -0,0 +1,44 @@
+AC_INIT(sshfs, 2.10)
+AC_CANONICAL_TARGET
+AM_INIT_AUTOMAKE([foreign subdir-objects])
+AM_CONFIG_HEADER(config.h)
+
+AC_PROG_CC
+AM_PROG_CC_C_O
+CFLAGS="$CFLAGS -Wall -W"
+LIBS=
+AC_SEARCH_LIBS(dlsym, [dl])
+LIBS=
+
+case "$target_os" in
+    *linux*) osname=linux;;
+    *darwin*) osname=darwin;;
+    *) osname=unknown;;
+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])
+have_fuse_opt_parse=no
+oldlibs="$LIBS"
+LIBS="$LIBS $SSHFS_LIBS"
+AC_CHECK_FUNC([fuse_opt_parse], [have_fuse_opt_parse=yes])
+LIBS="$oldlibs"
+if test "$have_fuse_opt_parse" = no -o "$osname" = darwin; then
+	CFLAGS="$CFLAGS -I${srcdir}/compat"
+fi
+AM_CONDITIONAL(FUSE_OPT_COMPAT, test "$have_fuse_opt_parse" = no)
+AM_CONDITIONAL(DARWIN_COMPAT, test "$osname" = darwin)
+
+AC_CHECK_PROG(UNMOUNT_COMMAND, fusermount, fusermount -u, umount)
+
+# TODO: Figure out why we special-case this in Darwin.  Would be nice if
+# the default setting was consistent across platforms so we wouldn't need
+# to care about it here.
+case "$osname" in
+    darwin) IDMAP_DEFAULT=user ;;
+    *) IDMAP_DEFAULT=none ;;
+esac
+AC_SUBST(IDMAP_DEFAULT)
+
+AC_CONFIG_FILES([Makefile test/Makefile])
+AC_OUTPUT
diff -pruN 3.6.0+repack-1/debian/changelog 3.6.0+repack+really2.10-0ubuntu1/debian/changelog
--- 3.6.0+repack-1/debian/changelog	2019-11-16 02:31:27.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/debian/changelog	2019-11-26 09:36:00.000000000 +0000
@@ -1,23 +1,10 @@
-sshfs-fuse (3.6.0+repack-1) unstable; urgency=medium
+sshfs-fuse (3.6.0+repack+really2.10-0ubuntu1) focal; urgency=medium
 
-  * New upstream release.
-  * Standards-Version: 4.4.1.
-  * Upload to unstable.
+  * Revert to 2.10 until debian fix their fuse -> fuse3 upgrade and/or
+    co-installability issues. The fuse3 dependency of 3.6.0 breaks
+    Kubuntu and UbuntuStudio ISO builds.
 
- -- Dmitry Smirnov <onlyjob@debian.org>  Sat, 16 Nov 2019 13:31:27 +1100
-
-sshfs-fuse (3.5.1+repack-1) experimental; urgency=medium
-
-  * New upstream release (Closes: #871019).
-  * (Build-)Depends:
-    + python3-docutils
-    - libfuse-dev
-    + libfuse3-dev
-    - fuse
-    + fuse3
-  * Standards-Version: 4.3.0.
-
- -- Dmitry Smirnov <onlyjob@debian.org>  Fri, 01 Feb 2019 14:26:20 +1100
+ -- Rik Mills <rikmills@kde.org>  Tue, 26 Nov 2019 09:36:00 +0000
 
 sshfs-fuse (2.10+repack-2) unstable; urgency=medium
 
diff -pruN 3.6.0+repack-1/debian/clean 3.6.0+repack+really2.10-0ubuntu1/debian/clean
--- 3.6.0+repack-1/debian/clean	2019-11-16 02:28:24.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/debian/clean	2014-01-24 00:39:39.000000000 +0000
@@ -1,4 +1 @@
-## Debian CI:
-debian/.gitlab-ci.yml
-
 configure
diff -pruN 3.6.0+repack-1/debian/control 3.6.0+repack+really2.10-0ubuntu1/debian/control
--- 3.6.0+repack-1/debian/control	2019-11-16 02:30:39.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/debian/control	2019-11-26 09:36:00.000000000 +0000
@@ -1,19 +1,14 @@
 Source: sshfs-fuse
 Section: utils
 Priority: optional
-Standards-Version: 4.4.1
-Maintainer: Bartosz Fenski <fenio@debian.org>
+Standards-Version: 4.1.5
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: Bartosz Fenski <fenio@debian.org>
 Uploaders: Dmitry Smirnov <onlyjob@debian.org>
-Build-Depends: debhelper (>= 11~)
-    ,libfuse3-dev
-    ,libglib2.0-dev
+Build-Depends: debhelper (>= 11~), libglib2.0-dev, libfuse-dev, pkg-config
     ,meson
-    ,pkg-config
     ,python3
-    ,python3-docutils
     ,python3-pytest
-# tests:
-    ,fuse3
 Homepage: https://github.com/libfuse/sshfs
 Vcs-Browser: https://salsa.debian.org/debian/sshfs-fuse
 Vcs-Git: https://salsa.debian.org/debian/sshfs-fuse.git
@@ -21,7 +16,7 @@ Vcs-Git: https://salsa.debian.org/debian
 Package: sshfs
 Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}
-        ,fuse3 [linux-any] | fuse4bsd [kfreebsd-any]
+        ,fuse [linux-any] | fuse4bsd [kfreebsd-any]
         ,openssh-client
 Description: filesystem client based on SSH File Transfer Protocol
  sshfs is a filesystem client based on the SSH File Transfer Protocol.
diff -pruN 3.6.0+repack-1/debian/copyright 3.6.0+repack+really2.10-0ubuntu1/debian/copyright
--- 3.6.0+repack-1/debian/copyright	2019-11-16 02:27:57.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/debian/copyright	2018-07-05 15:55:09.000000000 +0000
@@ -21,7 +21,7 @@ License: GPL-2+
 
 Files: debian/*
 Copyright: 2005-2018 Bartosz Fenski <fenio@debian.org>
-           2012-2019 Dmitry Smirnov <onlyjob@member.fsf.org>
+           2012-2018 Dmitry Smirnov <onlyjob@member.fsf.org>
 License: GPL-2+
 
 License: GPL-2
diff -pruN 3.6.0+repack-1/debian/docs 3.6.0+repack+really2.10-0ubuntu1/debian/docs
--- 3.6.0+repack-1/debian/docs	2019-11-16 02:27:57.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/debian/docs	2016-06-09 06:06:06.000000000 +0000
@@ -1,2 +1,3 @@
 AUTHORS
 README*
+FAQ
diff -pruN 3.6.0+repack-1/debian/patches/series 3.6.0+repack+really2.10-0ubuntu1/debian/patches/series
--- 3.6.0+repack-1/debian/patches/series	2019-11-16 02:27:57.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/debian/patches/series	2016-06-13 20:34:59.000000000 +0000
@@ -1 +1 @@
-#sshfs.1.patch
+sshfs.1.patch
diff -pruN 3.6.0+repack-1/debian/source/options 3.6.0+repack+really2.10-0ubuntu1/debian/source/options
--- 3.6.0+repack-1/debian/source/options	1970-01-01 00:00:00.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/debian/source/options	2012-05-05 00:57:49.000000000 +0000
@@ -0,0 +1 @@
+compression = "xz"
diff -pruN 3.6.0+repack-1/FAQ 3.6.0+repack+really2.10-0ubuntu1/FAQ
--- 3.6.0+repack-1/FAQ	1970-01-01 00:00:00.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/FAQ	2017-08-03 16:00:34.000000000 +0000
@@ -0,0 +1,263 @@
+SSHFS FAQ
+=========
+
+1.     I've found a bug and there's no solution in this FAQ, what
+       should I do?
+2.     Advantage of sshfs over NFS and Samba
+3.     Create the device node
+4.     mv fails with "Operation not permitted"
+5.     cvs fails with "cvs [status aborted]: cannot get working
+       directory: No such file or directory" in a sshfs mounted directory
+6.     Changes on the server are not immediately visible in the
+       mounted directory.
+7.     Configuring the ssh connection
+8.     What are the no_readahead and sshfs_sync options for?
+9.    Why does df return strange values on partitions mounted via
+       sshfs?
+10.    How do I specify the remote mount point (since the example
+       defaults to the home directory)
+11.    sshfs hangs after a while
+12.    Following symlinks on the server side
+13.    Making absolute symlinks work
+14.    Mounting as root
+15.    Exporting via NFS
+16.    Automatical mounting using /etc/fstab
+17.    Why does SVN (etc...) fail with permission denied?
+18.    Why does SVN (etc...) fail to rename files?
+19.    Is there some neat way to do it in reverse?
+20.    Might it be reasonable to disallow loops?
+21.    How to mount through an intermediary ssh server, eg:
+       localhost -> A -> B; mount B from localhost
+22.    Alternative Solution
+23.    I seem to have successfully mounted a remote directory, but
+       performing an `ls -l` on the directory above the mount point shows
+       the mount point's attributes as `? ? ? ? ? ?`. Nothing shows up in
+       the directory either. What am I doing wrong?
+
+--------------------------------------------------------------------------
+
+1. I've found a bug and there's no solution in this FAQ, what should I do?
+
+   Please report the bug in the Github issue tracker:
+   https://github.com/libfuse/sshfs/issues
+
+   Also logs with debugging output can be useful for diagnosing the
+   problem. Try running sshfs with the following options:
+     sshfs -odebug,sshfs_debug,loglevel=debug ...
+
+   Doing strace on the application which fails may also sometimes help:
+     strace -f -o /tmp/strace application args ...
+
+   Note that large messages (over 40k) will be rejected from the mailing
+   list. So try to keep the logs as short as possible.
+
+
+2. Advantage of sshfs over NFS and Samba
+
+   Users can mount remote resources they already have ssh access to,
+   without requiring the remote machine to export the resource.
+
+   The remote resource can be mounted when it is needed in a location
+   that is convenient for the user at that time, without needing to rely
+   on a central, root-controlled file system table.
+
+   Automatic mounting, if desired, can be added to a shell script such as
+   .bashrc (provided authentication is done using RSA/DSA keys).
+
+   Resources can be mounted over slow and unreliable (distant)
+   connections.
+
+3. Create the device node
+
+   If you don't use udev, you may get this error message:
+
+   fusermount: failed to open /dev/fuse: No such device or address
+
+   Before loading the fuse kernel module, create the device node
+   manually:
+
+     mknod -m 666 /dev/fuse c 10 229
+
+4. mv fails with "Operation not permitted".
+
+   Use -o workaround=rename (requires sshfs version >= 1.3).
+
+5. cvs fails with "cvs status aborted?: cannot get working directory: No such
+   file or directory" in a sshfs mounted directory
+
+   Use the -oreaddir_ino option. Example:
+     sshfs -oreaddir_ino hostname:remote_dir mount_point
+
+6. Changes on the server are not immediately visible in the mounted directory.
+
+   By default, sshfs caches things for 20 seconds, use -o cache_timeout=N
+   to change the default cache timeout (in seconds) or -o cache=no for
+   disabling the cache.
+
+   You can also control cache timeouts for directory listing etc with
+   -o cache_stat_timeout=N,
+   -o cache_dir_timout=N, and
+   -o cache_link_timout=N.
+
+7. Configuring the ssh connection
+
+   In addition to flags like -C, -p, and -o SSHOPT...=, you may find it
+   easier to edit your /.ssh/config file. You can add an entry with any
+   customization you want, test it with ssh, and finally use it with
+   sshfs. As a bonus, you get a short mnemonic for your configuration.
+
+8. What are the no_readahead and sshfs_sync options for?
+
+   These disable read and write optimizations respectively. They don't
+   really make sense unless you're doing something special.
+
+9. Why does df return strange values on partitions mounted via sshfs?
+
+   Because the SFTP protocol doesn't have a statfs operation this is
+   currently not possible to display proper usage on remote partition.
+
+10. How do I specfy the remote mount point (since the example defaults to the
+    home directory)
+
+    The example shows:
+      sshfs hostname: mountpoint
+
+    To specify a remote mount point use:
+      sshfs hostname:remotemountpoint mountpoint
+
+    This might be obvious to others, but I ended up looking up the
+    interface to sftp to see if I could learn how to specify the remote
+    mount point, then thought about the way that scp specifies the remote
+    directory, and it worked.
+
+11. sshfs hangs after a while
+
+    Mounting works fine, I can use the files in Mountpoint as good as any
+    other files on my system, but after bit of time, changing nothing on
+    the remote files sshfs crashes. This means, I can not cd into the
+    Mountpoint (xterm hangs, nautilus hangs... every program trying to
+    access the Mountpoint gets stuck, and won't return).
+
+    Solution: add
+      ServerAliveInterval 15
+
+    in your .ssh/config (or use -o ServerAliveInterval=15 on the sshfs
+    command line but I did not test that solution). This will force the
+    ssh connection to stay alive even if you have no activity.
+
+12. Following symlinks on the server side
+
+    The -o follow_symlinks option will enable this.
+
+13. Making absolute symlinks work
+
+    Use the -o transform_symlinks option, which will transform absolute
+    symlinks (ones which point somewhere inside the mount) into relative
+    ones.
+
+14. Mounting as root
+
+    Generally it's not possible to use an sshfs mount as a "real"
+    filesystem shared between multiple users. Some of this functionality
+    can be enabled with the -o allow_other and -o default_permissions
+    options, but files will not be created with the correct ownership,
+    etc...
+
+15. Exporting via NFS
+
+    Use the userspace NFS daemon http://sourceforge.net/projects/unfs
+
+16. Automatical mounting using /etc/fstab
+
+    A line in /etc/fstab has the following format:
+      sshfs#USERNAME@REMOTE_HOST:REMOTE_PATH MOUNT_POINT fuse SSHFS_OPTIONS 0 0
+
+    eg.
+      sshfs#guest@guest.login.com:data /mnt/guest fuse \
+        uid=1003,gid=100,umask=0,allow_other 0 0
+
+17. Why does SVN (etc...) fail with permission denied?
+
+    This is a bug that happens when an application creates a read-only
+    file opened for writing (e.g. open("foo", O_WRONLY|O_CREAT, 0444))
+
+    It has been fixed in sshfs version 1.3, but also requires FUSE version
+    >=2.5.X and Linux kernel version >=2.6.15.
+
+18. Why does SVN (etc...) fail to rename files?
+
+    $ svn co svn://anonsvn.kde.org/home/kde/trunk/KDE/kdelibs
+    svn: Can't move 'kdelibs/.svn/tmp/entries' to 'kdelibs/.svn/entries':
+    Operation not permitted
+
+    The reason is that SFTP protocol version 3 (which is implemented by
+    OpenSSH's sftp-server) defines the rename operation slightly
+    differently than POSIX. The difference is that renaming to an existing
+    file or directory will fail instead of atomically replacing the old
+    file.
+
+    The -o workaround=rename option will try to emulate POSIX rename
+    semantics, but it cannot guarantee atomicity. In most of the cases
+    this doesn't matter, and things will work fine with this option.
+
+19. Is there some neat way to do it in reverse?
+
+    You want to mount a USB thumb drive onto a file server that is rather
+    remote.
+
+    Assuming this is difficult because the laptop with the thumb drive is
+    sitting behind NAT, firewalls, etc. then you need to create a
+    port-forward:
+      client$ ssh -R 2222:localhost:22 server
+      server$ sshfs -p 2222 localhost:/media/usb1 myusb1
+
+    (Now, is there is there a smarter way that does not involve port
+    opening login permissions in an undesireable direction?)
+
+20. Might it be reasonable to disallow loops?
+
+    sshfs localhost:/mnt /mnt
+
+    This seems to produce undesirable results. --JoshuaRodman
+
+21. How to mount through an intermediary ssh server, eg: localhost -> A -> B;
+    mount B from localhost
+
+    Start by mounting the folder you need that is on "a" to a folder on
+    "b" then mount the new folder that is on "a" to a folder on localhost.
+
+    IE: (These are NOT real commands, but a sequence of steps.
+    A mounts B:/home/x on /mnt/Bx
+    localhost mounts A:/mnt/Bx on ~/mydir
+
+22. Alternative Solution:
+
+    1) Create a shell script to wrap the tunneling of one ssh command over
+    another,
+      $ cat >Atunnel <<EOF
+      #!/bin/bash
+      ssh -q A ssh -q "$@"
+      EOF
+      $ chmod u+x Atunnel
+
+    N.B. make sure to put this somewhere on your path. 2) sshfs mount as
+    normal but using this script as the ssh command.
+      $ sshfs -o ssh_command='Atunnel' B: ~/mydir
+
+23. I seem to have successfully mounted a remote directory, but performing an
+    `ls -l` on the directory above the mount point shows the mount point's
+    attributes as `? ? ? ? ? ?`. Nothing shows up in the directory either. What
+    am I doing wrong?
+
+    You probably specified a remote path with the tilde (~) in it. This
+    doesn't seem to work. Instead, specify an absolute remote path:
+      sshfs username@remote.host:/home/username/whatever my/mount
+
+    What options do i use to make playing media files (music) over sshfs more
+    efficient?
+
+    MacFUSE doesn't seem to let me move files from one directory to another. It
+    first asks for my local user password (i.e. the password on my Macbook Pro)
+    and then produces the error message "The operation cannot be completed
+    because one or more required items cannot be found. (Error code -120).
+
diff -pruN 3.6.0+repack-1/.github/ISSUE_TEMPLATE/issue-report.md 3.6.0+repack+really2.10-0ubuntu1/.github/ISSUE_TEMPLATE/issue-report.md
--- 3.6.0+repack-1/.github/ISSUE_TEMPLATE/issue-report.md	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/.github/ISSUE_TEMPLATE/issue-report.md	1970-01-01 00:00:00.000000000 +0000
@@ -1,17 +0,0 @@
----
-name: Issue report
-about: Create a report to help us improve
-title: ''
-labels: ''
-assignees: ''
-
----
-
-PLEASE READ BEFORE REPORTING AN ISSUE
-
-SSHFS does not have any active, regular contributors or developers. The current maintainer continues to apply pull requests and tries to make regular releases, but unfortunately has no capacity to do any development beyond addressing high-impact issues. When reporting bugs, please understand that unless you are including a pull request or are reporting a critical issue, you will probably not get a response.
-
-To prevent the issue tracker from being flooded with issues that no-one is intending to work on, and to give more visibilty to critical issues that users should be aware of and that most urgently need attention, I will also close most bug reports once they've been inactive for a while.
-
-Please note that this isn't meant to imply that you haven't found a bug - you most likely have and I'm grateful that you took the time to report it. Unfortunately, SSHFS is a purely volunteer driven project,
-and at the moment there simply aren't any volunteers.
diff -pruN 3.6.0+repack-1/Makefile.am 3.6.0+repack+really2.10-0ubuntu1/Makefile.am
--- 3.6.0+repack-1/Makefile.am	1970-01-01 00:00:00.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/Makefile.am	2017-08-03 16:00:34.000000000 +0000
@@ -0,0 +1,30 @@
+## Process this file with automake to produce Makefile.in
+
+bin_PROGRAMS = sshfs
+
+SUBDIRS = test
+
+sshfs_SOURCES = sshfs.c cache.c cache.h
+if FUSE_OPT_COMPAT
+sshfs_SOURCES += compat/fuse_opt.c compat/fuse_opt.h
+endif
+if DARWIN_COMPAT
+sshfs_SOURCES += compat/darwin_compat.c compat/darwin_compat.h
+endif
+
+sshfs_LDADD = $(SSHFS_LIBS)
+sshfs_CFLAGS = $(SSHFS_CFLAGS)
+sshfs_CPPFLAGS = -D_REENTRANT -DFUSE_USE_VERSION=26 -DLIBDIR=\"$(libdir)\" \
+                 -DIDMAP_DEFAULT="\"$(IDMAP_DEFAULT)\""
+
+EXTRA_DIST = sshfs.1.in meson.build
+CLEANFILES = sshfs.1 sshfs.1.tmp
+
+dist_man_MANS = sshfs.1
+
+sshfs.1: sshfs.1.in
+	$(AM_V_GEN)sed \
+	    -e 's/[@]IDMAP_DEFAULT@/$(IDMAP_DEFAULT)/g' \
+	    -e 's/[@]UNMOUNT_COMMAND@/$(UNMOUNT_COMMAND)/g' \
+	    <$(srcdir)/sshfs.1.in >sshfs.1.tmp || exit 1; \
+	mv sshfs.1.tmp sshfs.1
diff -pruN 3.6.0+repack-1/make_release_tarball.sh 3.6.0+repack+really2.10-0ubuntu1/make_release_tarball.sh
--- 3.6.0+repack-1/make_release_tarball.sh	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/make_release_tarball.sh	1970-01-01 00:00:00.000000000 +0000
@@ -1,30 +0,0 @@
-#!/bin/sh
-#
-# Create tarball from Git tag, removing and adding
-# some files.
-#
-
-set -e
-
-if [ -z "$1" ]; then
-    TAG="$(git tag --list 'sshfs-3*' --sort=-taggerdate | head -1)"
-else
-    TAG="$1"
-fi
-
-echo "Creating release tarball for ${TAG}..."
-
-mkdir "${TAG}"
-git archive --format=tar "${TAG}" | tar -x "--directory=${TAG}"
-find "${TAG}" -name .gitignore -delete
-rm "${TAG}/make_release_tarball.sh" \
-   "${TAG}/.travis.yml" \
-   "${TAG}/test/travis-build.sh" \
-   "${TAG}/test/travis-install.sh"
-tar -cJf "${TAG}.tar.xz" "${TAG}/"
-gpg --armor --detach-sign "${TAG}.tar.xz"
-
-PREV_TAG="$(git tag --list 'sshfs-3*' --sort=-taggerdate --merged "${TAG}^"| head -1)"
-echo "Contributors from ${PREV_TAG} to ${TAG}:"
-git log --pretty="format:%an <%aE>" "${PREV_TAG}..${TAG}" | sort -u
-
diff -pruN 3.6.0+repack-1/meson.build 3.6.0+repack+really2.10-0ubuntu1/meson.build
--- 3.6.0+repack-1/meson.build	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/meson.build	2017-08-03 16:00:34.000000000 +0000
@@ -1,8 +1,8 @@
-project('sshfs', 'c', version: '3.6.0',
-        meson_version: '>= 0.40',
-        default_options: [ 'buildtype=debugoptimized' ])
+project('sshfs', 'c', version: '2.10.0',
+        meson_version: '>= 0.38',
+        default_options: [ 'buildtype=plain' ])
 
-add_global_arguments('-D_REENTRANT', '-DHAVE_CONFIG_H',
+add_global_arguments('-D_REENTRANT', '-DHAVE_CONFIG_H', '-O2', '-g',
                      '-Wall', '-Wextra', '-Wno-sign-compare',
                      '-Wmissing-declarations', '-Wwrite-strings',
                      language: 'c')
@@ -25,8 +25,6 @@ if not cc.compiles(code, args: [ '-O0',
 endif
 
 
-rst2man = find_program('rst2man', 'rst2man.py', required: false)
-  
 cfg = configuration_data()
 
 cfg.set_quoted('PACKAGE_VERSION', meson.project_version())
@@ -41,32 +39,26 @@ else
   cfg.set_quoted('IDMAP_DEFAULT', 'none')
 endif
 
+configure_file(input: 'sshfs.1.in',
+               output: 'sshfs.1',
+               configuration : cfg)
 configure_file(output: 'config.h',
                configuration : cfg)
 
-sshfs_deps = [ dependency('fuse3', version: '>= 3.1.0'),
+sshfs_deps = [ dependency('fuse', version: '>= 2.3'),
                dependency('glib-2.0'),
                dependency('gthread-2.0') ]
 
 executable('sshfs', sshfs_sources,
            include_directories: include_dirs,
            dependencies: sshfs_deps,
-           c_args: ['-DFUSE_USE_VERSION=31'],
+           c_args: ['-DFUSE_USE_VERSION=26'],
            install: true,
            install_dir: get_option('bindir'))
 
-if rst2man.found()
-    custom_target('manpages', input: [ 'sshfs.rst' ], output: [ 'sshfs.1' ],
-                  command: [rst2man, '@INPUT@', '@OUTPUT@'], install: true,
-                  install_dir: join_paths(get_option('mandir'), 'man1'))
-else
-    message('rst2man not found, not building manual page.')
-endif
-
-meson.add_install_script('utils/install_helper.sh',
-                         get_option('sbindir'),
-                         get_option('bindir'))
-
+# This is a little ugly. Is there a better way to tell Meson that the
+# manpage is in the build directory?
+install_man(join_paths(meson.current_build_dir(), 'sshfs.1'))
 
 subdir('test')
 
diff -pruN 3.6.0+repack-1/README.rst 3.6.0+repack+really2.10-0ubuntu1/README.rst
--- 3.6.0+repack-1/README.rst	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/README.rst	2017-08-03 16:00:34.000000000 +0000
@@ -10,20 +10,6 @@ servers support and enable this SFTP acc
 very simple to use - there's nothing to do on the server-side.
 
 
-Development Status
-------------------
-
-SSHFS is shipped by all major Linux distributions and has been in
-production use across a wide range of systems for many years. However,
-at present SSHFS does not have any active, regular contributors, and
-there are a number of known issues (see the bugtracker).  The current
-maintainer continues to apply pull requests and makes regular
-releases, but unfortunately has no capacity to do any development
-beyond addressing high-impact issues. When reporting bugs, please
-understand that unless you are including a pull request or are
-reporting a critical issue, you will probably not get a response.
-
-
 How to use
 ----------
 
@@ -46,7 +32,7 @@ To unmount the filesystem::
 
     fusermount -u mountpoint
 
-On BSD and macOS, to unmount the filesystem::
+On BSD and OS-X, to unmount the filesystem::
 
     umount mountpoint
 
@@ -56,16 +42,15 @@ Installation
 
 First, download the latest SSHFS release from
 https://github.com/libfuse/sshfs/releases. On Linux and BSD, you will
-also need to install libfuse_ 3.1.0 or newer. On macOS, you need
-OSXFUSE_ instead. Finally, you need the Glib_ library with development
-headers (which should be available from your operating system's
-package manager).
+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).
 
 To build and install, we recommend to use Meson_ (version 0.38 or
 newer) and Ninja_.  After extracting the sshfs tarball, create a
 (temporary) build directory and run Meson::
 
-    $ mkdir build; cd build
+    $ md build; cd build
     $ meson ..
 
 Normally, the default build options will work fine. If you
@@ -89,6 +74,47 @@ tests requires the `py.test`_ Python mod
 .. _Ninja: https://ninja-build.org/
 .. _`py.test`: http://www.pytest.org/
 
+Alternate Installation
+----------------------
+
+If you are not able to use Meson and Ninja, please report this to the
+sshfs mailing list. Until the problem is resolved, you may fall back
+to an in-source build using autotools::
+
+    $ ./configure
+    $ make
+    $ sudo make install
+
+Note that support for building with autotools may disappear at some
+point, so if you depend on using autotools for some reason please let
+the sshfs developers know!
+
+
+Caveats
+-------
+
+Rename
+~~~~~~
+
+Some SSH servers do not support atomically overwriting the destination
+when renaming a file. In this case you will get an error when you
+attempt to rename a file and the destination already exists. A
+workaround is to first remove the destination file, and then do the
+rename. SSHFS can do this automatically if you call it with `-o
+workaround=rename`. However, in this case it is still possible that
+someone (or something) recreates the destination file after SSHFS has
+removed it, but before SSHFS had the time to rename the old file. In
+this case, the rename will still fail.
+
+Hardlinks
+~~~~~~~~~
+
+If the SSH server supports the *hardlinks* extension, SSHFS will allow
+you to create hardlinks. However, hardlinks will always appear as
+individual files when seen through an SSHFS mount, i.e. they will
+appear to have different inodes and an *st_nlink* value of 1.
+
+
 Getting Help
 ------------
 
@@ -99,10 +125,8 @@ https://lists.sourceforge.net/lists/list
 Please report any bugs on the GitHub issue tracker at
 https://github.com/libfuse/libfuse/issues.
 
-
 Professional Support
 --------------------
 
-Professional support is offered via `Rath Consulting`_.
-
-.. _`Rath Consulting`: http://www.rath-consulting.biz
+Professional support is available. Please contact Nikolaus Rath
+<Nikolaus@rath.org> for details.
diff -pruN 3.6.0+repack-1/sshfs.1.in 3.6.0+repack+really2.10-0ubuntu1/sshfs.1.in
--- 3.6.0+repack-1/sshfs.1.in	1970-01-01 00:00:00.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/sshfs.1.in	2017-08-03 16:00:34.000000000 +0000
@@ -0,0 +1,284 @@
+.TH SSHFS "1" "April 2008" "SSHFS version 2.0" "User Commands"
+.SH NAME
+SSHFS \- filesystem client based on ssh
+.SH SYNOPSIS
+.SS mounting
+.TP
+\fBsshfs\fP [\fIuser\fP@]\fBhost\fP:[\fIdir\fP] \fBmountpoint\fP [\fIoptions\fP]
+.SS unmounting
+.TP
+\fB@UNMOUNT_COMMAND@ mountpoint\fP
+.SH DESCRIPTION
+SSHFS (Secure SHell FileSystem) is a file system for Linux (and other
+operating systems with a FUSE implementation, such as Mac OS X or FreeBSD)
+capable of operating on files on a remote computer using just a secure
+shell login on the remote computer. On the local computer where the SSHFS
+is mounted, the implementation makes use of the FUSE (Filesystem in
+Userspace) kernel module. The practical effect of this is that the end user
+can seamlessly interact with remote files being securely served over SSH
+just as if they were local files on his/her computer. On the remote
+computer the SFTP subsystem of SSH is used.
+.PP
+If \fIhost\fP is a numeric IPv6 address, it needs to be enclosed in
+square brackets.
+.SH OPTIONS
+.SS "general options:"
+.TP
+\fB\-o\fR opt,[opt...]
+mount options
+.TP
+\fB\-h\fR   \fB\-\-help\fR
+print help
+.TP
+\fB\-V\fR   \fB\-\-version\fR
+print version
+.SS "SSHFS options:"
+.TP
+\fB\-p\fR PORT
+equivalent to '\-o port=PORT'
+.TP
+\fB\-C\fR
+equivalent to '\-o compression=yes'
+.TP
+\fB\-F\fR ssh_configfile
+specifies alternative ssh configuration file
+.TP
+\fB\-1\fR
+equivalent to '\-o ssh_protocol=1'
+.TP
+\fB\-o\fR reconnect
+reconnect to server
+.TP
+\fB\-o\fR delay_connect
+delay connection to server
+.TP
+\fB\-o\fR sshfs_sync
+synchronous writes
+.TP
+\fB\-o\fR no_readahead
+synchronous reads (no speculative readahead)
+.TP
+\fB\-o\fR sync_readdir
+synchronous readdir
+.TP
+\fB\-o\fR sshfs_debug
+print some debugging information
+.TP
+\fB\-o\fR cache=BOOL
+enable caching {yes,no} (default: yes)
+.TP
+\fB\-o\fR cache_timeout=N
+sets timeout for caches in seconds (default: 20)
+.TP
+\fB\-o\fR cache_X_timeout=N
+sets timeout for {stat,dir,link} cache
+.TP
+\fB\-o\fR workaround=LIST
+colon separated list of workarounds
+.RS 8
+.TP
+none
+no workarounds enabled
+.TP
+all
+all workarounds enabled
+.TP
+[no]rename
+fix renaming to existing file (default: off)
+.TP
+[no]nodelaysrv
+set nodelay tcp flag in ssh (default: off)
+.TP
+[no]truncate
+fix truncate for old servers (default: off)
+.TP
+[no]buflimit
+fix buffer fillup bug in server (default: on)
+.RE
+.TP
+\fB\-o\fR idmap=TYPE
+user/group ID mapping (default: @IDMAP_DEFAULT@)
+.RS 8
+.TP
+none
+no translation of the ID space
+.TP
+user
+only translate UID/GID of connecting user
+.TP
+file
+translate UIDs/GIDs based upon the contents of \fBuidfile \fR and
+\fBgidfile\fR
+.RE
+.TP
+\fB\-o\fR uidfile=FILE
+file containing username:uid mappings for \fBidmap=file\fR
+.RE
+.TP
+\fB\-o\fR gidfile=FILE
+file containing groupname:gid mappings for \fBidmap=file\fR
+.RE
+.TP
+\fB\-o\fR nomap=TYPE
+with idmap=file, how to handle missing mappings
+.RS 8
+.TP
+ignore
+don't do any re-mapping
+.TP
+error
+return an error (default)
+.RE
+.TP
+\fB\-o\fR ssh_command=CMD
+execute CMD instead of 'ssh'
+.TP
+\fB\-o\fR ssh_protocol=N
+ssh protocol to use (default: 2)
+.TP
+\fB\-o\fR sftp_server=SERV
+path to sftp server or subsystem (default: sftp)
+.TP
+\fB\-o\fR directport=PORT
+directly connect to PORT bypassing ssh
+.TP
+\fB\-o\fR slave
+communicate over stdin and stdout bypassing network
+.TP
+\fB\-o\fR disable_hardlink
+link(2) will return with errno set to ENOSYS.  Hard links don't currently work
+perfectly on sshfs, and this confuses some programs.  If that happens try
+disabling hard links with this option.
+.TP
+\fB\-o\fR transform_symlinks
+transform absolute symlinks to relative
+.TP
+\fB\-o\fR follow_symlinks
+follow symlinks on the server
+.TP
+\fB\-o\fR no_check_root
+don't check for existence of 'dir' on server
+.TP
+\fB\-o\fR password_stdin
+read password from stdin (only for pam_mount!)
+.TP
+\fB\-o\fR SSHOPT=VAL
+ssh options (see man ssh_config)
+.SS "FUSE options:"
+.TP
+\fB\-d\fR   \fB\-o\fR debug
+enable debug output (implies \fB\-f\fR)
+.TP
+\fB\-f\fR
+foreground operation
+.TP
+\fB\-s\fR
+disable multi\-threaded operation
+.TP
+\fB\-o\fR allow_other
+allow access to other users
+.TP
+\fB\-o\fR allow_root
+allow access to root
+.TP
+\fB\-o\fR nonempty
+allow mounts over non\-empty file/dir
+.HP
+\fB\-o\fR default_permissions
+enable permission checking by kernel
+.TP
+\fB\-o\fR fsname=NAME
+set filesystem name
+.TP
+\fB\-o\fR subtype=NAME
+set filesystem type
+.TP
+\fB\-o\fR large_read
+issue large read requests (2.4 only)
+.TP
+\fB\-o\fR max_read=N
+set maximum size of read requests
+.TP
+\fB\-o\fR hard_remove
+immediate removal (don't hide files)
+.TP
+\fB\-o\fR use_ino
+let filesystem set inode numbers
+.TP
+\fB\-o\fR readdir_ino
+try to fill in d_ino in readdir
+.TP
+\fB\-o\fR direct_io
+use direct I/O
+.TP
+\fB\-o\fR kernel_cache
+cache files in kernel
+.TP
+\fB\-o\fR [no]auto_cache
+enable caching based on modification times
+.TP
+\fB\-o\fR umask=M
+set file permissions (octal)
+.TP
+\fB\-o\fR uid=N
+set file owner
+.TP
+\fB\-o\fR gid=N
+set file group
+.TP
+\fB\-o\fR entry_timeout=T
+cache timeout for names (1.0s)
+.TP
+\fB\-o\fR negative_timeout=T
+cache timeout for deleted names (0.0s)
+.TP
+\fB\-o\fR attr_timeout=T
+cache timeout for attributes (1.0s)
+.TP
+\fB\-o\fR ac_attr_timeout=T
+auto cache timeout for attributes (attr_timeout)
+.TP
+\fB\-o\fR intr
+allow requests to be interrupted
+.TP
+\fB\-o\fR intr_signal=NUM
+signal to send on interrupt (10)
+.TP
+\fB\-o\fR modules=M1[:M2...]
+names of modules to push onto filesystem stack
+.TP
+\fB\-o\fR max_write=N
+set maximum size of write requests
+.TP
+\fB\-o\fR max_readahead=N
+set maximum readahead
+.TP
+\fB\-o\fR async_read
+perform reads asynchronously (default)
+.TP
+\fB\-o\fR sync_read
+perform reads synchronously
+.SS "Module options:"
+.TP
+[subdir]
+.TP
+\fB\-o\fR subdir=DIR
+prepend this directory to all paths (mandatory)
+.TP
+\fB\-o\fR [no]rellinks
+transform absolute symlinks to relative
+.TP
+[iconv]
+.TP
+\fB\-o\fR from_code=CHARSET
+original encoding of file names (default: UTF-8)
+.TP
+\fB\-o\fR to_code=CHARSET
+new encoding of the file names (default: ISO-8859-2)
+.PD
+.SH "AUTHORS"
+.LP
+SSHFS has been written by Miklos Szeredi <miklos@szeredi.hu>.
+.LP
+This man page was written by Bartosz Fenski <fenio@debian.org> for the
+Debian GNU/Linux distribution (but it may be used by others).
diff -pruN 3.6.0+repack-1/sshfs.c 3.6.0+repack+really2.10-0ubuntu1/sshfs.c
--- 3.6.0+repack-1/sshfs.c	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/sshfs.c	2017-08-03 16:00:34.000000000 +0000
@@ -12,7 +12,7 @@
 #include <fuse.h>
 #include <fuse_opt.h>
 #if !defined(__CYGWIN__)
-#  include <fuse_lowlevel.h>
+#include <fuse_lowlevel.h>
 #endif
 #ifdef __APPLE__
 #  include <fuse_darwin.h>
@@ -38,7 +38,7 @@
 #include <sys/socket.h>
 #include <sys/utsname.h>
 #include <sys/mman.h>
-#include <poll.h>
+#include <sys/poll.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <glib.h>
@@ -214,12 +214,9 @@ struct sshfs {
 	struct fuse_args ssh_args;
 	char *workarounds;
 	int rename_workaround;
-	int renamexdev_workaround;
 	int truncate_workaround;
 	int buflimit_workaround;
-	int unrel_append;
 	int fstat_workaround;
-	int createmode_workaround;
 	int transform_symlinks;
 	int follow_symlinks;
 	int no_check_root;
@@ -227,11 +224,6 @@ struct sshfs {
 	int idmap;
 	int nomap;
 	int disable_hardlink;
-	int dir_cache;
-	int show_version;
-	int show_help;
-	int singlethread;
-	char *mountpoint;
 	char *uid_file;
 	char *gid_file;
 	GHashTable *uid_map;
@@ -244,9 +236,7 @@ struct sshfs {
 	int sync_write;
 	int sync_read;
 	int sync_readdir;
-  int direct_io;
 	int debug;
-	int verbose;
 	int foreground;
 	int reconnect;
 	int delay_connect;
@@ -266,8 +256,10 @@ struct sshfs {
 	int server_version;
 	unsigned remote_uid;
 	unsigned local_uid;
+#ifdef __APPLE__
 	unsigned remote_gid;
 	unsigned local_gid;
+#endif
 	int remote_uid_detected;
 	unsigned blksize;
 	char *progname;
@@ -281,6 +273,7 @@ struct sshfs {
 	int ext_statvfs;
 	int ext_hardlink;
 	int ext_fsync;
+	mode_t mnt_mode;
 	struct fuse_operations *op;
 
 	/* statistics */
@@ -300,7 +293,6 @@ static const char *ssh_opts[] = {
 	"AddressFamily",
 	"BatchMode",
 	"BindAddress",
-	"BindInterface",
 	"CertificateFile",
 	"ChallengeResponseAuthentication",
 	"CheckHostIP",
@@ -364,6 +356,9 @@ static const char *ssh_opts[] = {
 enum {
 	KEY_PORT,
 	KEY_COMPRESS,
+	KEY_HELP,
+	KEY_VERSION,
+	KEY_FOREGROUND,
 	KEY_CONFIGFILE,
 };
 
@@ -400,7 +395,6 @@ static struct fuse_opt sshfs_opts[] = {
 	SSHFS_OPT("no_readahead",      sync_read, 1),
 	SSHFS_OPT("sync_readdir",      sync_readdir, 1),
 	SSHFS_OPT("sshfs_debug",       debug, 1),
-	SSHFS_OPT("sshfs_verbose",     verbose, 1),
 	SSHFS_OPT("reconnect",         reconnect, 1),
 	SSHFS_OPT("transform_symlinks", transform_symlinks, 1),
 	SSHFS_OPT("follow_symlinks",   follow_symlinks, 1),
@@ -409,40 +403,17 @@ static struct fuse_opt sshfs_opts[] = {
 	SSHFS_OPT("delay_connect",     delay_connect, 1),
 	SSHFS_OPT("slave",             slave, 1),
 	SSHFS_OPT("disable_hardlink",  disable_hardlink, 1),
-	SSHFS_OPT("dir_cache=yes", dir_cache, 1),
-	SSHFS_OPT("dir_cache=no",  dir_cache, 0),
-	SSHFS_OPT("direct_io",  direct_io, 1),
-
-	SSHFS_OPT("-h",		show_help, 1),
-	SSHFS_OPT("--help",	show_help, 1),
-	SSHFS_OPT("-V",		show_version, 1),
-	SSHFS_OPT("--version",	show_version, 1),
-	SSHFS_OPT("-d",		debug, 1),
-	SSHFS_OPT("debug",	debug, 1),
-	SSHFS_OPT("-v",		verbose, 1),
-	SSHFS_OPT("verbose",	verbose, 1),
-	SSHFS_OPT("-f",		foreground, 1),
-	SSHFS_OPT("-s",		singlethread, 1),
 
 	FUSE_OPT_KEY("-p ",            KEY_PORT),
 	FUSE_OPT_KEY("-C",             KEY_COMPRESS),
+	FUSE_OPT_KEY("-V",             KEY_VERSION),
+	FUSE_OPT_KEY("--version",      KEY_VERSION),
+	FUSE_OPT_KEY("-h",             KEY_HELP),
+	FUSE_OPT_KEY("--help",         KEY_HELP),
+	FUSE_OPT_KEY("debug",          KEY_FOREGROUND),
+	FUSE_OPT_KEY("-d",             KEY_FOREGROUND),
+	FUSE_OPT_KEY("-f",             KEY_FOREGROUND),
 	FUSE_OPT_KEY("-F ",            KEY_CONFIGFILE),
-
-	/* For backwards compatibility */
-	SSHFS_OPT("cache=yes", dir_cache, 1),
-	SSHFS_OPT("cache=no",  dir_cache, 0),
-	
-	FUSE_OPT_KEY("writeback_cache=no", FUSE_OPT_KEY_DISCARD),
-	FUSE_OPT_KEY("unreliable_append", FUSE_OPT_KEY_DISCARD),
-
-	/* These may come in from /etc/fstab - we just ignore them */
-	FUSE_OPT_KEY("auto", FUSE_OPT_KEY_DISCARD),
-	FUSE_OPT_KEY("noauto", FUSE_OPT_KEY_DISCARD),
-	FUSE_OPT_KEY("user", FUSE_OPT_KEY_DISCARD),
-	FUSE_OPT_KEY("nouser", FUSE_OPT_KEY_DISCARD),
-	FUSE_OPT_KEY("users", FUSE_OPT_KEY_DISCARD),
-	FUSE_OPT_KEY("_netdev", FUSE_OPT_KEY_DISCARD),
-
 	FUSE_OPT_END
 };
 
@@ -453,16 +424,12 @@ static struct fuse_opt workaround_opts[]
 	SSHFS_OPT("none",       fstat_workaround, 0),
 	SSHFS_OPT("rename",     rename_workaround, 1),
 	SSHFS_OPT("norename",   rename_workaround, 0),
-	SSHFS_OPT("renamexdev",   renamexdev_workaround, 1),
-	SSHFS_OPT("norenamexdev", renamexdev_workaround, 0),
 	SSHFS_OPT("truncate",   truncate_workaround, 1),
 	SSHFS_OPT("notruncate", truncate_workaround, 0),
 	SSHFS_OPT("buflimit",   buflimit_workaround, 1),
 	SSHFS_OPT("nobuflimit", buflimit_workaround, 0),
 	SSHFS_OPT("fstat",      fstat_workaround, 1),
 	SSHFS_OPT("nofstat",    fstat_workaround, 0),
-	SSHFS_OPT("createmode",   createmode_workaround, 1),
-	SSHFS_OPT("nocreatemode", createmode_workaround, 0),
 	FUSE_OPT_END
 };
 
@@ -793,12 +760,17 @@ static int buf_get_attrs(struct buffer *
 		}
 	}
 
+#ifdef __APPLE__
 	if (sshfs.remote_uid_detected) {
 		if (uid == sshfs.remote_uid)
 			uid = sshfs.local_uid;
 		if (gid == sshfs.remote_gid)
 			gid = sshfs.local_gid;
 	}
+#else /* !__APPLE__ */
+	if (sshfs.remote_uid_detected && uid == sshfs.remote_uid)
+		uid = sshfs.local_uid;
+#endif /* __APPLE__ */
 	if (sshfs.idmap == IDMAP_FILE && sshfs.uid_map)
 		if (translate_id(&uid, sshfs.uid_map) == -1)
 			return -EPERM;
@@ -864,8 +836,8 @@ static int buf_get_statvfs(struct buffer
 	return 0;
 }
 
-static int buf_get_entries(struct buffer *buf, void *dbuf,
-                           fuse_fill_dir_t filler)
+static int buf_get_entries(struct buffer *buf, fuse_cache_dirh_t h,
+                           fuse_cache_dirfil_t filler)
 {
 	uint32_t count;
 	unsigned i;
@@ -888,7 +860,7 @@ static int buf_get_entries(struct buffer
 				    S_ISLNK(stbuf.st_mode)) {
 					stbuf.st_mode = 0;
 				}
-				filler(dbuf, name, &stbuf, 0, 0);
+				filler(h, name, &stbuf);
 			}
 		}
 		free(name);
@@ -1043,7 +1015,7 @@ static int start_ssh(void)
 			perror("failed to redirect input/output");
 			_exit(1);
 		}
-		if (!sshfs.verbose && !sshfs.foreground && devnull != -1)
+		if (!sshfs.foreground && devnull != -1)
 			dup2(devnull, 2);
 
 		close(devnull);
@@ -1122,14 +1094,11 @@ static int connect_to(char *host, char *
 	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
 	if (sock == -1) {
 		perror("failed to create socket");
-		freeaddrinfo(ai);
 		return -1;
 	}
 	err = connect(sock, ai->ai_addr, ai->ai_addrlen);
 	if (err == -1) {
 		perror("failed to connect");
-		freeaddrinfo(ai);
-		close(sock);
 		return -1;
 	}
 	opt = 1;
@@ -1298,10 +1267,9 @@ static void chunk_put_locked(struct read
 	pthread_mutex_unlock(&sshfs.lock);
 }
 
-static int clean_req(void *key_, struct request *req, gpointer user_data_)
+static int clean_req(void *key_, struct request *req)
 {
 	(void) key_;
-	(void) user_data_;
 
 	req->error = -EIO;
 	if (req->want_reply)
@@ -1603,8 +1571,10 @@ static void sftp_detect_uid()
 
 	sshfs.remote_uid = stbuf.st_uid;
 	sshfs.local_uid = getuid();
+#ifdef __APPLE__
 	sshfs.remote_gid = stbuf.st_gid;
 	sshfs.local_gid = getgid();
+#endif
 	sshfs.remote_uid_detected = 1;
 	DEBUG("remote_uid = %i\n", sshfs.remote_uid);
 
@@ -1665,11 +1635,16 @@ static int sftp_check_root(const char *b
 	if (!(flags & SSH_FILEXFER_ATTR_PERMISSIONS))
 		goto out;
 
-	if (!S_ISDIR(stbuf.st_mode)) {
+	if (S_ISDIR(sshfs.mnt_mode) && !S_ISDIR(stbuf.st_mode)) {
 		fprintf(stderr, "%s:%s: Not a directory\n", sshfs.host,
 			remote_dir);
 		goto out;
 	}
+	if ((sshfs.mnt_mode ^ stbuf.st_mode) & S_IFMT) {
+		fprintf(stderr, "%s:%s: type of file differs from mountpoint\n",
+			sshfs.host, remote_dir);
+		goto out;
+	}
 
 	err = 0;
 
@@ -1737,25 +1712,21 @@ static int start_processing_thread(void)
 	return 0;
 }
 
-static void *sshfs_init(struct fuse_conn_info *conn,
-                        struct fuse_config *cfg)
+#if FUSE_VERSION >= 26
+static void *sshfs_init(struct fuse_conn_info *conn)
+#else
+static void *sshfs_init(void)
+#endif
 {
+#if FUSE_VERSION >= 26
 	/* Readahead should be done by kernel or sshfs but not both */
-	if (conn->capable & FUSE_CAP_ASYNC_READ)
+	if (conn->async_read)
 		sshfs.sync_read = 1;
-
-	// These workarounds require the "path" argument.
-        cfg->nullpath_ok = !(sshfs.truncate_workaround || sshfs.fstat_workaround);
-
-        // Lookup of . and .. is supported
-        conn->capable |= FUSE_CAP_EXPORT_SUPPORT;
+#endif
 
 	if (!sshfs.delay_connect)
 		start_processing_thread();
 
-	// SFTP only supports 1-second time resolution
-	conn->time_gran = 1000000000;
-	
 	return NULL;
 }
 
@@ -1915,13 +1886,33 @@ static int sftp_request(uint8_t type, co
 	return sftp_request_iov(type, &iov, 1, expect_type, outbuf);
 }
 
+static int sshfs_getattr(const char *path, struct stat *stbuf)
+{
+	int err;
+	struct buffer buf;
+	struct buffer outbuf;
+	buf_init(&buf, 0);
+	buf_add_path(&buf, path);
+	err = sftp_request(sshfs.follow_symlinks ? SSH_FXP_STAT : SSH_FXP_LSTAT,
+			   &buf, SSH_FXP_ATTRS, &outbuf);
+	if (!err) {
+		err = buf_get_attrs(&outbuf, stbuf, NULL);
+#ifdef __APPLE__
+		stbuf->st_blksize = 0;
+#endif
+		buf_free(&outbuf);
+	}
+	buf_free(&buf);
+	return err;
+}
+
 static int sshfs_access(const char *path, int mask)
 {
 	struct stat stbuf;
 	int err = 0;
 
 	if (mask & X_OK) {
-		err = sshfs.op->getattr(path, &stbuf, NULL);
+		err = sshfs.op->getattr(path, &stbuf);
 		if (!err) {
 			if (S_ISREG(stbuf.st_mode) &&
 			    !(stbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
@@ -2047,8 +2038,8 @@ static int sshfs_req_pending(struct requ
 		return 0;
 }
 
-static int sftp_readdir_async(struct buffer *handle, void *buf, off_t offset,
-			     fuse_fill_dir_t filler)
+static int sftp_readdir_async(struct buffer *handle, fuse_cache_dirh_t h,
+			      fuse_cache_dirfil_t filler)
 {
 	int err = 0;
 	int outstanding = 0;
@@ -2057,7 +2048,6 @@ static int sftp_readdir_async(struct buf
 
 	int done = 0;
 
-	assert(offset == 0);
 	while (!done || outstanding) {
 		struct request *req;
 		struct buffer name;
@@ -2108,7 +2098,7 @@ static int sftp_readdir_async(struct buf
 				done = 1;
 			}
 			if (!done) {
-				err = buf_get_entries(&name, buf, filler);
+				err = buf_get_entries(&name, h, filler);
 				buf_free(&name);
 
 				/* increase number of outstanding requests */
@@ -2125,16 +2115,15 @@ static int sftp_readdir_async(struct buf
 	return err;
 }
 
-static int sftp_readdir_sync(struct buffer *handle, void *buf, off_t offset,
-			     fuse_fill_dir_t filler)
+static int sftp_readdir_sync(struct buffer *handle, fuse_cache_dirh_t h,
+			     fuse_cache_dirfil_t filler)
 {
 	int err;
-	assert(offset == 0);
 	do {
 		struct buffer name;
 		err = sftp_request(SSH_FXP_READDIR, handle, SSH_FXP_NAME, &name);
 		if (!err) {
-			err = buf_get_entries(&name, buf, filler);
+			err = buf_get_entries(&name, h, filler);
 			buf_free(&name);
 		}
 	} while (!err);
@@ -2144,60 +2133,33 @@ static int sftp_readdir_sync(struct buff
 	return err;
 }
 
-static int sshfs_opendir(const char *path, struct fuse_file_info *fi)
+static int sshfs_getdir(const char *path, fuse_cache_dirh_t h,
+                        fuse_cache_dirfil_t filler)
 {
 	int err;
 	struct buffer buf;
-	struct buffer *handle;
-
-	handle = malloc(sizeof(struct buffer));
-	if(handle == NULL)
-		return -ENOMEM;
-
+	struct buffer handle;
 	buf_init(&buf, 0);
 	buf_add_path(&buf, path);
-	err = sftp_request(SSH_FXP_OPENDIR, &buf, SSH_FXP_HANDLE, handle);
+	err = sftp_request(SSH_FXP_OPENDIR, &buf, SSH_FXP_HANDLE, &handle);
 	if (!err) {
-		buf_finish(handle);
-		fi->fh = (unsigned long) handle;
-	} else
-		free(handle);
-	buf_free(&buf);
-	return err;
-}
-
-static int sshfs_readdir(const char *path, void *dbuf, fuse_fill_dir_t filler,
-			 off_t offset, struct fuse_file_info *fi,
-			 enum fuse_readdir_flags flags)
-{
-	(void) path; (void) flags;
-	int err;
-	struct buffer *handle;
-
-	handle = (struct buffer*) fi->fh;
-
-	if (sshfs.sync_readdir)
-		err = sftp_readdir_sync(handle, dbuf, offset, filler);
-	else
-		err = sftp_readdir_async(handle, dbuf, offset, filler);
-
-	return err;
-}
+		int err2;
+		buf_finish(&handle);
 
-static int sshfs_releasedir(const char *path, struct fuse_file_info *fi)
-{
-	(void) path;
-	int err;
-	struct buffer *handle;
+		if (sshfs.sync_readdir)
+			err = sftp_readdir_sync(&handle, h, filler);
+		else
+			err = sftp_readdir_async(&handle, h, filler);
 
-	handle = (struct buffer*) fi->fh;
-	err = sftp_request(SSH_FXP_CLOSE, handle, 0, NULL);
-	buf_free(handle);
-	free(handle);
+		err2 = sftp_request(SSH_FXP_CLOSE, &handle, 0, NULL);
+		if (!err)
+			err = err2;
+		buf_free(&handle);
+	}
+	buf_free(&buf);
 	return err;
 }
 
-
 static int sshfs_mkdir(const char *path, mode_t mode)
 {
 	int err;
@@ -2313,13 +2275,9 @@ static void random_string(char *str, int
 	*str = '\0';
 }
 
-static int sshfs_rename(const char *from, const char *to, unsigned int flags)
+static int sshfs_rename(const char *from, const char *to)
 {
 	int err;
-
-	if(flags != 0)
-		return -EINVAL;
-	
 	if (sshfs.ext_posix_rename)
 		err = sshfs_ext_posix_rename(from, to);
 	else
@@ -2341,8 +2299,6 @@ static int sshfs_rename(const char *from
 			}
 		}
 	}
-	if (err == -EPERM && sshfs.renamexdev_workaround)
-		err = -EXDEV;
 	return err;
 }
 
@@ -2365,72 +2321,36 @@ static int sshfs_link(const char *from,
 	return err;
 }
 
-static inline int sshfs_file_is_conn(struct sshfs_file *sf)
+static int sshfs_chmod(const char *path, mode_t mode)
 {
-	int ret;
-
-	pthread_mutex_lock(&sshfs.lock);
-	ret = (sf->connver == sshfs.connver);
-	pthread_mutex_unlock(&sshfs.lock);
-
-	return ret;
-}
-
-static inline struct sshfs_file *get_sshfs_file(struct fuse_file_info *fi)
-{
-	return (struct sshfs_file *) (uintptr_t) fi->fh;
-}
-
-static int sshfs_chmod(const char *path, mode_t mode,
-                       struct fuse_file_info *fi)
-{
-	(void) fi;
 	int err;
 	struct buffer buf;
-	struct sshfs_file *sf = NULL;
-
-	if (fi != NULL) {
-		sf = get_sshfs_file(fi);
-		if (!sshfs_file_is_conn(sf))
-			return -EIO;
-	}
-
 	buf_init(&buf, 0);
-	if (sf == NULL)
-		buf_add_path(&buf, path);
-	else 
-		buf_add_buf(&buf, &sf->handle);
-	
+	buf_add_path(&buf, path);
 	buf_add_uint32(&buf, SSH_FILEXFER_ATTR_PERMISSIONS);
 	buf_add_uint32(&buf, mode);
-	
 	/* FIXME: really needs LSETSTAT extension (debian Bug#640038) */
-	err = sftp_request(sf == NULL ? SSH_FXP_SETSTAT : SSH_FXP_FSETSTAT,
-			   &buf, SSH_FXP_STATUS, NULL);
+	err = sftp_request(SSH_FXP_SETSTAT, &buf, SSH_FXP_STATUS, NULL);
 	buf_free(&buf);
 	return err;
 }
 
-static int sshfs_chown(const char *path, uid_t uid, gid_t gid,
-                       struct fuse_file_info *fi)
+static int sshfs_chown(const char *path, uid_t uid, gid_t gid)
 {
-	(void) fi;
 	int err;
 	struct buffer buf;
-	struct sshfs_file *sf = NULL;
 
-	if (fi != NULL) {
-		sf = get_sshfs_file(fi);
-		if (!sshfs_file_is_conn(sf))
-			return -EIO;
-	}
-	
+#ifdef __APPLE__
 	if (sshfs.remote_uid_detected) {
 		if (uid == sshfs.local_uid)
 			uid = sshfs.remote_uid;
 		if (gid == sshfs.local_gid)
 			gid = sshfs.remote_gid;
 	}
+#else /* !__APPLE__ */
+	if (sshfs.remote_uid_detected && uid == sshfs.local_uid)
+		uid = sshfs.remote_uid;
+#endif /* __APPLE__ */
 	if (sshfs.idmap == IDMAP_FILE && sshfs.r_uid_map)
 		if(translate_id(&uid, sshfs.r_uid_map) == -1)
 			return -EPERM;
@@ -2439,16 +2359,11 @@ static int sshfs_chown(const char *path,
 			return -EPERM;
 
 	buf_init(&buf, 0);
-	if (sf == NULL)
-		buf_add_path(&buf, path);
-	else 
-		buf_add_buf(&buf, &sf->handle);
+	buf_add_path(&buf, path);
 	buf_add_uint32(&buf, SSH_FILEXFER_ATTR_UIDGID);
 	buf_add_uint32(&buf, uid);
 	buf_add_uint32(&buf, gid);
-
-	err = sftp_request(sf == NULL ? SSH_FXP_SETSTAT : SSH_FXP_FSETSTAT,
-			   &buf, SSH_FXP_STATUS, NULL);
+	err = sftp_request(SSH_FXP_SETSTAT, &buf, SSH_FXP_STATUS, NULL);
 	buf_free(&buf);
 	return err;
 }
@@ -2463,43 +2378,49 @@ static void sshfs_inc_modifver(void)
 	pthread_mutex_unlock(&sshfs.lock);
 }
 
-static int sshfs_utimens(const char *path, const struct timespec tv[2],
-			 struct fuse_file_info *fi)
+static int sshfs_truncate(const char *path, off_t size)
 {
-	(void) fi;
 	int err;
 	struct buffer buf;
-	struct sshfs_file *sf = NULL;
-	time_t asec = tv[0].tv_sec, msec = tv[1].tv_sec;
 
-	struct timeval now;
-	gettimeofday(&now, NULL);
-	if (asec == 0)
-		asec = now.tv_sec;
-	if (msec == 0)
-		msec = now.tv_sec;
-
-	if (fi != NULL) {
-		sf = get_sshfs_file(fi);
-		if (!sshfs_file_is_conn(sf))
-			return -EIO;
-	}
+	sshfs_inc_modifver();
+	if (size == 0 || sshfs.truncate_workaround)
+		return sshfs_truncate_workaround(path, size, NULL);
 
 	buf_init(&buf, 0);
-	if (sf == NULL)
-		buf_add_path(&buf, path);
-	else 
-		buf_add_buf(&buf, &sf->handle);
-	buf_add_uint32(&buf, SSH_FILEXFER_ATTR_ACMODTIME);
-	buf_add_uint32(&buf, asec);
-	buf_add_uint32(&buf, msec);
+	buf_add_path(&buf, path);
+	buf_add_uint32(&buf, SSH_FILEXFER_ATTR_SIZE);
+	buf_add_uint64(&buf, size);
+	err = sftp_request(SSH_FXP_SETSTAT, &buf, SSH_FXP_STATUS, NULL);
+	buf_free(&buf);
+	return err;
+}
 
-	err = sftp_request(sf == NULL ? SSH_FXP_SETSTAT : SSH_FXP_FSETSTAT,
-			   &buf, SSH_FXP_STATUS, NULL);
+static int sshfs_utime(const char *path, struct utimbuf *ubuf)
+{
+	int err;
+	struct buffer buf;
+	buf_init(&buf, 0);
+	buf_add_path(&buf, path);
+	buf_add_uint32(&buf, SSH_FILEXFER_ATTR_ACMODTIME);
+	buf_add_uint32(&buf, ubuf->actime);
+	buf_add_uint32(&buf, ubuf->modtime);
+	err = sftp_request(SSH_FXP_SETSTAT, &buf, SSH_FXP_STATUS, NULL);
 	buf_free(&buf);
 	return err;
 }
 
+static inline int sshfs_file_is_conn(struct sshfs_file *sf)
+{
+	int ret;
+
+	pthread_mutex_lock(&sshfs.lock);
+	ret = (sf->connver == sshfs.connver);
+	pthread_mutex_unlock(&sshfs.lock);
+
+	return ret;
+}
+
 static int sshfs_open_common(const char *path, mode_t mode,
                              struct fuse_file_info *fi)
 {
@@ -2513,13 +2434,7 @@ static int sshfs_open_common(const char
 	uint32_t pflags = 0;
 	struct iovec iov;
 	uint8_t type;
-	uint64_t wrctr = 0;
-
-	if (sshfs.dir_cache)
-		wrctr = cache_get_write_ctr();
-
-  if (sshfs.direct_io)
-    fi->direct_io = 1;
+	uint64_t wrctr = cache_get_write_ctr();
 
 	if ((fi->flags & O_ACCMODE) == O_RDONLY)
 		pflags = SSH_FXF_READ;
@@ -2539,9 +2454,6 @@ static int sshfs_open_common(const char
 	if (fi->flags & O_TRUNC)
 		pflags |= SSH_FXF_TRUNC;
 
-	if (fi->flags & O_APPEND)
-		pflags |= SSH_FXF_APPEND;
-	
 	sf = g_new0(struct sshfs_file, 1);
 	list_init(&sf->write_reqs);
 	pthread_cond_init(&sf->write_finished, NULL);
@@ -2579,13 +2491,11 @@ static int sshfs_open_common(const char
 	}
 
 	if (!err) {
-		if (sshfs.dir_cache)
-			cache_add_attr(path, &stbuf, wrctr);
+		cache_add_attr(path, &stbuf, wrctr);
 		buf_finish(&sf->handle);
 		fi->fh = (unsigned long) sf;
 	} else {
-		if (sshfs.dir_cache)
-			cache_invalidate(path);
+		cache_invalidate(path);
 		g_free(sf);
 	}
 	buf_free(&buf);
@@ -2597,6 +2507,11 @@ static int sshfs_open(const char *path,
 	return sshfs_open_common(path, 0, fi);
 }
 
+static inline struct sshfs_file *get_sshfs_file(struct fuse_file_info *fi)
+{
+	return (struct sshfs_file *) (uintptr_t) fi->fh;
+}
+
 static int sshfs_flush(const char *path, struct fuse_file_info *fi)
 {
 	int err;
@@ -2639,14 +2554,16 @@ static int sshfs_fsync(const char *path,
 	if (!sshfs.ext_fsync)
 		return err;
 
-	struct buffer buf;
-	struct sshfs_file *sf = get_sshfs_file(fi);
-	buf_init(&buf, 0);
-	buf_add_string(&buf, SFTP_EXT_FSYNC);
-	buf_add_buf(&buf, &sf->handle);
-	err = sftp_request(SSH_FXP_EXTENDED, &buf, SSH_FXP_STATUS, NULL);
-	buf_free(&buf);
-	return err;
+	{
+		struct buffer buf;
+		struct sshfs_file *sf = get_sshfs_file(fi);
+		buf_init(&buf, 0);
+		buf_add_string(&buf, SFTP_EXT_FSYNC);
+		buf_add_buf(&buf, &sf->handle);
+		err = sftp_request(SSH_FXP_EXTENDED, &buf, SSH_FXP_STATUS, NULL);
+		buf_free(&buf);
+		return err;
+	}
 }
 
 static void sshfs_file_put(struct sshfs_file *sf)
@@ -3090,6 +3007,7 @@ static int sshfs_ext_statvfs(const char
 }
 
 
+#if FUSE_VERSION >= 25
 static int sshfs_statfs(const char *path, struct statvfs *buf)
 {
 	if (sshfs.ext_statvfs)
@@ -3107,74 +3025,88 @@ static int sshfs_statfs(const char *path
 	buf->f_files = buf->f_ffree = 1000000000;
 	return 0;
 }
+#else
+static int sshfs_statfs(const char *path, struct statfs *buf)
+{
+	if (sshfs.ext_statvfs) {
+		int err;
+		struct statvfs vbuf;
+
+		err = sshfs_ext_statvfs(path, &vbuf);
+		if (!err) {
+			buf->f_bsize = vbuf.f_bsize;
+			buf->f_blocks = vbuf.f_blocks;
+			buf->f_bfree = vbuf.f_bfree;
+			buf->f_bavail = vbuf.f_bavail;
+			buf->f_files = vbuf.f_files;
+			buf->f_ffree = vbuf.f_ffree;
+			buf->f_namelen = vbuf.f_namemax;
+		}
+		return err;
+	}
+
+	buf->f_namelen = 255;
+	buf->f_bsize = sshfs.blksize;
+	buf->f_blocks = buf->f_bfree = buf->f_bavail =
+		1000ULL * 1024 * 1024 * 1024 / buf->f_bsize;
+	buf->f_files = buf->f_ffree = 1000000000;
+	return 0;
+}
+#endif
 
+#if FUSE_VERSION >= 25
 static int sshfs_create(const char *path, mode_t mode,
                         struct fuse_file_info *fi)
 {
-	if (sshfs.createmode_workaround)
-		mode = 0;
-
 	return sshfs_open_common(path, mode, fi);
 }
 
-static int sshfs_truncate(const char *path, off_t size,
-			  struct fuse_file_info *fi)
+static int sshfs_ftruncate(const char *path, off_t size,
+                           struct fuse_file_info *fi)
 {
 	int err;
 	struct buffer buf;
-	struct sshfs_file *sf = NULL;
+	struct sshfs_file *sf = get_sshfs_file(fi);
+
+	(void) path;
+
+	if (!sshfs_file_is_conn(sf))
+		return -EIO;
 
-	if (fi != NULL) {
-		sf = get_sshfs_file(fi);
-		if (!sshfs_file_is_conn(sf))
-			return -EIO;
-	}
-	
 	sshfs_inc_modifver();
 	if (sshfs.truncate_workaround)
 		return sshfs_truncate_workaround(path, size, fi);
-	
-	buf_init(&buf, 0);
-
-	if (sf != NULL)
-		buf_add_buf(&buf, &sf->handle);
-	else
-		buf_add_path(&buf, path);
 
+	buf_init(&buf, 0);
+	buf_add_buf(&buf, &sf->handle);
 	buf_add_uint32(&buf, SSH_FILEXFER_ATTR_SIZE);
 	buf_add_uint64(&buf, size);
-	err = sftp_request(sf == NULL ? SSH_FXP_SETSTAT : SSH_FXP_FSETSTAT,
-			   &buf, SSH_FXP_STATUS, NULL);
+	err = sftp_request(SSH_FXP_FSETSTAT, &buf, SSH_FXP_STATUS, NULL);
 	buf_free(&buf);
 
 	return err;
 }
+#endif
 
-static int sshfs_getattr(const char *path, struct stat *stbuf,
-			 struct fuse_file_info *fi)
+static int sshfs_fgetattr(const char *path, struct stat *stbuf,
+			  struct fuse_file_info *fi)
 {
 	int err;
 	struct buffer buf;
 	struct buffer outbuf;
-	struct sshfs_file *sf = NULL;
+	struct sshfs_file *sf = get_sshfs_file(fi);
 
-	if (fi != NULL && !sshfs.fstat_workaround) {
-		sf = get_sshfs_file(fi);
-		if (!sshfs_file_is_conn(sf))
-			return -EIO;
-	}
-	
+	(void) path;
+
+	if (!sshfs_file_is_conn(sf))
+		return -EIO;
+
+	if (sshfs.fstat_workaround)
+		return sshfs_getattr(path, stbuf);
 
 	buf_init(&buf, 0);
-	if(sf == NULL) {
-		buf_add_path(&buf, path);
-		err = sftp_request(sshfs.follow_symlinks ? SSH_FXP_STAT : SSH_FXP_LSTAT,
-				   &buf, SSH_FXP_ATTRS, &outbuf);
-	}
-	else {
-		buf_add_buf(&buf, &sf->handle);
-		err = sftp_request(SSH_FXP_FSTAT, &buf, SSH_FXP_ATTRS, &outbuf);
-	}		
+	buf_add_buf(&buf, &sf->handle);
+	err = sftp_request(SSH_FXP_FSTAT, &buf, SSH_FXP_ATTRS, &outbuf);
 	if (!err) {
 		err = buf_get_attrs(&outbuf, stbuf, NULL);
 #ifdef __APPLE__
@@ -3293,7 +3225,10 @@ static int sshfs_truncate_workaround(con
 	else {
 		struct stat stbuf;
 		int err;
-		err = sshfs_getattr(path, &stbuf, fi);
+		if (fi)
+			err = sshfs_fgetattr(path, &stbuf, fi);
+		else
+			err = sshfs_getattr(path, &stbuf);
 		if (err)
 			return err;
 		if (stbuf.st_size == size)
@@ -3320,13 +3255,11 @@ static int processing_init(void)
 	return 0;
 }
 
-static struct fuse_operations sshfs_oper = {
+static struct fuse_cache_operations sshfs_oper = {
+	.oper = {
 		.init       = sshfs_init,
 		.getattr    = sshfs_getattr,
 		.access     = sshfs_access,
-		.opendir    = sshfs_opendir,
-		.readdir    = sshfs_readdir,
-		.releasedir = sshfs_releasedir,
 		.readlink   = sshfs_readlink,
 		.mknod      = sshfs_mknod,
 		.mkdir      = sshfs_mkdir,
@@ -3338,7 +3271,7 @@ static struct fuse_operations sshfs_oper
 		.chmod      = sshfs_chmod,
 		.chown      = sshfs_chown,
 		.truncate   = sshfs_truncate,
-		.utimens    = sshfs_utimens,
+		.utime      = sshfs_utime,
 		.open       = sshfs_open,
 		.flush      = sshfs_flush,
 		.fsync      = sshfs_fsync,
@@ -3346,7 +3279,17 @@ static struct fuse_operations sshfs_oper
 		.read       = sshfs_read,
 		.write      = sshfs_write,
 		.statfs     = sshfs_statfs,
+#if FUSE_VERSION >= 25
 		.create     = sshfs_create,
+		.ftruncate  = sshfs_ftruncate,
+		.fgetattr   = sshfs_fgetattr,
+#endif
+#if FUSE_VERSION >= 29
+		.flag_nullpath_ok = 1,
+		.flag_nopath = 1,
+#endif
+	},
+	.cache_getdir = sshfs_getdir,
 };
 
 static void usage(const char *progname)
@@ -3354,43 +3297,38 @@ static void usage(const char *progname)
 	printf(
 "usage: %s [user@]host:[dir] mountpoint [options]\n"
 "\n"
+"general options:\n"
+"    -o opt,[opt...]        mount options\n"
 "    -h   --help            print help\n"
 "    -V   --version         print version\n"
-"    -f                     foreground operation\n"
-"    -s                     disable multi-threaded operation\n"
+"\n"
+"SSHFS options:\n"
 "    -p PORT                equivalent to '-o port=PORT'\n"
 "    -C                     equivalent to '-o compression=yes'\n"
 "    -F ssh_configfile      specifies alternative ssh configuration file\n"
 "    -1                     equivalent to '-o ssh_protocol=1'\n"
-"    -o opt,[opt...]        mount options\n"
 "    -o reconnect           reconnect to server\n"
 "    -o delay_connect       delay connection to server\n"
 "    -o sshfs_sync          synchronous writes\n"
 "    -o no_readahead        synchronous reads (no speculative readahead)\n"
 "    -o sync_readdir        synchronous readdir\n"
-"    -d, --debug            print some debugging information (implies -f)\n"
-"    -v, --verbose          print ssh replies and messages\n"
-"    -o dir_cache=BOOL      enable caching of directory contents (names,\n"
-"                           attributes, symlink targets) {yes,no} (default: yes)\n"
-"    -o dcache_max_size=N   sets the maximum size of the directory cache (default: 10000)\n"
-"    -o dcache_timeout=N    sets timeout for directory cache in seconds (default: 20)\n"
-"    -o dcache_{stat,link,dir}_timeout=N\n"
-"                           sets separate timeout for {attributes, symlinks, names}\n"
-"    -o dcache_clean_interval=N\n"
+"    -o sshfs_debug         print some debugging information\n"
+"    -o cache=BOOL          enable caching {yes,no} (default: yes)\n"
+"    -o cache_max_size=N    sets the maximum size of the cache (default: 10000)\n"
+"    -o cache_timeout=N     sets timeout for caches in seconds (default: 20)\n"
+"    -o cache_X_timeout=N   sets timeout for {stat,dir,link} cache\n"
+"    -o cache_clean_interval=N\n"
 "                           sets the interval for automatic cleaning of the\n"
 "                           cache (default: 60)\n"
-"    -o dcache_min_clean_interval=N\n"
+"    -o cache_min_clean_interval=N\n"
 "                           sets the interval for forced cleaning of the\n"
 "                           cache if full (default: 5)\n"
-"    -o direct_io           enable direct i/o\n"
 "    -o workaround=LIST     colon separated list of workarounds\n"
 "             none             no workarounds enabled\n"
 "             [no]rename       fix renaming to existing file (default: off)\n"
-"             [no]renamexdev   fix moving across filesystems (default: off)\n"
 "             [no]truncate     fix truncate for old servers (default: off)\n"
 "             [no]buflimit     fix buffer fillup bug in server (default: on)\n"
-"             [no]fstat        always use stat() instead of fstat() (default: off)\n"
-"             [no]createmode   always pass mode 0 to create (default: off)\n"
+"             [no]fstat        fix fstat for old servers (default: off)\n"
 "    -o idmap=TYPE          user/group ID mapping (default: " IDMAP_DEFAULT ")\n"
 "             none             no translation of the ID space\n"
 "             user             only translate UID/GID of connecting user\n"
@@ -3411,9 +3349,7 @@ static void usage(const char *progname)
 "    -o no_check_root       don't check for existence of 'dir' on server\n"
 "    -o password_stdin      read password from stdin (only for pam_mount!)\n"
 "    -o SSHOPT=VAL          ssh options (see man ssh_config)\n"
-"\n"
-"FUSE Options:\n",
-progname);
+"\n", progname);
 }
 
 static int is_ssh_opt(const char *arg)
@@ -3431,11 +3367,21 @@ static int is_ssh_opt(const char *arg)
 	return 0;
 }
 
+static int sshfs_fuse_main(struct fuse_args *args)
+{
+	sshfs.op = cache_init(&sshfs_oper);
+#if FUSE_VERSION >= 26
+	return fuse_main(args->argc, args->argv, sshfs.op, NULL);
+#else
+	return fuse_main(args->argc, args->argv, sshfs.op);
+#endif
+}
+
 static int sshfs_opt_proc(void *data, const char *arg, int key,
                           struct fuse_args *outargs)
 {
-	(void) outargs; (void) data;
 	char *tmp;
+	(void) data;
 
 	switch (key) {
 	case FUSE_OPT_KEY_OPT:
@@ -3445,7 +3391,6 @@ static int sshfs_opt_proc(void *data, co
 			g_free(tmp);
 			return 0;
 		}
-		/* Pass through */
 		return 1;
 
 	case FUSE_OPT_KEY_NONOPT:
@@ -3453,62 +3398,7 @@ static int sshfs_opt_proc(void *data, co
 			sshfs.host = strdup(arg);
 			return 0;
 		}
-		else if (!sshfs.mountpoint) {
-#if defined(__CYGWIN__)
-			/*
-			 * On FUSE for Cygwin the mountpoint may be a drive or directory.
-			 * Furthermore the mountpoint must NOT exist prior to mounting.
-			 * So we cannot use realpath(3).
-			 */
-			if ((('A' <= arg[0] && arg[0] <= 'Z') || ('a' <= arg[0] && arg[0] <= 'z'))
-				&& ':' == arg[1] && '\0' == arg[2]) {
-				/* drive: make a copy */
-				sshfs.mountpoint = strdup(arg);
-			} else {
-				/* path: split into dirname, basename and check dirname */
-				char *dir;
-				const char *base;
-				const char *slash = strrchr(arg, '/');
-				if (slash) {
-					char *tmp = strndup(arg, slash == arg ? 1 : slash - arg);
-					dir = tmp ? realpath(tmp, NULL) : 0;
-					base = slash + 1;
-					free(tmp);
-				} else {
-					dir = realpath(".", NULL);
-					base = arg;
-				}
-				if (dir) {
-					slash = '/' == dir[0] && '\0' == dir[1] ? "" : "/";
-					asprintf(&sshfs.mountpoint, "%s%s%s", dir, slash, base);
-					free(dir);
-				}
-			}
-#else
-                        int fd, len;
-                        if (sscanf(arg, "/dev/fd/%u%n", &fd, &len) == 1 &&
-                            len == strlen(arg)) {
-                                /*
-                                 * Allow /dev/fd/N unchanged; it can be
-                                 * use for pre-mounting a generic fuse
-                                 * mountpoint to later be completely
-                                 * unprivileged with libfuse >= 3.3.0.
-                                 */
-                                sshfs.mountpoint = strdup(arg);
-                        } else {
-                                sshfs.mountpoint = realpath(arg, NULL);
-                        }
-#endif
-			if (!sshfs.mountpoint) {
-				fprintf(stderr, "sshfs: bad mount point `%s': %s\n",
-					arg, strerror(errno));
-				return -1;
-			}
-			return 0;
-		}
-		fprintf(stderr, "sshfs: invalid argument `%s'\n", arg);
-		return -1;
-
+		return 1;
 
 	case KEY_PORT:
 		tmp = g_strdup_printf("-oPort=%s", arg + 2);
@@ -3526,6 +3416,24 @@ static int sshfs_opt_proc(void *data, co
 		g_free(tmp);
 		return 0;
 
+	case KEY_HELP:
+		usage(outargs->argv[0]);
+		fuse_opt_add_arg(outargs, "-ho");
+		sshfs_fuse_main(outargs);
+		exit(1);
+
+	case KEY_VERSION:
+		printf("SSHFS version %s\n", PACKAGE_VERSION);
+#if FUSE_VERSION >= 25
+		fuse_opt_add_arg(outargs, "--version");
+		sshfs_fuse_main(outargs);
+#endif
+		exit(0);
+
+	case KEY_FOREGROUND:
+		sshfs.foreground = 1;
+		return 1;
+
 	default:
 		fprintf(stderr, "internal error\n");
 		abort();
@@ -3563,6 +3471,33 @@ static int parse_workarounds(void)
 	return res;
 }
 
+#if FUSE_VERSION == 25
+static int fuse_opt_insert_arg(struct fuse_args *args, int pos,
+                               const char *arg)
+{
+	assert(pos <= args->argc);
+	if (fuse_opt_add_arg(args, arg) == -1)
+		return -1;
+
+	if (pos != args->argc - 1) {
+		char *newarg = args->argv[args->argc - 1];
+		memmove(&args->argv[pos + 1], &args->argv[pos],
+			sizeof(char *) * (args->argc - pos - 1));
+		args->argv[pos] = newarg;
+	}
+	return 0;
+}
+#endif
+
+static void check_large_read(struct fuse_args *args)
+{
+	struct utsname buf;
+	int err = uname(&buf);
+	if (!err && strcmp(buf.sysname, "Linux") == 0 &&
+	    strncmp(buf.release, "2.4.", 4) == 0)
+		fuse_opt_insert_arg(args, 1, "-olarge_read");
+}
+
 static int read_password(void)
 {
 	int size = getpagesize();
@@ -3610,60 +3545,40 @@ static int read_password(void)
 	return 0;
 }
 
-// Behaves similarly to strtok(), but allows for the ' ' delimiter to be escaped
-// by '\ '.
-static char *tokenize_on_space(char *str)
-{
-	static char *pos = NULL;
-	char *start = NULL;
-
-	if (str)
-		pos = str;
-
-	if (!pos)
-		return NULL;
-
-	// trim any leading spaces
-	while (*pos == ' ')
-		pos++;
-
-	start = pos;
-
-	while (pos && *pos != '\0') {
-		// break on space, but not on '\ '
-		if (*pos == ' ' && *(pos - 1) != '\\') {
-			break;
-		}
-		pos++;
-	}
-
-	if (*pos == '\0') {
-		pos = NULL;
-	}
-	else {
-		*pos = '\0';
-		pos++;
-	}
-
-	return start;
-}
-
 static void set_ssh_command(void)
 {
-	char *token = NULL;
+	char *s;
+	char *d;
 	int i = 0;
+	int end = 0;
 
-	token = tokenize_on_space(sshfs.ssh_command);
-	while (token != NULL) {
-		if (i == 0) {
-			replace_arg(&sshfs.ssh_args.argv[0], token);
-		} else {
-			if (fuse_opt_insert_arg(&sshfs.ssh_args, i, token) == -1)
-				_exit(1);
-		}
-		i++;
+	d = sshfs.ssh_command;
+	s = sshfs.ssh_command;
+	while (!end) {
+		switch (*s) {
+		case '\0':
+			end = 1;
+		case ' ':
+			*d = '\0';
+			if (i == 0) {
+				replace_arg(&sshfs.ssh_args.argv[0],
+					    sshfs.ssh_command);
+			} else {
+				if (fuse_opt_insert_arg(&sshfs.ssh_args, i,
+						sshfs.ssh_command) == -1)
+					_exit(1);
+			}
+			i++;
+			d = sshfs.ssh_command;
+			break;
 
-		token = tokenize_on_space(NULL);
+		case '\\':
+			if (s[1])
+				s++;
+		default:
+			*d++ = *s;
+		}
+		s++;
 	}
 }
 
@@ -3697,6 +3612,24 @@ static char *find_base_path(void)
 	return s;
 }
 
+/*
+ * Remove commas from fsname, as it confuses the fuse option parser.
+ */
+static void fsname_remove_commas(char *fsname)
+{
+	if (strchr(fsname, ',') != NULL) {
+		char *s = fsname;
+		char *d = s;
+
+		for (; *s; s++) {
+			if (*s != ',')
+				*d++ = *s;
+		}
+		*d = *s;
+	}
+}
+
+#if FUSE_VERSION >= 27
 static char *fsname_escape_commas(char *fsnameold)
 {
 	char *fsname = g_malloc(strlen(fsnameold) * 2 + 1);
@@ -3713,6 +3646,7 @@ static char *fsname_escape_commas(char *
 
 	return fsname;
 }
+#endif
 
 static int ssh_connect(void)
 {
@@ -3920,8 +3854,7 @@ int main(int argc, char *argv[])
 	char *tmp;
 	char *fsname;
 	const char *sftp_server;
-	struct fuse *fuse;
-	struct fuse_session *se;
+	int libver;
 
 #ifdef __APPLE__
 	if (!realpath(*exec_path, sshfs_program_path)) {
@@ -3929,11 +3862,7 @@ int main(int argc, char *argv[])
 	}
 #endif /* __APPLE__ */
 
-#ifdef __APPLE__
-	sshfs.blksize = 0;
-#else
 	sshfs.blksize = 4096;
-#endif
 	/* SFTP spec says all servers should allow at least 32k I/O */
 	sshfs.max_read = 32768;
 	sshfs.max_write = 32768;
@@ -3942,20 +3871,13 @@ int main(int argc, char *argv[])
 #else
 	sshfs.rename_workaround = 0;
 #endif
-	sshfs.renamexdev_workaround = 0;
 	sshfs.truncate_workaround = 0;
 	sshfs.buflimit_workaround = 1;
-	sshfs.createmode_workaround = 0;
 	sshfs.ssh_ver = 2;
 	sshfs.progname = argv[0];
 	sshfs.rfd = -1;
 	sshfs.wfd = -1;
 	sshfs.ptyfd = -1;
-	sshfs.dir_cache = 1;
-	sshfs.show_help = 0;
-	sshfs.show_version = 0;
-	sshfs.singlethread = 0;
-	sshfs.foreground = 0;
 	sshfs.ptyslavefd = -1;
 	sshfs.delay_connect = 0;
 	sshfs.slave = 0;
@@ -3979,28 +3901,13 @@ int main(int argc, char *argv[])
 	    parse_workarounds() == -1)
 		exit(1);
 
-	if (sshfs.show_version) {
-		printf("SSHFS version %s\n", PACKAGE_VERSION);
-		printf("FUSE library version %s\n", fuse_pkgversion());
-#if !defined(__CYGWIN__)
-		fuse_lowlevel_version();
-#endif
-		exit(0);
-	}
-
-	if (sshfs.show_help) {
-		usage(args.argv[0]);
-		fuse_lib_help(&args);
-		exit(0);
-	} else if (!sshfs.host) {
-		fprintf(stderr, "missing host\n");
-		fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
-		exit(1);
-	} else if (!sshfs.mountpoint) {
-		fprintf(stderr, "error: no mountpoint specified\n");
-		fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
-		exit(1);
+#if FUSE_VERSION >= 29
+	// These workarounds require the "path" argument.
+	if (sshfs.truncate_workaround || sshfs.fstat_workaround) {
+		sshfs_oper.oper.flag_nullpath_ok = 0;
+		sshfs_oper.oper.flag_nopath = 0;
 	}
+#endif
 
 	if (sshfs.idmap == IDMAP_USER)
 		sshfs.detect_uid = 1;
@@ -4023,10 +3930,10 @@ int main(int argc, char *argv[])
 
 	DEBUG("SSHFS version %s\n", PACKAGE_VERSION);
 
-	/* Force sshfs to the foreground when using stdin+stdout */
-	if (sshfs.slave)
+	if (sshfs.slave) {
+		/* Force sshfs to the foreground when using stdin+stdout */
 		sshfs.foreground = 1;
-
+	}
 
 	if (sshfs.slave && sshfs.password_stdin) {
 		fprintf(stderr, "the password_stdin and slave options cannot both be specified\n");
@@ -4039,9 +3946,6 @@ int main(int argc, char *argv[])
 			exit(1);
 	}
 
-	if (sshfs.debug)
-		sshfs.foreground = 1;
-	
 	if (sshfs.buflimit_workaround)
 		/* Work around buggy sftp-server in OpenSSH.  Without this on
 		   a slow server a 10Mbyte buffer would fill up and the server
@@ -4050,6 +3954,12 @@ int main(int argc, char *argv[])
 	else
 		sshfs.max_outstanding_len = ~0;
 
+	if (!sshfs.host) {
+		fprintf(stderr, "missing host\n");
+		fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
+		exit(1);
+	}
+
 	fsname = g_strdup(sshfs.host);
 	sshfs.base_path = g_strdup(find_base_path());
 
@@ -4073,6 +3983,7 @@ int main(int argc, char *argv[])
 	ssh_add_arg(sftp_server);
 	free(sshfs.sftp_server);
 
+
 	res = cache_parse_options(&args);
 	if (res == -1)
 		exit(1);
@@ -4084,70 +3995,122 @@ int main(int argc, char *argv[])
 	if (sshfs.max_write > 65536)
 		sshfs.max_write = 65536;
 
-        fsname = fsname_escape_commas(fsname);
+	if (fuse_is_lib_option("ac_attr_timeout="))
+		fuse_opt_insert_arg(&args, 1, "-oauto_cache,ac_attr_timeout=0");
+#if FUSE_VERSION >= 27
+	libver = fuse_version();
+	assert(libver >= 27);
+	if (libver >= 28)
+		fsname = fsname_escape_commas(fsname);
+	else
+		fsname_remove_commas(fsname);
 	tmp = g_strdup_printf("-osubtype=sshfs,fsname=%s", fsname);
+#else
+	fsname_remove_commas(fsname);
+	tmp = g_strdup_printf("-ofsname=sshfs#%s", fsname);
+#endif
 	fuse_opt_insert_arg(&args, 1, tmp);
 	g_free(tmp);
 	g_free(fsname);
+	check_large_read(&args);
 
-	if(sshfs.dir_cache)
-		sshfs.op = cache_wrap(&sshfs_oper);
-	else
-		sshfs.op = &sshfs_oper;
-	fuse = fuse_new(&args, sshfs.op,
-			sizeof(struct fuse_operations), NULL);
-	if(fuse == NULL)
-		exit(1);
-	se = fuse_get_session(fuse);
-	res = fuse_set_signal_handlers(se);
-	if (res != 0) {
-		fuse_destroy(fuse);
-		exit(1);
-	}
+#if FUSE_VERSION >= 26
+	{
+		struct fuse *fuse;
+		struct fuse_chan *ch;
+		char *mountpoint;
+		int multithreaded;
+		int foreground;
+#if !defined(__APPLE__) && !defined(__CYGWIN__)
+		struct stat st;
+#endif
 
-	res = fuse_mount(fuse, sshfs.mountpoint);
-	if (res != 0) {
-		fuse_destroy(fuse);
-		exit(1);
-	}
+		res = fuse_parse_cmdline(&args, &mountpoint, &multithreaded,
+					 &foreground);
+		if (res == -1)
+			exit(1);
+
+		if (sshfs.slave) {
+			/* Force sshfs to the foreground when using stdin+stdout */
+			foreground = 1;
+		}
+
+#if !defined(__APPLE__) && !defined(__CYGWIN__)
+		res = stat(mountpoint, &st);
+		if (res == -1) {
+			perror(mountpoint);
+			exit(1);
+		}
+		sshfs.mnt_mode = st.st_mode;
+#else
+		sshfs.mnt_mode = S_IFDIR | 0755;
+#endif
+
+		ch = fuse_mount(mountpoint, &args);
+		if (!ch)
+			exit(1);
 
 #if !defined(__CYGWIN__)
-	res = fcntl(fuse_session_fd(se), F_SETFD, FD_CLOEXEC);
-	if (res == -1)
-		perror("WARNING: failed to set FD_CLOEXEC on fuse device");
+		res = fcntl(fuse_chan_fd(ch), F_SETFD, FD_CLOEXEC);
+		if (res == -1)
+			perror("WARNING: failed to set FD_CLOEXEC on fuse device");
 #endif
 
-	/*
-	 * FIXME: trim $PATH so it doesn't contain anything inside the
-	 * mountpoint, which would deadlock.
-	 */
-	res = ssh_connect();
-	if (res == -1) {
-		fuse_unmount(fuse);
-		fuse_destroy(fuse);
-		exit(1);
-	}
+		sshfs.op = cache_init(&sshfs_oper);
+		fuse = fuse_new(ch, &args, sshfs.op,
+				sizeof(struct fuse_operations), NULL);
+		if (fuse == NULL) {
+			fuse_unmount(mountpoint, ch);
+			exit(1);
+		}
 
-	res = fuse_daemonize(sshfs.foreground);
-	if (res == -1) {
-		fuse_unmount(fuse);
-		fuse_destroy(fuse);
-		exit(1);
-	}
+                res = fuse_set_signal_handlers(fuse_get_session(fuse));
+		if (res == -1) {
+			fuse_unmount(mountpoint, ch);
+			fuse_destroy(fuse);
+			exit(1);
+		}
 
-	if (sshfs.singlethread)
-		res = fuse_loop(fuse);
-	else
-		res = fuse_loop_mt(fuse, 0);
+		/*
+		 * FIXME: trim $PATH so it doesn't contain anything inside the
+		 * mountpoint, which would deadlock.
+		 */
+		res = ssh_connect();
+		if (res == -1) {
+			fuse_unmount(mountpoint, ch);
+			fuse_destroy(fuse);
+			exit(1);
+		}
 
-	if (res != 0)
-		res = 1;
-	else
-		res = 0;
+		res = fuse_daemonize(foreground);
+		if (res == -1) {
+			fuse_unmount(mountpoint, ch);
+			fuse_destroy(fuse);
+			exit(1);
+		}
+
+		if (multithreaded)
+			res = fuse_loop_mt(fuse);
+		else
+			res = fuse_loop(fuse);
 
-	fuse_remove_signal_handlers(se);
-	fuse_unmount(fuse);
-	fuse_destroy(fuse);
+		if (res == -1)
+			res = 1;
+		else
+			res = 0;
+
+		fuse_remove_signal_handlers(fuse_get_session(fuse));
+		fuse_unmount(mountpoint, ch);
+		fuse_destroy(fuse);
+		free(mountpoint);
+	}
+#else
+	res = ssh_connect();
+	if (res == -1)
+		exit(1);
+
+	res = sshfs_fuse_main(&args);
+#endif
 
 	if (sshfs.debug) {
 		unsigned int avg_rtt = 0;
diff -pruN 3.6.0+repack-1/sshfs.rst 3.6.0+repack+really2.10-0ubuntu1/sshfs.rst
--- 3.6.0+repack-1/sshfs.rst	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/sshfs.rst	1970-01-01 00:00:00.000000000 +0000
@@ -1,327 +0,0 @@
-=======
- SSHFS
-=======
-
----------------------------------------------
- filesystem client based on SSH
----------------------------------------------
-
-:Manual section: 1
-:Manual group: User Commands
-
-Synopsis
-========
-
-To mount a filesystem::
-
-   sshfs [user@]host:[dir] mountpoint [options]
-
-If *host* is a numeric IPv6 address, it needs to be enclosed in square
-brackets.
-
-To unmount it::
-
-  fusermount3 -u mountpoint   # Linux
-  umount mountpoint           # OS X, FreeBSD
-
-Description
-===========
-
-SSHFS allows you to mount a remote filesystem using SSH (more
-precisely, the SFTP subsystem). Most SSH servers support and enable
-this SFTP access by default, so SSHFS is very simple to use - there's
-nothing to do on the server-side.
-
-SSHFS uses FUSE (Filesystem in Userspace) and should work on any
-operating system that provides a FUSE implementation. Currently,
-this includes Linux, FreeBSD and Mac OS X.
-
-It is recommended to run SSHFS as regular user (not as root).  For
-this to work the mountpoint must be owned by the user.  If username is
-omitted SSHFS will use the local username. If the directory is
-omitted, SSHFS will mount the (remote) home directory.  If you need to
-enter a password sshfs will ask for it (actually it just runs ssh
-which ask for the password if needed).
-
-
-Options
-=======
-
-
--o opt,[opt...]
-   mount options, see below for details. A a variety of SSH options can
-   be given here as well, see the manual pages for *sftp(1)* and
-   *ssh_config(5)*.
-
--h, --help
-   print help and exit.
-
--V, --version
-   print version information and exit.
-
--d, --debug
-   print debugging information.
-
--p PORT
-   equivalent to '-o port=PORT'
-
--f
-   do not daemonize, stay in foreground.
-
--s
-   Single threaded operation.
-
--C
-   equivalent to '-o compression=yes'
-
--F ssh_configfile
-   specifies alternative ssh configuration file
-
--1
-   equivalent to '-o ssh_protocol=1'
-
--o reconnect
-   automatically reconnect to server if connection is
-   interrupted. Attempts to access files that were opened before the
-   reconnection will give errors and need to be re-opened.
-
--o delay_connect
-   Don't immediately connect to server, wait until mountpoint is first
-   accessed.
-
--o sshfs_sync
-   synchronous writes. This will slow things down, but may be useful
-   in some situations.
-
--o no_readahead
-   Only read exactly the data that was requested, instead of
-   speculatively reading more to anticipate the next read request.
-
--o sync_readdir
-   synchronous readdir. This will slow things down, but may be useful
-   in some situations.
-
--o workaround=LIST
-   Enable the specified workaround. See the `Caveats` section below
-   for some additional information. Possible values are:
-
-   :rename: Emulate overwriting an existing file by deleting and
-        renaming.
-   :renamexdev: Make rename fail with EXDEV instead of the default EPERM
-        to allow moving files across remote filesystems.
-   :truncate: Work around servers that don't support truncate by
-        coping the whole file, truncating it locally, and sending it
-        back.
-   :fstat: Work around broken servers that don't support *fstat()* by
-           using *stat* instead.
-   :buflimit: Work around OpenSSH "buffer fillup" bug.
-   :createmode: Work around broken servers that produce an error when passing a
-                non-zero mode to create, by always passing a mode of 0.
-
--o idmap=TYPE
-   How to map remote UID/GIDs to local values. Possible values are:
-
-   :none: no translation of the ID space (default).
-
-   :user: map the UID/GID of the remote user to UID/GID of the
-            mounting user.
-
-   :file: translate UIDs/GIDs based upon the contents of `--uidfile`
-            and `--gidfile`.
-
--o uidfile=FILE
-   file containing ``username:uid`` mappings for `-o idmap=file`
-
--o gidfile=FILE
-   file containing ``groupname:gid`` mappings for `-o idmap=file`
-
--o nomap=TYPE
-   with idmap=file, how to handle missing mappings:
-
-   :ignore: don't do any re-mapping
-   :error:  return an error (default)
-
--o ssh_command=CMD
-   execute CMD instead of 'ssh'
-
--o ssh_protocol=N
-   ssh protocol to use (default: 2)
-
--o sftp_server=SERV
-   path to sftp server or subsystem (default: sftp)
-
--o directport=PORT
-   directly connect to PORT bypassing ssh
-
--o slave
-   communicate over stdin and stdout bypassing network
-
--o disable_hardlink
-   With this option set, attempts to call `link(2)` will fail with
-   error code ENOSYS.
-
--o transform_symlinks
-   transform absolute symlinks on remote side to relative
-   symlinks. This means that if e.g. on the server side
-   ``/foo/bar/com`` is a symlink to ``/foo/blub``, SSHFS will
-   transform the link target to ``../blub`` on the client side.
-
--o follow_symlinks
-   follow symlinks on the server, i.e. present them as regular
-   files on the client. If a symlink is dangling (i.e, the target does
-   not exist) the behavior depends on the remote server - the entry
-   may appear as a symlink on the client, or it may appear as a
-   regular file that cannot be accessed.
-
--o no_check_root
-   don't check for existence of 'dir' on server
-
--o password_stdin
-   read password from stdin (only for pam_mount!)
-
--o dir_cache=BOOL
-   Enables (*yes*) or disables (*no*) the SSHFS directory cache.  The
-   directory cache holds the names of directory entries. Enabling it
-   allows `readdir(3)` system calls to be processed without network
-   access.
-   
--o dcache_max_size=N
-   sets the maximum size of the directory cache.
-   
--o dcache_timeout=N
-   sets timeout for directory cache in seconds.
-   
--o dcache_{stat,link,dir}_timeout=N
-   sets separate timeout for {attributes, symlinks, names} in  the
-   directory cache.
-   
--o dcache_clean_interval=N
-   sets the interval for automatic cleaning of the directory cache.
-
--o dcache_min_clean_interval=N
-   sets the interval for forced cleaning of the directory cache
-   when full.
-
--o direct_io
-   This option disables the use of page cache (file content cache) in 
-   the kernel for this filesystem.
-   This has several affects:
-   1. Each read() or write() system call will initiate one or more read or
-      write operations, data will not be cached in the kernel.
-   2. The return value of the read() and write() system calls will correspond 
-      to the return values of the read and write operations. This is useful 
-      for example if the file size is not known in advance (before reading it).
-      e.g. /proc filesystem 
-
-In addition, SSHFS accepts several options common to all FUSE file
-systems. These are described in the `mount.fuse` manpage (look
-for "general", "libfuse specific", and "high-level API" options).
-
-Caveats / Workarounds
-=====================
-
-Hardlinks
-~~~~~~~~~
-
-If the SSH server supports the *hardlinks* extension, SSHFS will allow
-you to create hardlinks. However, hardlinks will always appear as
-individual files when seen through an SSHFS mount, i.e. they will
-appear to have different inodes and an *st_nlink* value of 1.
-
-
-Rename
-~~~~~~
-
-Some SSH servers do not support atomically overwriting the destination
-when renaming a file. In this case you will get an error when you
-attempt to rename a file and the destination already exists. A
-workaround is to first remove the destination file, and then do the
-rename. SSHFS can do this automatically if you call it with `-o
-workaround=rename`. However, in this case it is still possible that
-someone (or something) recreates the destination file after SSHFS has
-removed it, but before SSHFS had the time to rename the old file. In
-this case, the rename will still fail.
-
-
-Permission denied when moving files across remote filesystems
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Most SFTP servers return only a generic "failure" when failing to rename
-across filesystem boundaries (EXDEV).  sshfs normally converts this generic
-failure to a permission denied error (EPERM).  If the option ``-o
-workaround=renamexdev`` is given, generic failures will be considered EXDEV
-errors which will make programs like `mv(1)` attempt to actually move the
-file after the failed rename.
-
-
-SSHFS hangs for no apparent reason
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In some cases, attempts to access the SSHFS mountpoint may freeze if
-no filesystem activity has occured for some time. This is typically
-caused by the SSH connection being dropped because of inactivity
-without SSHFS being informed about that. As a workaround, you can try
-to mount with ``-o ServerAliveInterval=15``. This will force the SSH
-connection to stay alive even if you have no activity.
-
-
-SSHFS hangs after the connection was interrupted
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-By default, network operations in SSHFS run without timeouts, mirroring the
-default behavior of SSH itself. As a consequence, if the connection to the
-remote host is interrupted (e.g. because a network cable was removed),
-operations on files or directories under the mountpoint will block until the
-connection is either restored or closed altogether (e.g. manually).
-Applications that try to access such files or directories will generally appear
-to "freeze" when this happens.
-
-If it is acceptable to discard data being read or written, a quick workaround
-is to kill the responsible ``sshfs`` process, which will make any blocking
-operations on the mounted filesystem error out and thereby "unfreeze" the
-relevant applications. Note that force unmounting with ``fusermount -zu``, on
-the other hand, does not help in this case and will leave read/write operations
-in the blocking state.
-
-For a more automatic solution, one can use the ``-o ServerAliveInterval=15``
-option mentioned above, which will drop the connection after not receiving a
-response for 3 * 15 = 45 seconds from the remote host. By also supplying ``-o
-reconnect``, one can ensure that the connection is re-established as soon as
-possible afterwards. As before, this will naturally lead to loss of data that
-was in the process of being read or written at the time when the connection was
-interrupted.
-
-
-Mounting from /etc/fstab
-========================
-
-To mount an SSHFS filesystem from ``/etc/fstab``, simply use ``sshfs`
-as the file system type. (For backwards compatibility, you may also
-use ``fuse.sshfs``).
-
-
-See also
-========
-
-The `mount.fuse(8)` manpage.
-
-Getting Help
-============
-
-If you need help, please ask on the <fuse-sshfs@lists.sourceforge.net>
-mailing list (subscribe at
-https://lists.sourceforge.net/lists/listinfo/fuse-sshfs).
-
-Please report any bugs on the GitHub issue tracker at
-https://github.com/libfuse/libfuse/issues.
-
-
-Authors
-=======
-
-SSHFS is currently maintained by Nikolaus Rath <Nikolaus@rath.org>,
-and was created by Miklos Szeredi <miklos@szeredi.hu>.
-
-This man page was originally written by Bartosz Fenski
-<fenio@debian.org> for the Debian GNU/Linux distribution (but it may
-be used by others).
diff -pruN 3.6.0+repack-1/test/appveyor-build.sh 3.6.0+repack+really2.10-0ubuntu1/test/appveyor-build.sh
--- 3.6.0+repack-1/test/appveyor-build.sh	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/test/appveyor-build.sh	1970-01-01 00:00:00.000000000 +0000
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-machine=$(uname -m)
-mkdir build-$machine
-cd build-$machine
-meson ..
-ninja
diff -pruN 3.6.0+repack-1/test/Makefile.am 3.6.0+repack+really2.10-0ubuntu1/test/Makefile.am
--- 3.6.0+repack-1/test/Makefile.am	1970-01-01 00:00:00.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/test/Makefile.am	2017-08-03 16:00:34.000000000 +0000
@@ -0,0 +1,4 @@
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = meson.build conftest.py pytest.ini test_sshfs.py \
+	     util.py wrong_command.c
diff -pruN 3.6.0+repack-1/test/meson.build 3.6.0+repack+really2.10-0ubuntu1/test/meson.build
--- 3.6.0+repack-1/test/meson.build	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/test/meson.build	2017-08-03 16:00:34.000000000 +0000
@@ -2,7 +2,7 @@ test_scripts = [ 'conftest.py', 'pytest.
                  'util.py' ]
 custom_target('test_scripts', input: test_scripts,
               output: test_scripts, build_by_default: true,
-              command: ['cp', '-fPp', 
+              command: ['cp', '-fPu', '--preserve=mode',
                         '@INPUT@', meson.current_build_dir() ])
 
 # Provide something helpful when running 'ninja test'
diff -pruN 3.6.0+repack-1/test/test_sshfs.py 3.6.0+repack+really2.10-0ubuntu1/test/test_sshfs.py
--- 3.6.0+repack-1/test/test_sshfs.py	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/test/test_sshfs.py	2017-08-03 16:00:34.000000000 +0000
@@ -13,7 +13,6 @@ import stat
 import shutil
 import filecmp
 import errno
-from contextlib import contextmanager
 from tempfile import NamedTemporaryFile
 from util import (wait_for_mount, umount, cleanup, base_cmdline,
                   basename, fuse_test_marker, safe_sleep)
@@ -31,9 +30,8 @@ def name_generator(__ctr=[0]):
     return 'testfile_%d' % __ctr[0]
 
 @pytest.mark.parametrize("debug", (False, True))
-@pytest.mark.parametrize("cache_timeout", (0,1))
-@pytest.mark.parametrize("sync_rd", (True, False))
-def test_sshfs(tmpdir, debug, cache_timeout, sync_rd, capfd):
+@pytest.mark.parametrize("cache_timeout", (0, 1))
+def test_sshfs(tmpdir, debug, cache_timeout, capfd):
     
     # Avoid false positives from debug messages
     #if debug:
@@ -60,15 +58,11 @@ def test_sshfs(tmpdir, debug, cache_time
     if debug:
         cmdline += [ '-o', 'sshfs_debug' ]
 
-    if sync_rd:
-        cmdline += [ '-o', 'sync_readdir' ]
-
     # SSHFS Cache
     if cache_timeout == 0:
-        cmdline += [ '-o', 'dir_cache=no' ]
+        cmdline += [ '-o', 'cache=no' ]
     else:
-        cmdline += [ '-o', 'dcache_timeout=%d' % cache_timeout,
-                     '-o', 'dir_cache=yes' ]
+        cmdline += [ '-o', 'cache_timeout=%d' % cache_timeout ]
 
     # FUSE Cache
     cmdline += [ '-o', 'entry_timeout=0',
@@ -88,8 +82,6 @@ def test_sshfs(tmpdir, debug, cache_time
         tst_readdir(src_dir, mnt_dir)
         tst_open_read(src_dir, mnt_dir)
         tst_open_write(src_dir, mnt_dir)
-        tst_append(src_dir, mnt_dir)
-        tst_seek(src_dir, mnt_dir)
         tst_create(mnt_dir)
         tst_passthrough(src_dir, mnt_dir, cache_timeout)
         tst_mkdir(mnt_dir)
@@ -102,29 +94,17 @@ def test_sshfs(tmpdir, debug, cache_time
         # SSHFS only supports one second resolution when setting
         # file timestamps.
         tst_utimens(mnt_dir, tol=1)
-        tst_utimens_now(mnt_dir)
 
-        tst_link(mnt_dir, cache_timeout)
+        tst_link(mnt_dir)
         tst_truncate_path(mnt_dir)
         tst_truncate_fd(mnt_dir)
         tst_open_unlink(mnt_dir)
     except:
-        cleanup(mount_process, mnt_dir)
+        cleanup(mnt_dir)
         raise
     else:
         umount(mount_process, mnt_dir)
 
-@contextmanager
-def os_open(name, flags):
-    fd = os.open(name, flags)
-    try:
-        yield fd
-    finally:
-        os.close(fd)
-
-def os_create(name):
-    os.close(os.open(name, os.O_CREAT | os.O_RDWR))
-
 def tst_unlink(src_dir, mnt_dir, cache_timeout):
     name = name_generator()
     fullname = mnt_dir + "/" + name
@@ -230,32 +210,6 @@ def tst_open_write(src_dir, mnt_dir):
 
     assert filecmp.cmp(fullname, TEST_FILE, False)
 
-def tst_append(src_dir, mnt_dir):
-    name = name_generator()
-    os_create(pjoin(src_dir, name))
-    fullname = pjoin(mnt_dir, name)
-    with os_open(fullname, os.O_WRONLY) as fd:
-        os.write(fd, b'foo\n')
-    with os_open(fullname, os.O_WRONLY|os.O_APPEND) as fd:
-        os.write(fd, b'bar\n')
-
-    with open(fullname, 'rb') as fh:
-        assert fh.read() == b'foo\nbar\n'
-
-def tst_seek(src_dir, mnt_dir):
-    name = name_generator()
-    os_create(pjoin(src_dir, name))
-    fullname = pjoin(mnt_dir, name)
-    with os_open(fullname, os.O_WRONLY) as fd:
-        os.lseek(fd, 1, os.SEEK_SET)
-        os.write(fd, b'foobar\n')
-    with os_open(fullname, os.O_WRONLY) as fd:
-        os.lseek(fd, 4, os.SEEK_SET)
-        os.write(fd, b'com')
-
-    with open(fullname, 'rb') as fh:
-        assert fh.read() == b'\0foocom\n'
-
 def tst_open_unlink(mnt_dir):
     name = pjoin(mnt_dir, name_generator())
     data1 = b'foo'
@@ -275,7 +229,7 @@ def tst_open_unlink(mnt_dir):
 def tst_statvfs(mnt_dir):
     os.statvfs(mnt_dir)
 
-def tst_link(mnt_dir, cache_timeout):
+def tst_link(mnt_dir):
     name1 = pjoin(mnt_dir, name_generator())
     name2 = pjoin(mnt_dir, name_generator())
     shutil.copyfile(TEST_FILE, name1)
@@ -286,14 +240,6 @@ def tst_link(mnt_dir, cache_timeout):
 
     os.link(name1, name2)
 
-    # The link operation changes st_ctime, and if we're unlucky
-    # the kernel will keep the old value cached for name1, and
-    # retrieve the new value for name2 (at least, this is the only
-    # way I can explain the test failure). To avoid this problem,
-    # we need to wait until the cached value has expired.
-    if cache_timeout:
-        safe_sleep(cache_timeout)
-    
     fstat1 = os.lstat(name1)
     fstat2 = os.lstat(name2)
     for attr in ('st_mode', 'st_dev', 'st_uid', 'st_gid',
@@ -404,18 +350,6 @@ def tst_utimens(mnt_dir, tol=0):
         assert abs(fstat.st_atime_ns - atime_ns) < tol*1e9
         assert abs(fstat.st_mtime_ns - mtime_ns) < tol*1e9
 
-def tst_utimens_now(mnt_dir):
-    fullname = pjoin(mnt_dir, name_generator())
-
-    fd = os.open(fullname, os.O_CREAT | os.O_RDWR)
-    os.close(fd)
-    os.utime(fullname, None)
-
-    fstat = os.lstat(fullname)
-    # We should get now-timestamps
-    assert fstat.st_atime != 0
-    assert fstat.st_mtime != 0
-
 def tst_passthrough(src_dir, mnt_dir, cache_timeout):
     name = name_generator()
     src_name = pjoin(src_dir, name)
diff -pruN 3.6.0+repack-1/test/travis-build.sh 3.6.0+repack+really2.10-0ubuntu1/test/travis-build.sh
--- 3.6.0+repack-1/test/travis-build.sh	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/test/travis-build.sh	2017-08-03 16:00:34.000000000 +0000
@@ -36,6 +36,13 @@ for san in undefined address; do
     meson -D b_sanitize=${san} -D b_lundef=false -D werror=true ..
     ninja
     ${TEST_CMD}
-    sudo ninja install
     cd ..
 done
+
+# Autotools build
+CC=gcc
+autoreconf -i
+./configure
+make
+${TEST_CMD}
+sudo make install
diff -pruN 3.6.0+repack-1/test/travis-install.sh 3.6.0+repack+really2.10-0ubuntu1/test/travis-install.sh
--- 3.6.0+repack-1/test/travis-install.sh	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/test/travis-install.sh	2017-08-03 16:00:34.000000000 +0000
@@ -2,29 +2,20 @@
 
 set -e
 
-# Meson 0.45 requires Python 3.5 or newer
-sudo python3 -m pip install pytest meson==0.44
+sudo ln -svf $(which python3) /usr/bin/python3
+sudo python3 -m pip install pytest meson
+wget https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-linux.zip
+unzip ninja-linux.zip
+chmod 755 ninja
+sudo chown root:root ninja
+sudo mv -fv ninja /usr/local/bin
 valgrind --version
 ninja --version
 meson --version
 
-# Install fuse
-wget https://github.com/libfuse/libfuse/archive/master.zip
-unzip master.zip
-cd libfuse-master
-mkdir build
-cd build
-export CC=gcc-6
-meson ..
-ninja
-sudo ninja install
-test -e /usr/local/lib/pkgconfig || sudo mkdir /usr/local/lib/pkgconfig
-sudo mv /usr/local/lib/*/pkgconfig/* /usr/local/lib/pkgconfig/
-ls -d1 /usr/local/lib/*-linux-gnu | sudo tee /etc/ld.so.conf.d/usrlocal.conf
-sudo ldconfig
-
 # Setup ssh
-ssh-keygen -b 1024 -t rsa -f ~/.ssh/id_rsa -P ''
+ssh-keygen -b 768 -t rsa -f ~/.ssh/id_rsa -P ''
 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
 chmod 600 ~/.ssh/authorized_keys
 ssh -o "StrictHostKeyChecking=no" localhost echo "SSH connection succeeded"
+
diff -pruN 3.6.0+repack-1/test/util.py 3.6.0+repack+really2.10-0ubuntu1/test/util.py
--- 3.6.0+repack-1/test/util.py	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/test/util.py	2017-08-03 16:00:34.000000000 +0000
@@ -20,19 +20,13 @@ def wait_for_mount(mount_process, mnt_di
         elapsed += 0.1
     pytest.fail("mountpoint failed to come up")
 
-def cleanup(mount_process, mnt_dir):
+def cleanup(mnt_dir):
     subprocess.call(['fusermount', '-z', '-u', mnt_dir],
                     stdout=subprocess.DEVNULL,
                     stderr=subprocess.STDOUT)
-    mount_process.terminate()
-    try:
-        mount_process.wait(1)
-    except subprocess.TimeoutExpired:
-        mount_process.kill()
-    
 
 def umount(mount_process, mnt_dir):
-    subprocess.check_call(['fusermount3', '-z', '-u', mnt_dir ])
+    subprocess.check_call(['fusermount', '-z', '-u', mnt_dir ])
     assert not os.path.ismount(mnt_dir)
 
     # Give mount process a little while to terminate. Popen.wait(timeout)
diff -pruN 3.6.0+repack-1/utils/install_helper.sh 3.6.0+repack+really2.10-0ubuntu1/utils/install_helper.sh
--- 3.6.0+repack-1/utils/install_helper.sh	2019-11-03 09:34:29.000000000 +0000
+++ 3.6.0+repack+really2.10-0ubuntu1/utils/install_helper.sh	1970-01-01 00:00:00.000000000 +0000
@@ -1,19 +0,0 @@
-#!/bin/sh
-#
-# Don't call this script. It is used internally by the Meson
-# build system. Thank you for your cooperation.
-#
-
-set -e
-
-bindir="$2"
-sbindir="$1"
-prefix="${MESON_INSTALL_DESTDIR_PREFIX}"
-
-mkdir -p "${prefix}/${sbindir}"
-
-ln -svf --relative "${prefix}/${bindir}/sshfs" \
-   "${prefix}/${sbindir}/mount.sshfs"
-
-ln -svf --relative "${prefix}/${bindir}/sshfs" \
-   "${prefix}/${sbindir}/mount.fuse.sshfs"
