aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolaus Rath <Nikolaus@rath.org>2017-08-06 11:06:42 +0200
committerNikolaus Rath <Nikolaus@rath.org>2017-08-06 11:07:23 +0200
commitd141ea44c1d901c27f61865808e8c5f9801b2606 (patch)
tree790fbd2e8aeb01426edb9bb2ed9c04f62f78aafe
parent6ac4046bee1763081d78fab555dc8c4ecd24078d (diff)
downloadsshfs-d141ea44c1d901c27f61865808e8c5f9801b2606.tar
sshfs-d141ea44c1d901c27f61865808e8c5f9801b2606.tar.gz
sshfs-d141ea44c1d901c27f61865808e8c5f9801b2606.tar.bz2
sshfs-d141ea44c1d901c27f61865808e8c5f9801b2606.zip
Re-enabled writeback cache.
Fixes: #72.
-rw-r--r--ChangeLog.rst3
-rw-r--r--README.rst10
-rw-r--r--sshfs.c30
-rwxr-xr-xtest/test_sshfs.py3
4 files changed, 36 insertions, 10 deletions
diff --git a/ChangeLog.rst b/ChangeLog.rst
index 5285523..973d86b 100644
--- a/ChangeLog.rst
+++ b/ChangeLog.rst
@@ -1,8 +1,7 @@
Unreleased Changes
------------------
-* Truly disable the writeback cache, instead of just adjusting the
- default and printing a warning when explicitly enabled.
+* Re-enabled writeback cache.
* SSHFS now supports O_APPEND.
Release 3.1.0 (2017-08-04)
diff --git a/README.rst b/README.rst
index 91c3ef5..1ec2d72 100644
--- a/README.rst
+++ b/README.rst
@@ -116,6 +116,16 @@ individual files when seen through an SSHFS mount, i.e. they will
appear to have different inodes and an *st_nlink* value of 1.
+O_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``.
+
+
Getting Help
------------
diff --git a/sshfs.c b/sshfs.c
index cc35577..a76ae8a 100644
--- a/sshfs.c
+++ b/sshfs.c
@@ -216,6 +216,7 @@ struct sshfs {
int rename_workaround;
int truncate_workaround;
int buflimit_workaround;
+ int unrel_append;
int fstat_workaround;
int transform_symlinks;
int follow_symlinks;
@@ -409,6 +410,7 @@ static struct fuse_opt sshfs_opts[] = {
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),
@@ -2500,6 +2502,24 @@ 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)
@@ -3344,6 +3364,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"
@@ -3855,7 +3876,8 @@ int main(int argc, char *argv[])
sshfs.wfd = -1;
sshfs.ptyfd = -1;
sshfs.dir_cache = 1;
- sshfs.writeback_cache = 0;
+ sshfs.writeback_cache = 1;
+ sshfs.unrel_append = 0;
sshfs.show_help = 0;
sshfs.show_version = 0;
sshfs.singlethread = 0;
@@ -3904,12 +3926,6 @@ int main(int argc, char *argv[])
exit(1);
}
- if(sshfs.writeback_cache) {
- printf("NOTICE: writeback cache is disabled in this release due to potential\n"
- "dataloss. It will be re-enabled in a future SSHFS release.\n");
- sshfs.writeback_cache = 0;
- }
-
if (sshfs.idmap == IDMAP_USER)
sshfs.detect_uid = 1;
else if (sshfs.idmap == IDMAP_FILE) {
diff --git a/test/test_sshfs.py b/test/test_sshfs.py
index 446a617..224179f 100755
--- a/test/test_sshfs.py
+++ b/test/test_sshfs.py
@@ -66,7 +66,8 @@ def test_sshfs(tmpdir, debug, cache_timeout, sync_rd,
cmdline += [ '-o', 'sync_readdir' ]
if writeback:
- cmdline += [ '-o', 'writeback_cache=yes' ]
+ cmdline += [ '-o', 'writeback_cache=yes',
+ '-o', 'unreliable_append' ]
else:
cmdline += [ '-o', 'writeback_cache=no' ]