aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-09-29 14:22:54 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2006-09-29 14:22:54 +0000
commit09d5ee2eeea3d4315b04e1f7793fd56f4ffd24a7 (patch)
tree83139f379dea48d867b96df65473177749eda37f
parentb917f9a42086724158f43a4097e7810f3f73ee75 (diff)
downloadsshfs-09d5ee2eeea3d4315b04e1f7793fd56f4ffd24a7.tar
sshfs-09d5ee2eeea3d4315b04e1f7793fd56f4ffd24a7.tar.gz
sshfs-09d5ee2eeea3d4315b04e1f7793fd56f4ffd24a7.tar.bz2
sshfs-09d5ee2eeea3d4315b04e1f7793fd56f4ffd24a7.zip
fix segfault
-rw-r--r--ChangeLog6
-rw-r--r--sshfs.c20
2 files changed, 24 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 08f82ae..0f793d2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-09-29 Miklos Szeredi <miklos@szeredi.hu>
+
+ * Fix segfault if there are outstanding writes to the server after
+ release on the file descriptor. The only happened on FreeBSD.
+ Reported by Andriy Gapon
+
2006-08-18 Miklos Szeredi <miklos@szeredi.hu>
* Released 1.7
diff --git a/sshfs.c b/sshfs.c
index abbd710..eb5dce4 100644
--- a/sshfs.c
+++ b/sshfs.c
@@ -147,6 +147,7 @@ struct sshfs_file {
int is_seq;
int connver;
int modifver;
+ int refs;
};
struct sshfs {
@@ -1768,6 +1769,7 @@ static int sshfs_open_common(const char *path, mode_t mode,
pthread_cond_init(&sf->write_finished, NULL);
/* Assume random read after open */
sf->is_seq = 0;
+ sf->refs = 1;
sf->next_pos = 0;
sf->modifver= sshfs.modifver;
sf->connver = sshfs.connver;
@@ -1851,6 +1853,19 @@ static int sshfs_fsync(const char *path, int isdatasync,
return sshfs_flush(path, fi);
}
+static void sshfs_file_put(struct sshfs_file *sf)
+{
+ sf->refs--;
+ if (!sf->refs)
+ g_free(sf);
+}
+
+static struct sshfs_file *sshfs_file_get(struct sshfs_file *sf)
+{
+ sf->refs++;
+ return sf;
+}
+
static int sshfs_release(const char *path, struct fuse_file_info *fi)
{
struct sshfs_file *sf = get_sshfs_file(fi);
@@ -1861,7 +1876,7 @@ static int sshfs_release(const char *path, struct fuse_file_info *fi)
}
buf_free(handle);
chunk_put_locked(sf->readahead);
- g_free(sf);
+ sshfs_file_put(sf);
return 0;
}
@@ -2084,6 +2099,7 @@ static void sshfs_write_end(struct request *req)
}
list_del(&req->list);
pthread_cond_broadcast(&sf->write_finished);
+ sshfs_file_put(sf);
}
static int sshfs_write(const char *path, const char *wbuf, size_t size,
@@ -2110,7 +2126,7 @@ static int sshfs_write(const char *path, const char *wbuf, size_t size,
iov[1].iov_len = size;
if (!sshfs.sync_write && !sf->write_error)
err = sftp_request_send(SSH_FXP_WRITE, iov, 2, sshfs_write_begin,
- sshfs_write_end, 0, sf, NULL);
+ sshfs_write_end, 0, sshfs_file_get(sf), NULL);
else
err = sftp_request_iov(SSH_FXP_WRITE, iov, 2, SSH_FXP_STATUS, NULL);
buf_free(&buf);