mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-04-26 15:04:04 +08:00
Merge pull request #1091 from trapexit/cleanup
Remove unnecessary libfuse abstractions
This commit is contained in:
commit
fea499e220
3547
libfuse/ChangeLog
3547
libfuse/ChangeLog
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,6 @@ SRC = \
|
|||||||
lib/debug.c \
|
lib/debug.c \
|
||||||
lib/fuse.c \
|
lib/fuse.c \
|
||||||
lib/fuse_dirents.c \
|
lib/fuse_dirents.c \
|
||||||
lib/fuse_kern_chan.c \
|
|
||||||
lib/fuse_loop_mt.c \
|
lib/fuse_loop_mt.c \
|
||||||
lib/fuse_lowlevel.c \
|
lib/fuse_lowlevel.c \
|
||||||
lib/fuse_mt.c \
|
lib/fuse_mt.c \
|
||||||
|
@ -1503,231 +1503,29 @@ struct fuse_session *fuse_lowlevel_new(struct fuse_args *args,
|
|||||||
* Session interface *
|
* Session interface *
|
||||||
* ----------------------------------------------------------- */
|
* ----------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
struct fuse_session *fuse_session_new(void *data,
|
||||||
* Session operations
|
void *receive_buf,
|
||||||
*
|
void *process_buf,
|
||||||
* This is used in session creation
|
void *destroy);
|
||||||
*/
|
|
||||||
struct fuse_session_ops
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Hook to process a request (mandatory)
|
|
||||||
*
|
|
||||||
* @param data user data passed to fuse_session_new()
|
|
||||||
* @param buf buffer containing the raw request
|
|
||||||
* @param len request length
|
|
||||||
* @param ch channel on which the request was received
|
|
||||||
*/
|
|
||||||
void (*process)(void *data, const char *buf, size_t len,
|
|
||||||
struct fuse_chan *ch);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook for session exit and reset (optional)
|
|
||||||
*
|
|
||||||
* @param data user data passed to fuse_session_new()
|
|
||||||
* @param val exited status (1 - exited, 0 - not exited)
|
|
||||||
*/
|
|
||||||
void (*exit)(void *data, int val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook for querying the current exited status (optional)
|
|
||||||
*
|
|
||||||
* @param data user data passed to fuse_session_new()
|
|
||||||
* @return 1 if exited, 0 if not exited
|
|
||||||
*/
|
|
||||||
int (*exited)(void *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook for cleaning up the channel on destroy (optional)
|
|
||||||
*
|
|
||||||
* @param data user data passed to fuse_session_new()
|
|
||||||
*/
|
|
||||||
void (*destroy)(void *data);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new session
|
|
||||||
*
|
|
||||||
* @param op session operations
|
|
||||||
* @param data user data
|
|
||||||
* @return new session object, or NULL on failure
|
|
||||||
*/
|
|
||||||
struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assign a channel to a session
|
|
||||||
*
|
|
||||||
* Note: currently only a single channel may be assigned. This may
|
|
||||||
* change in the future
|
|
||||||
*
|
|
||||||
* If a session is destroyed, the assigned channel is also destroyed
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
* @param ch the channel
|
|
||||||
*/
|
|
||||||
void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch);
|
void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch);
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a channel from a session
|
|
||||||
*
|
|
||||||
* If the channel is not assigned to a session, then this is a no-op
|
|
||||||
*
|
|
||||||
* @param ch the channel to remove
|
|
||||||
*/
|
|
||||||
void fuse_session_remove_chan(struct fuse_chan *ch);
|
void fuse_session_remove_chan(struct fuse_chan *ch);
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterate over the channels assigned to a session
|
|
||||||
*
|
|
||||||
* The iterating function needs to start with a NULL channel, and
|
|
||||||
* after that needs to pass the previously returned channel to the
|
|
||||||
* function.
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
* @param ch the previous channel, or NULL
|
|
||||||
* @return the next channel, or NULL if no more channels exist
|
|
||||||
*/
|
|
||||||
struct fuse_chan *fuse_session_next_chan(struct fuse_session *se,
|
|
||||||
struct fuse_chan *ch);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a raw request
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
* @param buf buffer containing the raw request
|
|
||||||
* @param len request length
|
|
||||||
* @param ch channel on which the request was received
|
|
||||||
*/
|
|
||||||
void fuse_session_process(struct fuse_session *se, const char *buf, size_t len,
|
|
||||||
struct fuse_chan *ch);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a raw request supplied in a generic buffer
|
|
||||||
*
|
|
||||||
* This is a more generic version of fuse_session_process(). The
|
|
||||||
* fuse_buf may contain a memory buffer or a pipe file descriptor.
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
* @param buf the fuse_buf containing the request
|
|
||||||
* @param ch channel on which the request was received
|
|
||||||
*/
|
|
||||||
void fuse_session_process_buf(struct fuse_session *se,
|
|
||||||
const struct fuse_buf *buf, struct fuse_chan *ch);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receive a raw request supplied in a generic buffer
|
|
||||||
*
|
|
||||||
* This is a more generic version of fuse_chan_recv(). The fuse_buf
|
|
||||||
* supplied to this function contains a suitably allocated memory
|
|
||||||
* buffer. This may be overwritten with a file descriptor buffer.
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
* @param buf the fuse_buf to store the request in
|
|
||||||
* @param chp pointer to the channel
|
|
||||||
* @return the actual size of the raw request, or -errno on error
|
|
||||||
*/
|
|
||||||
int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
|
|
||||||
struct fuse_chan **chp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy a session
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
*/
|
|
||||||
void fuse_session_destroy(struct fuse_session *se);
|
void fuse_session_destroy(struct fuse_session *se);
|
||||||
|
|
||||||
/**
|
|
||||||
* Exit a session
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
*/
|
|
||||||
void fuse_session_exit(struct fuse_session *se);
|
void fuse_session_exit(struct fuse_session *se);
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the exited status of a session
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
*/
|
|
||||||
void fuse_session_reset(struct fuse_session *se);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query the exited status of a session
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
* @return 1 if exited, 0 if not exited
|
|
||||||
*/
|
|
||||||
int fuse_session_exited(struct fuse_session *se);
|
int fuse_session_exited(struct fuse_session *se);
|
||||||
|
void fuse_session_reset(struct fuse_session *se);
|
||||||
/**
|
|
||||||
* Get the user data provided to the session
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
* @return the user data
|
|
||||||
*/
|
|
||||||
void *fuse_session_data(struct fuse_session *se);
|
void *fuse_session_data(struct fuse_session *se);
|
||||||
|
int fuse_session_receive(struct fuse_session *se,
|
||||||
|
struct fuse_buf *buf);
|
||||||
|
void fuse_session_process(struct fuse_session *se,
|
||||||
|
const struct fuse_buf *buf);
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter a multi-threaded event loop
|
|
||||||
*
|
|
||||||
* @param se the session
|
|
||||||
* @return 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int fuse_session_loop_mt(struct fuse_session *se, const int threads);
|
int fuse_session_loop_mt(struct fuse_session *se, const int threads);
|
||||||
|
|
||||||
/* ----------------------------------------------------------- *
|
/* ----------------------------------------------------------- *
|
||||||
* Channel interface *
|
* Channel interface *
|
||||||
* ----------------------------------------------------------- */
|
* ----------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
struct fuse_chan *fuse_chan_new(int fd, size_t bufsize);
|
||||||
* Channel operations
|
|
||||||
*
|
|
||||||
* This is used in channel creation
|
|
||||||
*/
|
|
||||||
struct fuse_chan_ops
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Hook for receiving a raw request
|
|
||||||
*
|
|
||||||
* @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 **chp, char *buf, size_t size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook for sending a raw reply
|
|
||||||
*
|
|
||||||
* A return value of -ENOENT means, that the request was
|
|
||||||
* interrupted, and the reply was discarded
|
|
||||||
*
|
|
||||||
* @param ch the channel
|
|
||||||
* @param iov vector of blocks
|
|
||||||
* @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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy the channel
|
|
||||||
*
|
|
||||||
* @param ch the channel
|
|
||||||
*/
|
|
||||||
void (*destroy)(struct fuse_chan *ch);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new channel
|
|
||||||
*
|
|
||||||
* @param op channel operations
|
|
||||||
* @param fd file descriptor of the channel
|
|
||||||
* @param bufsize the minimal receive buffer size
|
|
||||||
* @param data user data
|
|
||||||
* @return the new channel object, or NULL on failure
|
|
||||||
*/
|
|
||||||
struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
|
|
||||||
size_t bufsize, void *data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query the file descriptor of the channel
|
* Query the file descriptor of the channel
|
||||||
@ -1761,37 +1559,12 @@ void *fuse_chan_data(struct fuse_chan *ch);
|
|||||||
*/
|
*/
|
||||||
struct fuse_session *fuse_chan_session(struct fuse_chan *ch);
|
struct fuse_session *fuse_chan_session(struct fuse_chan *ch);
|
||||||
|
|
||||||
/**
|
int fuse_chan_recv(struct fuse_chan *ch,
|
||||||
* Receive a raw request
|
char *buf,
|
||||||
*
|
size_t size);
|
||||||
* A return value of -ENODEV means, that the filesystem was unmounted
|
int fuse_chan_send(struct fuse_chan *ch,
|
||||||
*
|
const struct iovec iov[],
|
||||||
* @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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a raw reply
|
|
||||||
*
|
|
||||||
* A return value of -ENOENT means, that the request was
|
|
||||||
* interrupted, and the reply was discarded
|
|
||||||
*
|
|
||||||
* @param ch the channel
|
|
||||||
* @param iov vector of blocks
|
|
||||||
* @param count the number of blocks in vector
|
|
||||||
* @return zero on success, -errno on failure
|
|
||||||
*/
|
|
||||||
int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[],
|
|
||||||
size_t count);
|
size_t count);
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy a channel
|
|
||||||
*
|
|
||||||
* @param ch the channel
|
|
||||||
*/
|
|
||||||
void fuse_chan_destroy(struct fuse_chan *ch);
|
void fuse_chan_destroy(struct fuse_chan *ch);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
@ -3817,14 +3817,6 @@ free_cmd(struct fuse_cmd *cmd)
|
|||||||
free(cmd);
|
free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
fuse_process_cmd(struct fuse *f,
|
|
||||||
struct fuse_cmd *cmd)
|
|
||||||
{
|
|
||||||
fuse_session_process(f->se,cmd->buf,cmd->buflen,cmd->ch);
|
|
||||||
free_cmd(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
fuse_exited(struct fuse *f)
|
fuse_exited(struct fuse *f)
|
||||||
{
|
{
|
||||||
@ -3863,13 +3855,13 @@ fuse_alloc_cmd(size_t bufsize)
|
|||||||
struct fuse_cmd*
|
struct fuse_cmd*
|
||||||
fuse_read_cmd(struct fuse *f)
|
fuse_read_cmd(struct fuse *f)
|
||||||
{
|
{
|
||||||
struct fuse_chan *ch = fuse_session_next_chan(f->se,NULL);
|
struct fuse_chan *ch = f->se->ch;
|
||||||
size_t bufsize = fuse_chan_bufsize(ch);
|
size_t bufsize = fuse_chan_bufsize(ch);
|
||||||
struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize);
|
struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize);
|
||||||
|
|
||||||
if(cmd != NULL)
|
if(cmd != NULL)
|
||||||
{
|
{
|
||||||
int res = fuse_chan_recv(&ch,cmd->buf,bufsize);
|
int res = fuse_chan_recv(ch,cmd->buf,bufsize);
|
||||||
if(res <= 0)
|
if(res <= 0)
|
||||||
{
|
{
|
||||||
free_cmd(cmd);
|
free_cmd(cmd);
|
||||||
@ -3887,7 +3879,7 @@ fuse_read_cmd(struct fuse *f)
|
|||||||
void
|
void
|
||||||
fuse_exit(struct fuse *f)
|
fuse_exit(struct fuse *f)
|
||||||
{
|
{
|
||||||
fuse_session_exit(f->se);
|
f->se->exited = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fuse_context*
|
struct fuse_context*
|
||||||
|
@ -16,18 +16,18 @@ struct fuse_ll;
|
|||||||
|
|
||||||
struct fuse_session
|
struct fuse_session
|
||||||
{
|
{
|
||||||
struct fuse_session_ops op;
|
int (*receive_buf)(struct fuse_session *se,
|
||||||
|
struct fuse_buf *buf,
|
||||||
|
struct fuse_chan *ch);
|
||||||
|
|
||||||
int (*receive_buf)(struct fuse_session *se, struct fuse_buf *buf,
|
void (*process_buf)(void *data,
|
||||||
struct fuse_chan **chp);
|
const struct fuse_buf *buf,
|
||||||
|
|
||||||
void (*process_buf)(void *data, const struct fuse_buf *buf,
|
|
||||||
struct fuse_chan *ch);
|
struct fuse_chan *ch);
|
||||||
|
|
||||||
|
void (*destroy)(void *data);
|
||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
volatile int exited;
|
volatile int exited;
|
||||||
|
|
||||||
struct fuse_chan *ch;
|
struct fuse_chan *ch;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
FUSE: Filesystem in Userspace
|
|
||||||
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
|
||||||
|
|
||||||
This program can be distributed under the terms of the GNU LGPLv2.
|
|
||||||
See the file COPYING.LIB
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "fuse_lowlevel.h"
|
|
||||||
#include "fuse_kernel.h"
|
|
||||||
#include "fuse_i.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
assert(se != NULL);
|
|
||||||
|
|
||||||
restart:
|
|
||||||
res = read(fuse_chan_fd(ch), buf, size);
|
|
||||||
err = errno;
|
|
||||||
|
|
||||||
if (fuse_session_exited(se))
|
|
||||||
return 0;
|
|
||||||
if (res == -1) {
|
|
||||||
/* ENOENT means the operation was interrupted, it's safe
|
|
||||||
to restart */
|
|
||||||
if (err == ENOENT)
|
|
||||||
goto restart;
|
|
||||||
|
|
||||||
if (err == ENODEV) {
|
|
||||||
fuse_session_exit(se);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* Errors occurring during normal operation: EINTR (read
|
|
||||||
interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem
|
|
||||||
umounted) */
|
|
||||||
if (err != EINTR && err != EAGAIN)
|
|
||||||
perror("fuse: reading device");
|
|
||||||
return -err;
|
|
||||||
}
|
|
||||||
if ((size_t) res < sizeof(struct fuse_in_header)) {
|
|
||||||
fprintf(stderr, "short read on fuse device\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fuse_kern_chan_send(struct fuse_chan *ch, const struct iovec iov[],
|
|
||||||
size_t count)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
assert(se != NULL);
|
|
||||||
|
|
||||||
/* ENOENT means the operation was interrupted */
|
|
||||||
if (!fuse_session_exited(se) && err != ENOENT)
|
|
||||||
perror("fuse: writing device");
|
|
||||||
return -err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fuse_kern_chan_destroy(struct fuse_chan *ch)
|
|
||||||
{
|
|
||||||
int fd = fuse_chan_fd(ch);
|
|
||||||
|
|
||||||
if (fd != -1)
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fuse_chan *
|
|
||||||
fuse_kern_chan_new(int fd_)
|
|
||||||
{
|
|
||||||
long pagesize;
|
|
||||||
size_t bufsize;
|
|
||||||
struct fuse_chan_ops op =
|
|
||||||
{
|
|
||||||
.receive = fuse_kern_chan_receive,
|
|
||||||
.send = fuse_kern_chan_send,
|
|
||||||
.destroy = fuse_kern_chan_destroy,
|
|
||||||
};
|
|
||||||
|
|
||||||
pagesize = sysconf(_SC_PAGESIZE);
|
|
||||||
|
|
||||||
bufsize = ((FUSE_MAX_MAX_PAGES * pagesize) + 0x1000);
|
|
||||||
|
|
||||||
return fuse_chan_new(&op, fd_, bufsize, NULL);
|
|
||||||
}
|
|
@ -37,7 +37,6 @@ struct fuse_worker
|
|||||||
struct fuse_mt
|
struct fuse_mt
|
||||||
{
|
{
|
||||||
struct fuse_session *se;
|
struct fuse_session *se;
|
||||||
struct fuse_chan *prevch;
|
|
||||||
struct fuse_worker main;
|
struct fuse_worker main;
|
||||||
sem_t finish;
|
sem_t finish;
|
||||||
int exit;
|
int exit;
|
||||||
@ -77,28 +76,29 @@ fuse_do_work(void *data)
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
struct fuse_buf fbuf;
|
struct fuse_buf fbuf;
|
||||||
struct fuse_chan *ch = mt->prevch;
|
|
||||||
|
|
||||||
fbuf = (struct fuse_buf){ .mem = w->buf,
|
fbuf = (struct fuse_buf){ .mem = w->buf,
|
||||||
.size = w->bufsize };
|
.size = w->bufsize };
|
||||||
|
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||||
res = fuse_session_receive_buf(mt->se, &fbuf, &ch);
|
res = fuse_session_receive(mt->se,&fbuf);
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
if(res == -EINTR)
|
if(res == -EINTR)
|
||||||
continue;
|
continue;
|
||||||
if(res <= 0) {
|
if(res <= 0)
|
||||||
if(res < 0) {
|
{
|
||||||
fuse_session_exit(mt->se);
|
if(res < 0)
|
||||||
mt->error = -1;
|
{
|
||||||
|
mt->se->exited = 1;
|
||||||
|
mt->error = -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mt->exit)
|
if(mt->exit)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
fuse_session_process_buf(mt->se, &fbuf, ch);
|
fuse_session_process(mt->se,&fbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
sem_post(&mt->finish);
|
sem_post(&mt->finish);
|
||||||
@ -144,7 +144,7 @@ static int fuse_loop_start_thread(struct fuse_mt *mt)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(w, 0, sizeof(struct fuse_worker));
|
memset(w, 0, sizeof(struct fuse_worker));
|
||||||
w->bufsize = fuse_chan_bufsize(mt->prevch);
|
w->bufsize = fuse_chan_bufsize(mt->se->ch);
|
||||||
w->buf = calloc(w->bufsize,1);
|
w->buf = calloc(w->bufsize,1);
|
||||||
w->mt = mt;
|
w->mt = mt;
|
||||||
if(!w->buf) {
|
if(!w->buf) {
|
||||||
@ -193,7 +193,6 @@ fuse_session_loop_mt(struct fuse_session *se_,
|
|||||||
|
|
||||||
memset(&mt,0,sizeof(struct fuse_mt));
|
memset(&mt,0,sizeof(struct fuse_mt));
|
||||||
mt.se = se_;
|
mt.se = se_;
|
||||||
mt.prevch = fuse_session_next_chan(se_,NULL);
|
|
||||||
mt.error = 0;
|
mt.error = 0;
|
||||||
mt.main.thread_id = pthread_self();
|
mt.main.thread_id = pthread_self();
|
||||||
mt.main.prev = mt.main.next = &mt.main;
|
mt.main.prev = mt.main.next = &mt.main;
|
||||||
|
@ -2515,21 +2515,6 @@ fuse_ll_process_buf(void *data,
|
|||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
void
|
|
||||||
fuse_ll_process(void *data,
|
|
||||||
const char *buf,
|
|
||||||
size_t len,
|
|
||||||
struct fuse_chan *ch)
|
|
||||||
{
|
|
||||||
struct fuse_buf fbuf = {
|
|
||||||
.mem = (void *) buf,
|
|
||||||
.size = len,
|
|
||||||
};
|
|
||||||
|
|
||||||
fuse_ll_process_buf(data, &fbuf, ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
KEY_HELP,
|
KEY_HELP,
|
||||||
KEY_VERSION,
|
KEY_VERSION,
|
||||||
@ -2652,11 +2637,9 @@ fuse_ll_pipe_destructor(void *data)
|
|||||||
#ifdef HAVE_SPLICE
|
#ifdef HAVE_SPLICE
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
fuse_ll_receive_buf(struct fuse_session *se,
|
fuse_ll_receive_buf(struct fuse_session *se,
|
||||||
struct fuse_buf *buf,
|
struct fuse_buf *buf)
|
||||||
struct fuse_chan **chp)
|
|
||||||
{
|
{
|
||||||
struct fuse_chan *ch = *chp;
|
|
||||||
struct fuse_ll *f = fuse_session_data(se);
|
struct fuse_ll *f = fuse_session_data(se);
|
||||||
size_t bufsize = buf->size;
|
size_t bufsize = buf->size;
|
||||||
struct fuse_ll_pipe *llp;
|
struct fuse_ll_pipe *llp;
|
||||||
@ -2687,27 +2670,27 @@ fuse_ll_receive_buf(struct fuse_session *se,
|
|||||||
goto fallback;
|
goto fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = splice(fuse_chan_fd(ch), NULL, llp->pipe[1], NULL, bufsize, 0);
|
res = splice(fuse_chan_fd(se->ch), NULL, llp->pipe[1], NULL, bufsize, 0);
|
||||||
err = errno;
|
err = errno;
|
||||||
|
|
||||||
if(fuse_session_exited(se))
|
if(fuse_session_exited(se))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (res == -1)
|
if(res == -1)
|
||||||
{
|
{
|
||||||
if (err == ENODEV)
|
if(err == ENODEV)
|
||||||
{
|
{
|
||||||
fuse_session_exit(se);
|
fuse_session_exit(se);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != EINTR && err != EAGAIN)
|
if(err != EINTR && err != EAGAIN)
|
||||||
perror("fuse: splice from device");
|
perror("fuse: splice from device");
|
||||||
|
|
||||||
return -err;
|
return -err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res < sizeof(struct fuse_in_header))
|
if(res < sizeof(struct fuse_in_header))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "short splice from fuse device\n");
|
fprintf(stderr, "short splice from fuse device\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@ -2755,7 +2738,7 @@ fuse_ll_receive_buf(struct fuse_session *se,
|
|||||||
return res;
|
return res;
|
||||||
|
|
||||||
fallback:
|
fallback:
|
||||||
res = fuse_chan_recv(chp, buf->mem, bufsize);
|
res = fuse_chan_recv(se->ch, buf->mem, bufsize);
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
@ -2766,13 +2749,12 @@ fuse_ll_receive_buf(struct fuse_session *se,
|
|||||||
#else
|
#else
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
fuse_ll_receive_buf(struct fuse_session *se,
|
fuse_ll_receive_buf(struct fuse_session *se,
|
||||||
struct fuse_buf *buf,
|
struct fuse_buf *buf)
|
||||||
struct fuse_chan **chp)
|
|
||||||
{
|
{
|
||||||
(void) se;
|
(void) se;
|
||||||
|
|
||||||
int res = fuse_chan_recv(chp, buf->mem, buf->size);
|
int res = fuse_chan_recv(se->ch, buf->mem, buf->size);
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
@ -2796,10 +2778,6 @@ fuse_lowlevel_new_common(struct fuse_args *args,
|
|||||||
int err;
|
int err;
|
||||||
struct fuse_ll *f;
|
struct fuse_ll *f;
|
||||||
struct fuse_session *se;
|
struct fuse_session *se;
|
||||||
struct fuse_session_ops sop = {
|
|
||||||
.process = fuse_ll_process,
|
|
||||||
.destroy = fuse_ll_destroy,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (sizeof(struct fuse_lowlevel_ops) < op_size)
|
if (sizeof(struct fuse_lowlevel_ops) < op_size)
|
||||||
{
|
{
|
||||||
@ -2835,13 +2813,13 @@ fuse_lowlevel_new_common(struct fuse_args *args,
|
|||||||
f->owner = getuid();
|
f->owner = getuid();
|
||||||
f->userdata = userdata;
|
f->userdata = userdata;
|
||||||
|
|
||||||
se = fuse_session_new(&sop, f);
|
se = fuse_session_new(f,
|
||||||
|
fuse_ll_receive_buf,
|
||||||
|
fuse_ll_process_buf,
|
||||||
|
fuse_ll_destroy);
|
||||||
if (!se)
|
if (!se)
|
||||||
goto out_key_destroy;
|
goto out_key_destroy;
|
||||||
|
|
||||||
se->receive_buf = fuse_ll_receive_buf;
|
|
||||||
se->process_buf = fuse_ll_process_buf;
|
|
||||||
|
|
||||||
return se;
|
return se;
|
||||||
|
|
||||||
out_key_destroy:
|
out_key_destroy:
|
||||||
|
@ -16,98 +16,8 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
struct procdata
|
int
|
||||||
{
|
fuse_loop_mt(struct fuse *f)
|
||||||
struct fuse *f;
|
|
||||||
struct fuse_chan *prevch;
|
|
||||||
struct fuse_session *prevse;
|
|
||||||
fuse_processor_t proc;
|
|
||||||
void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void mt_session_proc(void *data, const char *buf, size_t len,
|
|
||||||
struct fuse_chan *ch)
|
|
||||||
{
|
|
||||||
struct procdata *pd = (struct procdata *) data;
|
|
||||||
struct fuse_cmd *cmd = *(struct fuse_cmd **) buf;
|
|
||||||
|
|
||||||
(void) len;
|
|
||||||
(void) ch;
|
|
||||||
pd->proc(pd->f, cmd, pd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mt_session_exit(void *data, int val)
|
|
||||||
{
|
|
||||||
struct procdata *pd = (struct procdata *) data;
|
|
||||||
if (val)
|
|
||||||
fuse_session_exit(pd->prevse);
|
|
||||||
else
|
|
||||||
fuse_session_reset(pd->prevse);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mt_session_exited(void *data)
|
|
||||||
{
|
|
||||||
struct procdata *pd = (struct procdata *) data;
|
|
||||||
return fuse_session_exited(pd->prevse);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(*chp);
|
|
||||||
|
|
||||||
assert(size >= sizeof(cmd));
|
|
||||||
|
|
||||||
cmd = fuse_read_cmd(pd->f);
|
|
||||||
if (cmd == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
*(struct fuse_cmd **)buf = cmd;
|
|
||||||
|
|
||||||
return sizeof(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
struct procdata pd;
|
|
||||||
struct fuse_session *prevse = fuse_get_session(f);
|
|
||||||
struct fuse_session *se;
|
|
||||||
struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL);
|
|
||||||
struct fuse_chan *ch;
|
|
||||||
struct fuse_session_ops sop = {
|
|
||||||
.exit = mt_session_exit,
|
|
||||||
.exited = mt_session_exited,
|
|
||||||
.process = mt_session_proc,
|
|
||||||
};
|
|
||||||
struct fuse_chan_ops cop = {
|
|
||||||
.receive = mt_chan_receive,
|
|
||||||
};
|
|
||||||
|
|
||||||
pd.f = f;
|
|
||||||
pd.prevch = prevch;
|
|
||||||
pd.prevse = prevse;
|
|
||||||
pd.proc = proc;
|
|
||||||
pd.data = data;
|
|
||||||
|
|
||||||
se = fuse_session_new(&sop, &pd);
|
|
||||||
if (se == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ch = fuse_chan_new(&cop, fuse_chan_fd(prevch),
|
|
||||||
sizeof(struct fuse_cmd *), &pd);
|
|
||||||
if (ch == NULL) {
|
|
||||||
fuse_session_destroy(se);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
fuse_session_add_chan(se, ch);
|
|
||||||
res = fuse_session_loop_mt(se,
|
|
||||||
fuse_config_num_threads(f));
|
|
||||||
fuse_session_destroy(se);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fuse_loop_mt(struct fuse *f)
|
|
||||||
{
|
{
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -8,23 +8,28 @@
|
|||||||
|
|
||||||
#include "fuse_i.h"
|
#include "fuse_i.h"
|
||||||
#include "fuse_misc.h"
|
#include "fuse_misc.h"
|
||||||
|
#include "fuse_kernel.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <sys/uio.h>
|
||||||
|
|
||||||
|
|
||||||
struct fuse_chan
|
struct fuse_chan
|
||||||
{
|
{
|
||||||
struct fuse_chan_ops op;
|
|
||||||
struct fuse_session *se;
|
struct fuse_session *se;
|
||||||
int fd;
|
int fd;
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
void *data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data)
|
struct fuse_session *fuse_session_new(void *data,
|
||||||
|
void *receive_buf,
|
||||||
|
void *process_buf,
|
||||||
|
void *destroy)
|
||||||
{
|
{
|
||||||
struct fuse_session *se = (struct fuse_session *) malloc(sizeof(*se));
|
struct fuse_session *se = (struct fuse_session *) malloc(sizeof(*se));
|
||||||
if (se == NULL) {
|
if (se == NULL) {
|
||||||
@ -33,8 +38,10 @@ struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(se, 0, sizeof(*se));
|
memset(se, 0, sizeof(*se));
|
||||||
se->op = *op;
|
|
||||||
se->data = data;
|
se->data = data;
|
||||||
|
se->receive_buf = receive_buf;
|
||||||
|
se->process_buf = process_buf;
|
||||||
|
se->destroy = destroy;
|
||||||
|
|
||||||
return se;
|
return se;
|
||||||
}
|
}
|
||||||
@ -57,79 +64,30 @@ void fuse_session_remove_chan(struct fuse_chan *ch)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fuse_chan *fuse_session_next_chan(struct fuse_session *se,
|
void
|
||||||
struct fuse_chan *ch)
|
fuse_session_destroy(struct fuse_session *se)
|
||||||
{
|
{
|
||||||
assert(ch == NULL || ch == se->ch);
|
se->destroy(se->data);
|
||||||
if (ch == NULL)
|
if(se->ch != NULL)
|
||||||
return se->ch;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fuse_session_process(struct fuse_session *se, const char *buf, size_t len,
|
|
||||||
struct fuse_chan *ch)
|
|
||||||
{
|
|
||||||
se->op.process(se->data, buf, len, ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fuse_session_process_buf(struct fuse_session *se,
|
|
||||||
const struct fuse_buf *buf, struct fuse_chan *ch)
|
|
||||||
{
|
|
||||||
if (se->process_buf) {
|
|
||||||
se->process_buf(se->data, buf, ch);
|
|
||||||
} else {
|
|
||||||
assert(!(buf->flags & FUSE_BUF_IS_FD));
|
|
||||||
fuse_session_process(se->data, buf->mem, buf->size, ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
|
|
||||||
struct fuse_chan **chp)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (se->receive_buf) {
|
|
||||||
res = se->receive_buf(se, buf, chp);
|
|
||||||
} else {
|
|
||||||
res = fuse_chan_recv(chp, buf->mem, buf->size);
|
|
||||||
if (res > 0)
|
|
||||||
buf->size = res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void fuse_session_destroy(struct fuse_session *se)
|
|
||||||
{
|
|
||||||
if (se->op.destroy)
|
|
||||||
se->op.destroy(se->data);
|
|
||||||
if (se->ch != NULL)
|
|
||||||
fuse_chan_destroy(se->ch);
|
fuse_chan_destroy(se->ch);
|
||||||
free(se);
|
free(se);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuse_session_exit(struct fuse_session *se)
|
|
||||||
{
|
|
||||||
if (se->op.exit)
|
|
||||||
se->op.exit(se->data, 1);
|
|
||||||
se->exited = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fuse_session_reset(struct fuse_session *se)
|
void fuse_session_reset(struct fuse_session *se)
|
||||||
{
|
{
|
||||||
if (se->op.exit)
|
|
||||||
se->op.exit(se->data, 0);
|
|
||||||
se->exited = 0;
|
se->exited = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fuse_session_exited(struct fuse_session *se)
|
int
|
||||||
|
fuse_session_exited(struct fuse_session *se)
|
||||||
{
|
{
|
||||||
if (se->op.exited)
|
return se->exited;
|
||||||
return se->op.exited(se->data);
|
}
|
||||||
else
|
|
||||||
return se->exited;
|
void
|
||||||
|
fuse_session_exit(struct fuse_session *se_)
|
||||||
|
{
|
||||||
|
se_->exited = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *fuse_session_data(struct fuse_session *se)
|
void *fuse_session_data(struct fuse_session *se)
|
||||||
@ -137,28 +95,39 @@ void *fuse_session_data(struct fuse_session *se)
|
|||||||
return se->data;
|
return se->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct fuse_chan *fuse_chan_new_common(struct fuse_chan_ops *op, int fd,
|
int
|
||||||
size_t bufsize, void *data)
|
fuse_session_receive(struct fuse_session *se_,
|
||||||
|
struct fuse_buf *buf_)
|
||||||
{
|
{
|
||||||
struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch));
|
return se_->receive_buf(se_,buf_,se_->ch);
|
||||||
if (ch == NULL) {
|
|
||||||
fprintf(stderr, "fuse: failed to allocate channel\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(ch, 0, sizeof(*ch));
|
|
||||||
ch->op = *op;
|
|
||||||
ch->fd = fd;
|
|
||||||
ch->bufsize = bufsize;
|
|
||||||
ch->data = data;
|
|
||||||
|
|
||||||
return ch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
|
void
|
||||||
size_t bufsize, void *data)
|
fuse_session_process(struct fuse_session *se_,
|
||||||
|
const struct fuse_buf *buf_)
|
||||||
{
|
{
|
||||||
return fuse_chan_new_common(op, fd, bufsize, data);
|
se_->process_buf(se_->data,buf_,se_->ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct fuse_chan *
|
||||||
|
fuse_chan_new(int fd,
|
||||||
|
size_t bufsize)
|
||||||
|
{
|
||||||
|
struct fuse_chan *ch;
|
||||||
|
|
||||||
|
ch = (struct fuse_chan*)malloc(sizeof(*ch));
|
||||||
|
if(ch == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "fuse: failed to allocate channel\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(ch, 0, sizeof(*ch));
|
||||||
|
|
||||||
|
ch->fd = fd;
|
||||||
|
ch->bufsize = bufsize;
|
||||||
|
|
||||||
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fuse_chan_fd(struct fuse_chan *ch)
|
int fuse_chan_fd(struct fuse_chan *ch)
|
||||||
@ -178,40 +147,97 @@ size_t fuse_chan_bufsize(struct fuse_chan *ch)
|
|||||||
return ch->bufsize;
|
return ch->bufsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *fuse_chan_data(struct fuse_chan *ch)
|
|
||||||
{
|
|
||||||
return ch->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fuse_session *fuse_chan_session(struct fuse_chan *ch)
|
struct fuse_session *fuse_chan_session(struct fuse_chan *ch)
|
||||||
{
|
{
|
||||||
return ch->se;
|
return ch->se;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size)
|
int
|
||||||
|
fuse_chan_recv(struct fuse_chan *ch,
|
||||||
|
char *buf,
|
||||||
|
size_t size)
|
||||||
{
|
{
|
||||||
struct fuse_chan *ch = *chp;
|
int err;
|
||||||
|
ssize_t res;
|
||||||
|
struct fuse_session *se = fuse_chan_session(ch);
|
||||||
|
assert(se != NULL);
|
||||||
|
|
||||||
return ch->op.receive(chp, buf, size);
|
restart:
|
||||||
|
res = read(fuse_chan_fd(ch), buf, size);
|
||||||
|
err = errno;
|
||||||
|
|
||||||
|
if(fuse_session_exited(se))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(res == -1)
|
||||||
|
{
|
||||||
|
/* ENOENT means the operation was interrupted, it's safe
|
||||||
|
to restart */
|
||||||
|
if (err == ENOENT)
|
||||||
|
goto restart;
|
||||||
|
|
||||||
|
if(err == ENODEV)
|
||||||
|
{
|
||||||
|
se->exited = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Errors occurring during normal operation: EINTR (read
|
||||||
|
interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem
|
||||||
|
umounted) */
|
||||||
|
if(err != EINTR && err != EAGAIN)
|
||||||
|
perror("fuse: reading device");
|
||||||
|
return -err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((size_t) res < sizeof(struct fuse_in_header))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "short read on fuse device\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size)
|
int
|
||||||
|
fuse_chan_send(struct fuse_chan *ch,
|
||||||
|
const struct iovec iov[],
|
||||||
|
size_t count)
|
||||||
{
|
{
|
||||||
int res;
|
if(!iov)
|
||||||
|
return 0;
|
||||||
|
|
||||||
res = fuse_chan_recv(&ch, buf, size);
|
int err;
|
||||||
return res >= 0 ? res : (res != -EINTR && res != -EAGAIN) ? -1 : 0;
|
ssize_t res;
|
||||||
|
|
||||||
|
res = writev(fuse_chan_fd(ch), iov, count);
|
||||||
|
err = errno;
|
||||||
|
|
||||||
|
if(res == -1)
|
||||||
|
{
|
||||||
|
struct fuse_session *se = fuse_chan_session(ch);
|
||||||
|
|
||||||
|
assert(se != NULL);
|
||||||
|
|
||||||
|
/* ENOENT means the operation was interrupted */
|
||||||
|
if(!fuse_session_exited(se) && err != ENOENT)
|
||||||
|
perror("fuse: writing device");
|
||||||
|
return -err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count)
|
void
|
||||||
|
fuse_chan_destroy(struct fuse_chan *ch)
|
||||||
{
|
{
|
||||||
return ch->op.send(ch, iov, count);
|
int fd;
|
||||||
}
|
|
||||||
|
|
||||||
void fuse_chan_destroy(struct fuse_chan *ch)
|
|
||||||
{
|
|
||||||
fuse_session_remove_chan(ch);
|
fuse_session_remove_chan(ch);
|
||||||
if (ch->op.destroy)
|
|
||||||
ch->op.destroy(ch);
|
fd = fuse_chan_fd(ch);
|
||||||
|
if(fd != -1)
|
||||||
|
close(fd);
|
||||||
|
|
||||||
free(ch);
|
free(ch);
|
||||||
}
|
}
|
||||||
|
@ -237,8 +237,10 @@ struct fuse_chan *
|
|||||||
fuse_mount_common(const char *mountpoint_,
|
fuse_mount_common(const char *mountpoint_,
|
||||||
struct fuse_args *args_)
|
struct fuse_args *args_)
|
||||||
{
|
{
|
||||||
struct fuse_chan *ch;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
long bufsize;
|
||||||
|
long pagesize;
|
||||||
|
struct fuse_chan *ch;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
|
* Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
|
||||||
@ -255,7 +257,10 @@ fuse_mount_common(const char *mountpoint_,
|
|||||||
if(fd == -1)
|
if(fd == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ch = fuse_kern_chan_new(fd);
|
pagesize = sysconf(_SC_PAGESIZE);
|
||||||
|
bufsize = ((FUSE_MAX_MAX_PAGES + 1) * pagesize);
|
||||||
|
|
||||||
|
ch = fuse_chan_new(fd,bufsize);
|
||||||
if(!ch)
|
if(!ch)
|
||||||
fuse_kern_unmount(mountpoint_, fd);
|
fuse_kern_unmount(mountpoint_, fd);
|
||||||
|
|
||||||
@ -284,11 +289,13 @@ void fuse_unmount(const char *mountpoint, struct fuse_chan *ch)
|
|||||||
fuse_unmount_common(mountpoint, ch);
|
fuse_unmount_common(mountpoint, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fuse *fuse_setup_common(int argc, char *argv[],
|
struct fuse *
|
||||||
const struct fuse_operations *op,
|
fuse_setup_common(int argc,
|
||||||
size_t op_size,
|
char *argv[],
|
||||||
char **mountpoint,
|
const struct fuse_operations *op,
|
||||||
int *fd)
|
size_t op_size,
|
||||||
|
char **mountpoint,
|
||||||
|
int *fd)
|
||||||
{
|
{
|
||||||
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
|
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
|
||||||
struct fuse_chan *ch;
|
struct fuse_chan *ch;
|
||||||
@ -344,7 +351,7 @@ struct fuse *fuse_setup(int argc, char *argv[],
|
|||||||
static void fuse_teardown_common(struct fuse *fuse, char *mountpoint)
|
static void fuse_teardown_common(struct fuse *fuse, char *mountpoint)
|
||||||
{
|
{
|
||||||
struct fuse_session *se = fuse_get_session(fuse);
|
struct fuse_session *se = fuse_get_session(fuse);
|
||||||
struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
|
struct fuse_chan *ch = se->ch;
|
||||||
fuse_remove_signal_handlers(se);
|
fuse_remove_signal_handlers(se);
|
||||||
fuse_unmount_common(mountpoint, ch);
|
fuse_unmount_common(mountpoint, ch);
|
||||||
fuse_destroy(fuse);
|
fuse_destroy(fuse);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user