From d193b19a8f60e8830f0aa5696d2bf3d4fd8d7930 Mon Sep 17 00:00:00 2001 From: Nikolaus Rath Date: Wed, 20 Sep 2017 17:47:52 +0100 Subject: [PATCH] Dropped support for writeback caching 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. For more details, see https://marc.info/?l=fuse-devel&m=150592103107662&w=2 or As a consequence, the -o unreliable_append option has become obsolete as well. Fixes: #93 Fixes: #88 Fixes: #81 --- ChangeLog.rst | 4 ++++ sshfs.c | 34 ++++------------------------------ sshfs.rst | 15 --------------- test/test_sshfs.py | 10 +--------- 4 files changed, 9 insertions(+), 54 deletions(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index dffae52b..6347a662 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,6 +1,10 @@ Unreleased Changes ------------------ +* 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. diff --git a/sshfs.c b/sshfs.c index a76ae8a3..50ec3849 100644 --- a/sshfs.c +++ b/sshfs.c @@ -226,7 +226,6 @@ struct sshfs { int nomap; int disable_hardlink; int dir_cache; - int writeback_cache; int show_version; int show_help; int singlethread; @@ -408,9 +407,6 @@ static struct fuse_opt sshfs_opts[] = { 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("writeback_cache=yes", writeback_cache, 1), - SSHFS_OPT("writeback_cache=no", writeback_cache, 0), - SSHFS_OPT("unreliable_append", unrel_append, 1), SSHFS_OPT("-h", show_help, 1), SSHFS_OPT("--help", show_help, 1), @@ -429,6 +425,10 @@ static struct fuse_opt sshfs_opts[] = { 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), + + FUSE_OPT_END }; @@ -1736,10 +1736,6 @@ static void *sshfs_init(struct fuse_conn_info *conn, // Lookup of . and .. is supported conn->capable |= FUSE_CAP_EXPORT_SUPPORT; - // Enable writeback cache if supported - if (sshfs.writeback_cache && (conn->capable & FUSE_CAP_WRITEBACK_CACHE)) - conn->want |= FUSE_CAP_WRITEBACK_CACHE; - if (!sshfs.delay_connect) start_processing_thread(); @@ -2502,24 +2498,6 @@ static int sshfs_open_common(const char *path, mode_t mode, if (sshfs.dir_cache) wrctr = cache_get_write_ctr(); - /* With writeback cache, kernel may send read requests even - when userspace opened write-only */ - if (sshfs.writeback_cache && - (fi->flags & O_ACCMODE) == O_WRONLY) { - fi->flags &= ~O_ACCMODE; - fi->flags |= O_RDWR; - } - - /* Having the kernel handle O_APPEND doesn't work reliably, if - the file changes on the server at the wrong time, we will - overwrite data instead of appending. */ - if ((fi->flags & O_APPEND) && sshfs.writeback_cache) { - if(sshfs.unrel_append) - fi->flags &= ~O_APPEND; - else - return -EINVAL; - } - if ((fi->flags & O_ACCMODE) == O_RDONLY) pflags = SSH_FXF_READ; else if((fi->flags & O_ACCMODE) == O_WRONLY) @@ -3364,9 +3342,7 @@ static void usage(const char *progname) " -o sshfs_sync synchronous writes\n" " -o no_readahead synchronous reads (no speculative readahead)\n" " -o sync_readdir synchronous readdir\n" -" -o unreliable_append Enable (unreliable) O_APPEND support\n" " -d, --debug print some debugging information (implies -f)\n" -" -o writeback_cache=BOOL enable writeback cache {yes,no} (default: yes)\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" @@ -3876,8 +3852,6 @@ int main(int argc, char *argv[]) sshfs.wfd = -1; sshfs.ptyfd = -1; sshfs.dir_cache = 1; - sshfs.writeback_cache = 1; - sshfs.unrel_append = 0; sshfs.show_help = 0; sshfs.show_version = 0; sshfs.singlethread = 0; diff --git a/sshfs.rst b/sshfs.rst index 7c763dd7..dac3108f 100644 --- a/sshfs.rst +++ b/sshfs.rst @@ -175,21 +175,6 @@ Options -o password_stdin read password from stdin (only for pam_mount!) --o writeback_cache=BOOL - Enables (*yes*) or disables (*no*) the FUSE writeback cache. When - writeback caching is enabled, write operations are not immediately - sent to the SSH server but first collected and merged locally. This - can significantly improve performance. However, if the file is - changed on the server while there are unsent changes on the client, - data corruption is likely to result. - --o unreliable_append - When writeback caching is enabled, SSHFS cannot reliably support - the ``O_APPEND`` open flag and thus signals an error on open. To - enable support for unreliable ``O_APPEND`` (which may overwrite - data if the file changes on the server at a bad time), mount the - file system with ``-o unreliable_append``. - -o dir_cache=BOOL Enables (*yes*) or disables (*no*) the SSHFS directory cache. The directory cache holds the names of directory entries. Enabling it diff --git a/test/test_sshfs.py b/test/test_sshfs.py index 0c8917b4..caa7fdae 100755 --- a/test/test_sshfs.py +++ b/test/test_sshfs.py @@ -33,9 +33,7 @@ def name_generator(__ctr=[0]): @pytest.mark.parametrize("debug", (False, True)) @pytest.mark.parametrize("cache_timeout", (0,1)) @pytest.mark.parametrize("sync_rd", (True, False)) -@pytest.mark.parametrize("writeback", (False, True)) -def test_sshfs(tmpdir, debug, cache_timeout, sync_rd, - writeback, capfd): +def test_sshfs(tmpdir, debug, cache_timeout, sync_rd, capfd): # Avoid false positives from debug messages #if debug: @@ -65,12 +63,6 @@ def test_sshfs(tmpdir, debug, cache_timeout, sync_rd, if sync_rd: cmdline += [ '-o', 'sync_readdir' ] - if writeback: - cmdline += [ '-o', 'writeback_cache=yes', - '-o', 'unreliable_append' ] - else: - cmdline += [ '-o', 'writeback_cache=no' ] - # SSHFS Cache if cache_timeout == 0: cmdline += [ '-o', 'dir_cache=no' ]