aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-02-01 15:50:44 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2006-02-01 15:50:44 +0000
commit6f0233e11e9a819e2bc50d4e0d09dd7d083071d6 (patch)
tree3c1340ccb7f04b0d294196f6ad78fe6d38040151
parent89da93d07eeb3629858011358a4f07ded2f64df0 (diff)
downloadsshfs-6f0233e11e9a819e2bc50d4e0d09dd7d083071d6.tar
sshfs-6f0233e11e9a819e2bc50d4e0d09dd7d083071d6.tar.gz
sshfs-6f0233e11e9a819e2bc50d4e0d09dd7d083071d6.tar.bz2
sshfs-6f0233e11e9a819e2bc50d4e0d09dd7d083071d6.zip
fix
-rw-r--r--ChangeLog9
-rw-r--r--Makefile.am4
-rw-r--r--configure.ac4
-rw-r--r--sshfs.c25
4 files changed, 29 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index dab6e0d..1837c76 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,9 +5,12 @@
2006-01-30 Miklos Szeredi <miklos@szeredi.hu>
* Fix data consitency bug if readahead is enabled and writes are
- intermixed with reads. Only fixed for the case when reads and
- writes are performed on the same file handle. Bug reported and
- test program written by Wolfgang Köbler
+ intermixed with reads. Solution is far from optimal, since it
+ will prevent readahead in the above situation. If used with FUSE
+ >= 2.6.0 with Linux-2.6.X, readahead will be done by the kernel,
+ and hence there will be no performance penalty. Bug reported and
+ test program written by Wolfgang Köbler. Further testing on
+ FreeBSD by Csaba Henk
2006-01-29 Miklos Szeredi <miklos@szeredi.hu>
diff --git a/Makefile.am b/Makefile.am
index 8c0ca99..72aa75d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,7 +7,9 @@ if FUSE_OPT_COMPAT
sshfs_SOURCES += compat/fuse_opt.c compat/fuse_opt.h
endif
-sshfs_CPPFLAGS = -DFUSE_USE_VERSION=26 -DLIBDIR=\"$(libdir)\"
+sshfs_LDADD = $(SSHFS_LIBS)
+sshfs_CFLAGS = $(SSHFS_CFLAGS)
+sshfs_CPPFLAGS = -D_REENTRANT -DFUSE_USE_VERSION=26 -DLIBDIR=\"$(libdir)\"
EXTRA_DIST = sshnodelay.c
CLEANFILES = sshnodelay.so
diff --git a/configure.ac b/configure.ac
index bcb6ca4..b3eb52c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,15 +3,15 @@ AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
AC_PROG_CC
+CFLAGS="$CFLAGS -Wall -W"
LIBS=
AC_SEARCH_LIBS(dlsym, [dl])
sshnodelay_libs=$LIBS
AC_SUBST(sshnodelay_libs)
+LIBS=
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
PKG_CHECK_MODULES(SSHFS, [fuse >= 2.2 glib-2.0])
-CFLAGS="$CFLAGS -Wall -W -D_REENTRANT $SSHFS_CFLAGS"
-LIBS="$SSHFS_LIBS"
have_fuse_opt_parse=no
AC_CHECK_FUNC([fuse_opt_parse], [have_fuse_opt_parse=yes])
if test "$have_fuse_opt_parse" = no; then
diff --git a/sshfs.c b/sshfs.c
index e0ce4bf..18da591 100644
--- a/sshfs.c
+++ b/sshfs.c
@@ -134,7 +134,7 @@ struct read_chunk {
struct buffer data;
int refs;
int res;
- int filever;
+ long modifver;
};
struct sshfs_file {
@@ -146,7 +146,7 @@ struct sshfs_file {
off_t next_pos;
int is_seq;
int connver;
- int filever;
+ int modifver;
};
struct sshfs {
@@ -169,6 +169,7 @@ struct sshfs {
char *base_path;
GHashTable *reqtab;
pthread_mutex_t lock;
+ pthread_mutex_t lock_write;
int processing_thread_started;
unsigned int randseed;
int infd;
@@ -180,6 +181,7 @@ struct sshfs {
int remote_uid_detected;
unsigned blksize;
char *progname;
+ long modifver;
};
static struct sshfs sshfs;
@@ -805,7 +807,9 @@ static int sftp_send(uint8_t type, struct buffer *buf)
buf_add_uint8(&buf2, type);
buf_to_iov(&buf2, &iov[0]);
buf_to_iov(buf, &iov[1]);
+ pthread_mutex_lock(&sshfs.lock_write);
res = do_write(iov, 2);
+ pthread_mutex_unlock(&sshfs.lock_write);
buf_free(&buf2);
return res;
}
@@ -1138,14 +1142,15 @@ static int sftp_request_common(uint8_t type, const struct buffer *buf,
g_hash_table_insert(sshfs.reqtab, GUINT_TO_POINTER(id), req);
gettimeofday(&req->start, NULL);
DEBUG("[%05i] %s\n", id, type_name(type));
+ pthread_mutex_unlock(&sshfs.lock);
err = -EIO;
if (sftp_send(type, &buf2) == -1) {
+ pthread_mutex_lock(&sshfs.lock);
g_hash_table_remove(sshfs.reqtab, GUINT_TO_POINTER(id));
pthread_mutex_unlock(&sshfs.lock);
goto out;
}
- pthread_mutex_unlock(&sshfs.lock);
if (expect_type == 0) {
buf_free(&buf2);
@@ -1524,6 +1529,8 @@ static int sshfs_truncate(const char *path, off_t size)
{
int err;
struct buffer buf;
+
+ sshfs.modifver ++;
buf_init(&buf, 0);
buf_add_path(&buf, path);
if (size == 0) {
@@ -1600,6 +1607,7 @@ static int sshfs_open_common(const char *path, mode_t mode,
/* Assume random read after open */
sf->is_seq = 0;
sf->next_pos = 0;
+ sf->modifver= sshfs.modifver;
sf->connver = sshfs.connver;
buf_init(&buf, 0);
buf_add_path(&buf, path);
@@ -1773,7 +1781,7 @@ static int submit_read(struct sshfs_file *sf, size_t size, off_t offset,
chunk->offset = offset;
chunk->size = size;
chunk->refs = 1;
- chunk->filever = sf->filever;
+ chunk->modifver = sshfs.modifver;
err = sshfs_send_async_read(sf, chunk);
if (!err) {
pthread_mutex_lock(&sshfs.lock);
@@ -1807,7 +1815,7 @@ static int wait_chunk(struct read_chunk *chunk, char *buf, size_t size)
static struct read_chunk *search_read_chunk(struct sshfs_file *sf, off_t offset)
{
struct read_chunk *ch = sf->readahead;
- if (ch && ch->offset == offset && ch->filever == sf->filever) {
+ if (ch && ch->offset == offset && ch->modifver == sshfs.modifver) {
ch->refs++;
return ch;
} else
@@ -1826,8 +1834,9 @@ static int sshfs_async_read(struct sshfs_file *sf, char *rbuf, size_t size,
pthread_mutex_lock(&sshfs.lock);
curr_is_seq = sf->is_seq;
- sf->is_seq = (sf->next_pos == offset);
+ sf->is_seq = (sf->next_pos == offset && sf->modifver == sshfs.modifver);
sf->next_pos = offset + size;
+ sf->modifver = sshfs.modifver;
chunk = search_read_chunk(sf, offset);
pthread_mutex_unlock(&sshfs.lock);
@@ -1915,7 +1924,7 @@ static int sshfs_write(const char *path, const char *wbuf, size_t size,
if (!sshfs_file_is_conn(sf))
return -EIO;
- sf->filever ++;
+ sshfs.modifver ++;
data.p = (uint8_t *) wbuf;
data.len = size;
buf_init(&buf, 0);
@@ -1981,6 +1990,7 @@ static int sshfs_ftruncate(const char *path, off_t size,
if (!sshfs_file_is_conn(sf))
return -EIO;
+ sshfs.modifver ++;
buf_init(&buf, 0);
buf_add_buf(&buf, &sf->handle);
buf_add_uint32(&buf, SSH_FILEXFER_ATTR_SIZE);
@@ -2020,6 +2030,7 @@ static int sshfs_fgetattr(const char *path, struct stat *stbuf,
static int processing_init(void)
{
pthread_mutex_init(&sshfs.lock, NULL);
+ pthread_mutex_init(&sshfs.lock_write, NULL);
sshfs.reqtab = g_hash_table_new(NULL, NULL);
if (!sshfs.reqtab) {
fprintf(stderr, "failed to create hash table\n");