mirror of
https://github.com/libfuse/libfuse.git
synced 2024-11-23 12:14:15 +08:00
fix
This commit is contained in:
parent
6f385414b2
commit
8d975f6fb3
@ -16,6 +16,9 @@
|
||||
* new exported functions: fuse_session_remove_chan(),
|
||||
fuse_get_session(), fuse_daemonize()
|
||||
|
||||
* fuse_chan_recv() may now return a new channel which will be used
|
||||
to send the reply
|
||||
|
||||
2006-03-16 Miklos Szeredi <miklos@szeredi.hu>
|
||||
|
||||
* Released 2.6.0-pre2
|
||||
|
@ -1102,12 +1102,12 @@ struct fuse_chan_ops {
|
||||
/**
|
||||
* Hook for receiving a raw request
|
||||
*
|
||||
* @param ch the channel
|
||||
* @param ch pointer to the channel
|
||||
* @param buf the buffer to store the request in
|
||||
* @param size the size of the buffer
|
||||
* @return the actual size of the raw request, or -1 on error
|
||||
*/
|
||||
int (*receive)(struct fuse_chan *ch, char *buf, size_t size);
|
||||
int (*receive)(struct fuse_chan **chp, char *buf, size_t size);
|
||||
|
||||
/**
|
||||
* Hook for sending a raw reply
|
||||
@ -1120,8 +1120,7 @@ struct fuse_chan_ops {
|
||||
* @param count the number of blocks in vector
|
||||
* @return zero on success, -errno on failure
|
||||
*/
|
||||
int (*send)(struct fuse_chan *ch, const struct iovec iov[],
|
||||
size_t count);
|
||||
int (*send)(struct fuse_chan *ch, const struct iovec iov[], size_t count);
|
||||
|
||||
/**
|
||||
* Destroy the channel
|
||||
@ -1180,12 +1179,12 @@ struct fuse_session *fuse_chan_session(struct fuse_chan *ch);
|
||||
*
|
||||
* A return value of -ENODEV means, that the filesystem was unmounted
|
||||
*
|
||||
* @param ch the channel
|
||||
* @param ch pointer to the channel
|
||||
* @param buf the buffer to store the request in
|
||||
* @param size the size of the buffer
|
||||
* @return the actual size of the raw request, or -errno on error
|
||||
*/
|
||||
int fuse_chan_recv(struct fuse_chan *ch, char *buf, size_t size);
|
||||
int fuse_chan_recv(struct fuse_chan **ch, char *buf, size_t size);
|
||||
|
||||
/**
|
||||
* Send a raw reply
|
||||
@ -1218,6 +1217,8 @@ void fuse_chan_destroy(struct fuse_chan *ch);
|
||||
# if FUSE_USE_VERSION == 25
|
||||
# define fuse_lowlevel_ops fuse_lowlevel_ops_compat25
|
||||
# define fuse_lowlevel_new fuse_lowlevel_new_compat25
|
||||
# define fuse_chan_ops fuse_chan_ops_compat25
|
||||
# define fuse_chan_new fuse_chan_new_compat25
|
||||
# elif FUSE_USE_VERSION == 24
|
||||
# define fuse_file_info fuse_file_info_compat
|
||||
# define fuse_reply_statfs fuse_reply_statfs_compat
|
||||
|
@ -88,6 +88,16 @@ struct fuse_session *fuse_lowlevel_new_compat(const char *opts,
|
||||
const struct fuse_lowlevel_ops *op,
|
||||
size_t op_size, void *userdata);
|
||||
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
struct fuse_chan_ops_compat24 {
|
||||
int (*receive)(struct fuse_chan *ch, char *buf, size_t size);
|
||||
int (*send)(struct fuse_chan *ch, const struct iovec iov[], size_t count);
|
||||
void (*destroy)(struct fuse_chan *ch);
|
||||
};
|
||||
|
||||
struct fuse_chan *fuse_chan_new_compat24(struct fuse_chan_ops_compat24 *op,
|
||||
int fd, size_t bufsize, void *data);
|
||||
|
||||
int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size);
|
||||
|
||||
#endif /* __FreeBSD__ */
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user