aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2006-03-17 15:56:05 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2006-03-17 15:56:05 +0000
commit8d975f6fb3f54c82f295b5e44391637a7c008345 (patch)
treeb86bb953018aaf573bb88df08cd48df97bc02d75 /lib
parent6f385414b27e929bd14435ea8342cde4bae0ef8d (diff)
fix
Diffstat (limited to 'lib')
-rw-r--r--lib/fuse.c2
-rw-r--r--lib/fuse_kern_chan.c24
-rw-r--r--lib/fuse_loop.c5
-rw-r--r--lib/fuse_loop_mt.c48
-rw-r--r--lib/fuse_lowlevel.c1
-rw-r--r--lib/fuse_mt.c4
-rw-r--r--lib/fuse_session.c39
-rw-r--r--lib/fuse_versionscript2
8 files changed, 87 insertions, 38 deletions
diff --git a/lib/fuse.c b/lib/fuse.c
index 82e0e44..dc1ab10 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -1881,7 +1881,7 @@ struct fuse_cmd *fuse_read_cmd(struct fuse *f)
size_t bufsize = fuse_chan_bufsize(ch);
struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize);
if (cmd != NULL) {
- int res = fuse_chan_recv(ch, cmd->buf, bufsize);
+ int res = fuse_chan_recv(&ch, cmd->buf, bufsize);
if (res <= 0) {
free_cmd(cmd);
if (res < 0 && res != -EINTR && res != -EAGAIN)
diff --git a/lib/fuse_kern_chan.c b/lib/fuse_kern_chan.c
index fe7d252..45ff738 100644
--- a/lib/fuse_kern_chan.c
+++ b/lib/fuse_kern_chan.c
@@ -14,8 +14,10 @@
#include <unistd.h>
#include <assert.h>
-static int fuse_kern_chan_receive(struct fuse_chan *ch, char *buf, size_t size)
+static int fuse_kern_chan_receive(struct fuse_chan **chp, char *buf,
+ size_t size)
{
+ struct fuse_chan *ch = *chp;
int err;
ssize_t res;
struct fuse_session *se = fuse_chan_session(ch);
@@ -50,18 +52,20 @@ static int fuse_kern_chan_receive(struct fuse_chan *ch, char *buf, size_t size)
static int fuse_kern_chan_send(struct fuse_chan *ch, const struct iovec iov[],
size_t count)
{
- ssize_t res = writev(fuse_chan_fd(ch), iov, count);
- int err = errno;
+ if (iov) {
+ ssize_t res = writev(fuse_chan_fd(ch), iov, count);
+ int err = errno;
- if (res == -1) {
- struct fuse_session *se = fuse_chan_session(ch);
+ if (res == -1) {
+ struct fuse_session *se = fuse_chan_session(ch);
- assert(se != NULL);
+ assert(se != NULL);
- /* ENOENT means the operation was interrupted */
- if (!fuse_session_exited(se) && err != ENOENT)
- perror("fuse: writing device");
- return -err;
+ /* ENOENT means the operation was interrupted */
+ if (!fuse_session_exited(se) && err != ENOENT)
+ perror("fuse: writing device");
+ return -err;
+ }
}
return 0;
}
diff --git a/lib/fuse_loop.c b/lib/fuse_loop.c
index 6a6edaa..af85269 100644
--- a/lib/fuse_loop.c
+++ b/lib/fuse_loop.c
@@ -24,12 +24,13 @@ int fuse_session_loop(struct fuse_session *se)
}
while (!fuse_session_exited(se)) {
- res = fuse_chan_recv(ch, buf, bufsize);
+ struct fuse_chan *tmpch = ch;
+ res = fuse_chan_recv(&tmpch, buf, bufsize);
if (res == -EINTR)
continue;
if (res <= 0)
break;
- fuse_session_process(se, buf, res, ch);
+ fuse_session_process(se, buf, res, tmpch);
}
free(buf);
diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c
index 16be149..fc8f892 100644
--- a/lib/fuse_loop_mt.c
+++ b/lib/fuse_loop_mt.c
@@ -24,7 +24,6 @@ struct fuse_worker {
int numworker;
int numavail;
struct fuse_session *se;
- struct fuse_chan *ch;
struct fuse_chan *prevch;
pthread_t threads[FUSE_MAX_WORKERS];
pthread_t main_thread;
@@ -32,6 +31,11 @@ struct fuse_worker {
int error;
};
+struct fuse_wchan {
+ struct fuse_worker *w;
+ struct fuse_chan *prevch;
+};
+
#ifndef USE_UCLIBC
#define mutex_init(mut) pthread_mutex_init(mut, NULL)
#else
@@ -48,11 +52,15 @@ static void mutex_init(pthread_mutex_t *mut)
static int fuse_loop_mt_send(struct fuse_chan *ch, const struct iovec iov[],
size_t count)
{
- struct fuse_worker *w = (struct fuse_worker *) fuse_chan_data(ch);
- pthread_mutex_lock(&w->lock);
- w->numavail ++;
- pthread_mutex_unlock(&w->lock);
- return fuse_chan_send(w->prevch, iov, count);
+ int res;
+ struct fuse_wchan *wchan_data = (struct fuse_wchan *) fuse_chan_data(ch);
+ pthread_mutex_lock(&wchan_data->w->lock);
+ wchan_data->w->numavail ++;
+ pthread_mutex_unlock(&wchan_data->w->lock);
+ res = fuse_chan_send(wchan_data->prevch, iov, count);
+ fuse_chan_destroy(ch);
+ free(wchan_data);
+ return res;
}
static int start_thread(struct fuse_worker *w, pthread_t *thread_id);
@@ -74,7 +82,11 @@ static void *do_work(void *data)
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
while (!fuse_session_exited(w->se)) {
- int res = fuse_chan_recv(w->prevch, buf, bufsize);
+ struct fuse_chan *ch = w->prevch;
+ struct fuse_chan *wchan;
+ struct fuse_wchan *wchan_data;
+ struct fuse_chan_ops cop = { .send = fuse_loop_mt_send };
+ int res = fuse_chan_recv(&ch, buf, bufsize);
if (res == -EINTR)
continue;
if (res <= 0) {
@@ -105,7 +117,17 @@ static void *do_work(void *data)
}
}
pthread_mutex_unlock(&w->lock);
- fuse_session_process(w->se, buf, res, w->ch);
+ wchan_data = malloc(sizeof(struct fuse_wchan));
+ wchan = fuse_chan_new(&cop, -1, fuse_chan_bufsize(ch), wchan_data);
+ if (!wchan_data || !wchan) {
+ free(wchan_data);
+ fuse_session_exit(w->se);
+ w->error = -1;
+ break;
+ }
+ wchan_data->w = w;
+ wchan_data->prevch = ch;
+ fuse_session_process(w->se, buf, res, wchan);
}
pthread_cleanup_pop(1);
@@ -145,10 +167,6 @@ int fuse_session_loop_mt(struct fuse_session *se)
int i;
int err;
struct fuse_worker *w;
- struct fuse_chan_ops cop = {
- .send = fuse_loop_mt_send,
- };
-
w = (struct fuse_worker *) malloc(sizeof(struct fuse_worker));
if (w == NULL) {
fprintf(stderr, "fuse: failed to allocate worker structure\n");
@@ -157,11 +175,6 @@ int fuse_session_loop_mt(struct fuse_session *se)
memset(w, 0, sizeof(struct fuse_worker));
w->se = se;
w->prevch = fuse_session_next_chan(se, NULL);
- w->ch = fuse_chan_new(&cop, -1, fuse_chan_bufsize(w->prevch), w);
- if (w->ch == NULL) {
- free(w);
- return -1;
- }
w->error = 0;
w->numworker = 1;
w->numavail = 1;
@@ -179,7 +192,6 @@ int fuse_session_loop_mt(struct fuse_session *se)
pthread_join(w->threads[i], NULL);
pthread_mutex_destroy(&w->lock);
err = w->error;
- fuse_chan_destroy(w->ch);
free(w);
fuse_session_reset(se);
return err;
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index c6b7db8..7b5cb7b 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -223,6 +223,7 @@ int fuse_reply_err(fuse_req_t req, int err)
void fuse_reply_none(fuse_req_t req)
{
+ fuse_chan_send(req->ch, NULL, 0);
free_req(req);
}
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index 8a8964f..b0b31dd 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -104,10 +104,10 @@ static int mt_session_exited(void *data)
return fuse_session_exited(pd->prevse);
}
-static int mt_chan_receive(struct fuse_chan *ch, char *buf, size_t size)
+static int mt_chan_receive(struct fuse_chan **chp, char *buf, size_t size)
{
struct fuse_cmd *cmd;
- struct procdata *pd = (struct procdata *) fuse_chan_data(ch);
+ struct procdata *pd = (struct procdata *) fuse_chan_data(*chp);
assert(size >= sizeof(cmd));
diff --git a/lib/fuse_session.c b/lib/fuse_session.c
index 040645b..6cfd462 100644
--- a/lib/fuse_session.c
+++ b/lib/fuse_session.c
@@ -7,6 +7,7 @@
*/
#include "fuse_lowlevel.h"
+#include "fuse_lowlevel_compat.h"
#include <stdio.h>
#include <stdlib.h>
@@ -34,6 +35,8 @@ struct fuse_chan {
size_t bufsize;
void *data;
+
+ int compat;
};
struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data)
@@ -116,8 +119,8 @@ int fuse_session_exited(struct fuse_session *se)
return se->exited;
}
-struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
- size_t bufsize, void *data)
+struct fuse_chan *fuse_chan_new_common(struct fuse_chan_ops *op, int fd,
+ size_t bufsize, void *data, int compat)
{
struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch));
if (ch == NULL) {
@@ -130,10 +133,24 @@ struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
ch->fd = fd;
ch->bufsize = bufsize;
ch->data = data;
+ ch->compat = compat;
return ch;
}
+struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
+ size_t bufsize, void *data)
+{
+ return fuse_chan_new_common(op, fd, bufsize, data, 0);
+}
+
+struct fuse_chan *fuse_chan_new_compat24(struct fuse_chan_ops_compat24 *op,
+ int fd, size_t bufsize, void *data)
+{
+ return fuse_chan_new_common((struct fuse_chan_ops *) op, fd, bufsize,
+ data, 24);
+}
+
int fuse_chan_fd(struct fuse_chan *ch)
{
return ch->fd;
@@ -154,14 +171,22 @@ struct fuse_session *fuse_chan_session(struct fuse_chan *ch)
return ch->se;
}
-int fuse_chan_recv(struct fuse_chan *ch, char *buf, size_t size)
+int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size)
{
- return ch->op.receive(ch, buf, size);
+ struct fuse_chan *ch = *chp;
+ if (ch->compat)
+ return ((struct fuse_chan_ops_compat24 *) &ch->op)
+ ->receive(ch, buf, size);
+ else
+ return ch->op.receive(chp, buf, size);
}
int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size)
{
- int res = fuse_chan_recv(ch, buf, size);
+ int res;
+
+ assert(ch->compat);
+ res = fuse_chan_recv(&ch, buf, size);
return res >= 0 ? res : (res != -EINTR && res != -EAGAIN) ? -1 : 0;
}
@@ -177,3 +202,7 @@ void fuse_chan_destroy(struct fuse_chan *ch)
ch->op.destroy(ch);
free(ch);
}
+
+#ifndef __FreeBSD__
+__asm__(".symver fuse_chan_new_compat24,fuse_chan_new@FUSE_2.4");
+#endif
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
index 467d870..147067f 100644
--- a/lib/fuse_versionscript
+++ b/lib/fuse_versionscript
@@ -83,6 +83,8 @@ FUSE_2.5 {
FUSE_2.6 {
global:
fuse_add_direntry;
+ fuse_chan_new;
+ fuse_chan_new_compat24;
fuse_daemonize;
fuse_get_session;
fuse_lowlevel_new;