checkpoint

This commit is contained in:
Antonio SJ Musumeci 2020-11-01 23:49:48 -05:00
parent eaa2593a4b
commit a5a6b45463
18 changed files with 581 additions and 645 deletions

View File

@ -46,10 +46,10 @@ SRC = \
lib/mount.c lib/mount.c
OBJS = $(SRC:lib/%.c=build/%.o) OBJS = $(SRC:lib/%.c=build/%.o)
DEPS = $(SRC:lib/%.c=build/%.d) DEPS = $(SRC:lib/%.c=build/%.d)
CFLAGS ?= \ CXXFLAGS ?= \
$(OPT_FLAGS) $(OPT_FLAGS)
CFLAGS := \ CXXFLAGS := \
${CFLAGS} \ ${CXXFLAGS} \
-Wall \ -Wall \
-pipe \ -pipe \
-MMD -MMD
@ -85,17 +85,17 @@ build/libfuse.a: objects
utils: mergerfs-fusermount mount.mergerfs utils: mergerfs-fusermount mount.mergerfs
build/mergerfs-fusermount: build/config.h util/fusermount.c lib/mount_util.c build/mergerfs-fusermount: build/config.h util/fusermount.c lib/mount_util.c
$(CC) $(CFLAGS) $(FUSE_FLAGS) -Ilib -o build/mergerfs-fusermount util/fusermount.c lib/mount_util.c $(CXX) $(CXXFLAGS) $(FUSE_FLAGS) -Ilib -o build/mergerfs-fusermount util/fusermount.c lib/mount_util.c
mergerfs-fusermount: build/mergerfs-fusermount mergerfs-fusermount: build/mergerfs-fusermount
build/mount.mergerfs: build/libfuse.a util/mount.mergerfs.c build/mount.mergerfs: build/libfuse.a util/mount.mergerfs.c
$(CC) $(CFLAGS) $(FUSE_FLAGS) -o build/mount.mergerfs util/mount.mergerfs.c build/libfuse.a $(LDFLAGS) $(CXX) $(CXXFLAGS) $(FUSE_FLAGS) -o build/mount.mergerfs util/mount.mergerfs.c build/libfuse.a $(LDFLAGS)
mount.mergerfs: build/mount.mergerfs mount.mergerfs: build/mount.mergerfs
build/%.o: lib/%.c build/%.o: lib/%.c
$(CC) $(CFLAGS) $(FUSE_FLAGS) -c $< -o $@ $(CXX) $(CXXFLAGS) $(FUSE_FLAGS) -c $< -o $@
clean: clean:
rm -rf build rm -rf build

View File

@ -280,14 +280,15 @@ void fuse_pollhandle_destroy(struct fuse_pollhandle *ph);
/** /**
* Buffer flags * Buffer flags
*/ */
enum fuse_buf_flags { #define FUSE_BUF_FLAG_NONE (1 << 0)
/**
/**
* Buffer contains a file descriptor * Buffer contains a file descriptor
* *
* If this flag is set, the .fd field is valid, otherwise the * If this flag is set, the .fd field is valid, otherwise the
* .mem fields is valid. * .mem fields is valid.
*/ */
FUSE_BUF_IS_FD = (1 << 1), #define FUSE_BUF_FLAG_IS_FD (1 << 1)
/** /**
* Seek on the file descriptor * Seek on the file descriptor
@ -296,7 +297,7 @@ enum fuse_buf_flags {
* used to seek to the given offset before performing * used to seek to the given offset before performing
* operation on file descriptor. * operation on file descriptor.
*/ */
FUSE_BUF_FD_SEEK = (1 << 2), #define FUSE_BUF_FLAG_FD_SEEK (1 << 2)
/** /**
* Retry operation on file descriptor * Retry operation on file descriptor
@ -305,50 +306,50 @@ enum fuse_buf_flags {
* until .size bytes have been copied or an error or EOF is * until .size bytes have been copied or an error or EOF is
* detected. * detected.
*/ */
FUSE_BUF_FD_RETRY = (1 << 3), #define FUSE_BUF_FLAG_FD_RETRY (1 << 3)
};
/** /**
* Buffer copy flags * Buffer copy flags
*/ */
enum fuse_buf_copy_flags { #define FUSE_BUF_COPY_FLAG_NONE 0
/**
* Don't use splice(2)
*
* Always fall back to using read and write instead of
* splice(2) to copy data from one file descriptor to another.
*
* If this flag is not set, then only fall back if splice is
* unavailable.
*/
FUSE_BUF_NO_SPLICE = (1 << 1),
/** /**
* Force splice * Don't use splice(2)
* *
* Always use splice(2) to copy data from one file descriptor * Always fall back to using read and write instead of
* to another. If splice is not available, return -EINVAL. * splice(2) to copy data from one file descriptor to another.
*/ *
FUSE_BUF_FORCE_SPLICE = (1 << 2), * If this flag is not set, then only fall back if splice is
* unavailable.
*/
#define FUSE_BUF_COPY_FLAG_NO_SPLICE (1 << 1)
/** /**
* Try to move data with splice. * Force splice
* *
* If splice is used, try to move pages from the source to the * Always use splice(2) to copy data from one file descriptor
* destination instead of copying. See documentation of * to another. If splice is not available, return -EINVAL.
* SPLICE_F_MOVE in splice(2) man page. */
*/ #define FUSE_BUF_COPY_FLAG_FORCE_SPLICE (1 << 2)
FUSE_BUF_SPLICE_MOVE = (1 << 3),
/**
* Try to move data with splice.
*
* If splice is used, try to move pages from the source to the
* destination instead of copying. See documentation of
* SPLICE_F_MOVE in splice(2) man page.
*/
#define FUSE_BUF_COPY_FLAG_SPLICE_MOVE (1 << 3)
/**
* Don't block on the pipe when copying data with splice
*
* Makes the operations on the pipe non-blocking (if the pipe
* is full or empty). See SPLICE_F_NONBLOCK in the splice(2)
* man page.
*/
#define FUSE_BUF_COPY_FLAG_SPLICE_NONBLOCK (1 << 4)
/**
* Don't block on the pipe when copying data with splice
*
* Makes the operations on the pipe non-blocking (if the pipe
* is full or empty). See SPLICE_F_NONBLOCK in the splice(2)
* man page.
*/
FUSE_BUF_SPLICE_NONBLOCK= (1 << 4),
};
/** /**
* Single data buffer * Single data buffer
@ -365,14 +366,14 @@ struct fuse_buf {
/** /**
* Buffer flags * Buffer flags
*/ */
enum fuse_buf_flags flags; int flags;
/** /**
* Memory pointer * Memory pointer
* *
* Used unless FUSE_BUF_IS_FD flag is set. * Used unless FUSE_BUF_IS_FD flag is set.
*/ */
void *mem; char *mem;
/** /**
* File descriptor * File descriptor
@ -427,7 +428,7 @@ struct fuse_bufvec {
/* .off = */ 0, \ /* .off = */ 0, \
/* .buf = */ { /* [0] = */ { \ /* .buf = */ { /* [0] = */ { \
/* .size = */ (size__), \ /* .size = */ (size__), \
/* .flags = */ (enum fuse_buf_flags) 0, \ /* .flags = */ 0, \
/* .mem = */ NULL, \ /* .mem = */ NULL, \
/* .fd = */ -1, \ /* .fd = */ -1, \
/* .pos = */ 0, \ /* .pos = */ 0, \
@ -450,8 +451,7 @@ size_t fuse_buf_size(const struct fuse_bufvec *bufv);
* @param flags flags controlling the copy * @param flags flags controlling the copy
* @return actual number of bytes copied or -errno on error * @return actual number of bytes copied or -errno on error
*/ */
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, int flags);
enum fuse_buf_copy_flags flags);
/* ----------------------------------------------------------- * /* ----------------------------------------------------------- *
* Signal handling * * Signal handling *

View File

@ -1202,8 +1202,7 @@ int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size);
* @param flags flags controlling the copy * @param flags flags controlling the copy
* @return zero for success, -errno for failure to send reply * @return zero for success, -errno for failure to send reply
*/ */
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, int flags);
enum fuse_buf_copy_flags flags);
/** /**
* Reply with data vector * Reply with data vector
@ -1406,7 +1405,7 @@ int fuse_lowlevel_notify_delete(struct fuse_chan *ch,
*/ */
int fuse_lowlevel_notify_store(struct fuse_chan *ch, fuse_ino_t ino, int fuse_lowlevel_notify_store(struct fuse_chan *ch, fuse_ino_t ino,
off_t offset, struct fuse_bufvec *bufv, off_t offset, struct fuse_bufvec *bufv,
enum fuse_buf_copy_flags flags); int flags);
/** /**
* Retrieve data from the kernel buffers * Retrieve data from the kernel buffers
* *
@ -1486,7 +1485,7 @@ int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]);
* @param req interrupted request * @param req interrupted request
* @param data user data * @param data user data
*/ */
typedef void (*fuse_interrupt_func_t)(fuse_req_t req, void *data); typedef void (*fuse_interrupt_func_t)(fuse_req_t req, struct fuse_intr_data *data);
/** /**
* Register/unregister callback for an interrupt * Register/unregister callback for an interrupt
@ -1499,7 +1498,8 @@ typedef void (*fuse_interrupt_func_t)(fuse_req_t req, void *data);
* @param func the callback function or NULL for unregister * @param func the callback function or NULL for unregister
* @param data user data passed to the callback function * @param data user data passed to the callback function
*/ */
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, void fuse_req_interrupt_func(fuse_req_t req,
fuse_interrupt_func_t func,
void *data); void *data);
/** /**

View File

@ -6,15 +6,16 @@
See the file COPYING.LIB See the file COPYING.LIB
*/ */
#define _GNU_SOURCE
#include "config.h" #include "config.h"
#include "fuse_i.h" #include "fuse_i.h"
#include "fuse_lowlevel.h" #include "fuse_lowlevel.h"
#include <limits>
#include <assert.h>
#include <errno.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#include <assert.h>
size_t fuse_buf_size(const struct fuse_bufvec *bufv) size_t fuse_buf_size(const struct fuse_bufvec *bufv)
{ {
@ -22,8 +23,8 @@ size_t fuse_buf_size(const struct fuse_bufvec *bufv)
size_t size = 0; size_t size = 0;
for (i = 0; i < bufv->count; i++) { for (i = 0; i < bufv->count; i++) {
if (bufv->buf[i].size == SIZE_MAX) if (bufv->buf[i].size == std::numeric_limits<size_t>::max())
size = SIZE_MAX; size = std::numeric_limits<size_t>::max();
else else
size += bufv->buf[i].size; size += bufv->buf[i].size;
} }
@ -44,7 +45,7 @@ static ssize_t fuse_buf_write(const struct fuse_buf *dst, size_t dst_off,
size_t copied = 0; size_t copied = 0;
while (len) { while (len) {
if (dst->flags & FUSE_BUF_FD_SEEK) { if (dst->flags & FUSE_BUF_FLAG_FD_SEEK) {
res = pwrite(dst->fd, src->mem + src_off, len, res = pwrite(dst->fd, src->mem + src_off, len,
dst->pos + dst_off); dst->pos + dst_off);
} else { } else {
@ -59,7 +60,7 @@ static ssize_t fuse_buf_write(const struct fuse_buf *dst, size_t dst_off,
break; break;
copied += res; copied += res;
if (!(dst->flags & FUSE_BUF_FD_RETRY)) if (!(dst->flags & FUSE_BUF_FLAG_FD_RETRY))
break; break;
src_off += res; src_off += res;
@ -78,7 +79,7 @@ static ssize_t fuse_buf_read(const struct fuse_buf *dst, size_t dst_off,
size_t copied = 0; size_t copied = 0;
while (len) { while (len) {
if (src->flags & FUSE_BUF_FD_SEEK) { if (src->flags & FUSE_BUF_FLAG_FD_SEEK) {
res = pread(src->fd, dst->mem + dst_off, len, res = pread(src->fd, dst->mem + dst_off, len,
src->pos + src_off); src->pos + src_off);
} else { } else {
@ -93,7 +94,7 @@ static ssize_t fuse_buf_read(const struct fuse_buf *dst, size_t dst_off,
break; break;
copied += res; copied += res;
if (!(src->flags & FUSE_BUF_FD_RETRY)) if (!(src->flags & FUSE_BUF_FLAG_FD_RETRY))
break; break;
dst_off += res; dst_off += res;
@ -104,52 +105,56 @@ static ssize_t fuse_buf_read(const struct fuse_buf *dst, size_t dst_off,
return copied; return copied;
} }
static ssize_t fuse_buf_fd_to_fd(const struct fuse_buf *dst, size_t dst_off, static
const struct fuse_buf *src, size_t src_off, ssize_t
size_t len) fuse_buf_fd_to_fd(const struct fuse_buf *dst,
size_t dst_off,
const struct fuse_buf *src,
size_t src_off,
size_t len)
{ {
char buf[4096]; char buf[4096];
struct fuse_buf tmp = {
.size = sizeof(buf),
.flags = 0,
};
ssize_t res; ssize_t res;
size_t copied = 0; size_t copied = 0;
struct fuse_buf tmp;
tmp.mem = buf; tmp.size = sizeof(buf);
tmp.flags = FUSE_BUF_FLAG_NONE;
tmp.mem = buf;
while (len) { while(len)
size_t this_len = min_size(tmp.size, len); {
size_t read_len; ssize_t this_len = min_size(tmp.size, len);
ssize_t read_len;
res = fuse_buf_read(&tmp, 0, src, src_off, this_len); res = fuse_buf_read(&tmp, 0, src, src_off, this_len);
if (res < 0) { if (res < 0) {
if (!copied) if (!copied)
return res; return res;
break; break;
}
if (res == 0)
break;
read_len = res;
res = fuse_buf_write(dst, dst_off, &tmp, 0, read_len);
if (res < 0) {
if (!copied)
return res;
break;
}
if (res == 0)
break;
copied += res;
if (res < this_len)
break;
dst_off += res;
src_off += res;
len -= res;
} }
if (res == 0)
break;
read_len = res;
res = fuse_buf_write(dst, dst_off, &tmp, 0, read_len);
if (res < 0) {
if (!copied)
return res;
break;
}
if (res == 0)
break;
copied += res;
if (res < this_len)
break;
dst_off += res;
src_off += res;
len -= res;
}
return copied; return copied;
} }
@ -157,7 +162,7 @@ static ssize_t fuse_buf_fd_to_fd(const struct fuse_buf *dst, size_t dst_off,
#ifdef HAVE_SPLICE #ifdef HAVE_SPLICE
static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off, static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
const struct fuse_buf *src, size_t src_off, const struct fuse_buf *src, size_t src_off,
size_t len, enum fuse_buf_copy_flags flags) size_t len, int flags)
{ {
int splice_flags = 0; int splice_flags = 0;
off_t *srcpos = NULL; off_t *srcpos = NULL;
@ -167,16 +172,16 @@ static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
ssize_t res; ssize_t res;
size_t copied = 0; size_t copied = 0;
if (flags & FUSE_BUF_SPLICE_MOVE) if (flags & FUSE_BUF_COPY_FLAG_SPLICE_MOVE)
splice_flags |= SPLICE_F_MOVE; splice_flags |= SPLICE_F_MOVE;
if (flags & FUSE_BUF_SPLICE_NONBLOCK) if (flags & FUSE_BUF_COPY_FLAG_SPLICE_NONBLOCK)
splice_flags |= SPLICE_F_NONBLOCK; splice_flags |= SPLICE_F_NONBLOCK;
if (src->flags & FUSE_BUF_FD_SEEK) { if (src->flags & FUSE_BUF_FLAG_FD_SEEK) {
srcpos_val = src->pos + src_off; srcpos_val = src->pos + src_off;
srcpos = &srcpos_val; srcpos = &srcpos_val;
} }
if (dst->flags & FUSE_BUF_FD_SEEK) { if (dst->flags & FUSE_BUF_FLAG_FD_SEEK) {
dstpos_val = dst->pos + dst_off; dstpos_val = dst->pos + dst_off;
dstpos = &dstpos_val; dstpos = &dstpos_val;
} }
@ -188,7 +193,7 @@ static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
if (copied) if (copied)
break; break;
if (errno != EINVAL || (flags & FUSE_BUF_FORCE_SPLICE)) if (errno != EINVAL || (flags & FUSE_BUF_COPY_FLAG_FORCE_SPLICE))
return -errno; return -errno;
/* Maybe splice is not supported for this combination */ /* Maybe splice is not supported for this combination */
@ -199,8 +204,8 @@ static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
break; break;
copied += res; copied += res;
if (!(src->flags & FUSE_BUF_FD_RETRY) && if (!(src->flags & FUSE_BUF_FLAG_FD_RETRY) &&
!(dst->flags & FUSE_BUF_FD_RETRY)) { !(dst->flags & FUSE_BUF_FLAG_FD_RETRY)) {
break; break;
} }
@ -223,10 +228,10 @@ static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
static ssize_t fuse_buf_copy_one(const struct fuse_buf *dst, size_t dst_off, static ssize_t fuse_buf_copy_one(const struct fuse_buf *dst, size_t dst_off,
const struct fuse_buf *src, size_t src_off, const struct fuse_buf *src, size_t src_off,
size_t len, enum fuse_buf_copy_flags flags) size_t len, int flags)
{ {
int src_is_fd = src->flags & FUSE_BUF_IS_FD; int src_is_fd = src->flags & FUSE_BUF_FLAG_IS_FD;
int dst_is_fd = dst->flags & FUSE_BUF_IS_FD; int dst_is_fd = dst->flags & FUSE_BUF_FLAG_IS_FD;
if (!src_is_fd && !dst_is_fd) { if (!src_is_fd && !dst_is_fd) {
char *dstmem = dst->mem + dst_off; char *dstmem = dst->mem + dst_off;
@ -244,7 +249,7 @@ static ssize_t fuse_buf_copy_one(const struct fuse_buf *dst, size_t dst_off,
return fuse_buf_write(dst, dst_off, src, src_off, len); return fuse_buf_write(dst, dst_off, src, src_off, len);
} else if (!dst_is_fd) { } else if (!dst_is_fd) {
return fuse_buf_read(dst, dst_off, src, src_off, len); return fuse_buf_read(dst, dst_off, src, src_off, len);
} else if (flags & FUSE_BUF_NO_SPLICE) { } else if (flags & FUSE_BUF_COPY_FLAG_NO_SPLICE) {
return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len); return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
} else { } else {
return fuse_buf_splice(dst, dst_off, src, src_off, len, flags); return fuse_buf_splice(dst, dst_off, src, src_off, len, flags);
@ -275,23 +280,26 @@ static int fuse_bufvec_advance(struct fuse_bufvec *bufv, size_t len)
return 1; return 1;
} }
ssize_t fuse_buf_copy(struct fuse_bufvec *dstv, struct fuse_bufvec *srcv, ssize_t
enum fuse_buf_copy_flags flags) fuse_buf_copy(struct fuse_bufvec *dstv,
struct fuse_bufvec *srcv,
int flags)
{ {
size_t copied = 0; size_t copied = 0;
if (dstv == srcv) if(dstv == srcv)
return fuse_buf_size(dstv); return fuse_buf_size(dstv);
for (;;) { for (;;)
{
const struct fuse_buf *src = fuse_bufvec_current(srcv); const struct fuse_buf *src = fuse_bufvec_current(srcv);
const struct fuse_buf *dst = fuse_bufvec_current(dstv); const struct fuse_buf *dst = fuse_bufvec_current(dstv);
size_t src_len; ssize_t src_len;
size_t dst_len; ssize_t dst_len;
size_t len; ssize_t len;
ssize_t res; ssize_t res;
if (src == NULL || dst == NULL) if(src == NULL || dst == NULL)
break; break;
src_len = src->size - srcv->off; src_len = src->size - srcv->off;

View File

@ -8,7 +8,6 @@
/* For pthread_rwlock_t */ /* For pthread_rwlock_t */
#define _GNU_SOURCE
#include "config.h" #include "config.h"
#include "fuse_i.h" #include "fuse_i.h"
@ -18,6 +17,8 @@
#include "fuse_kernel.h" #include "fuse_kernel.h"
#include "fuse_dirents.h" #include "fuse_dirents.h"
#include <limits>
#include <assert.h> #include <assert.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <errno.h> #include <errno.h>
@ -39,15 +40,9 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#define FUSE_NODE_SLAB 1
#ifndef MAP_ANONYMOUS
#undef FUSE_NODE_SLAB
#endif
#define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1 #define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
#define FUSE_UNKNOWN_INO UINT64_MAX #define FUSE_UNKNOWN_INO std::numeric_limits<uint64_t>::max()
#define OFFSET_MAX 0x7fffffffffffffffLL #define OFFSET_MAX 0x7fffffffffffffffLL
#define NODE_TABLE_MIN_SIZE 8192 #define NODE_TABLE_MIN_SIZE 8192
@ -102,13 +97,6 @@ struct node_table
size_t split; size_t split;
}; };
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
struct list_head struct list_head
{ {
struct list_head *next; struct list_head *next;
@ -216,32 +204,32 @@ list_empty(const struct list_head *head)
static static
void void
list_add(struct list_head *new, list_add(struct list_head *new_,
struct list_head *prev, struct list_head *prev_,
struct list_head *next) struct list_head *next_)
{ {
next->prev = new; next_->prev = new_;
new->next = next; new_->next = next_;
new->prev = prev; new_->prev = prev_;
prev->next = new; prev_->next = new_;
} }
static static
inline inline
void void
list_add_head(struct list_head *new, list_add_head(struct list_head *new_,
struct list_head *head) struct list_head *head_)
{ {
list_add(new, head, head->next); list_add(new_,head_,head_->next);
} }
static static
inline inline
void void
list_add_tail(struct list_head *new, list_add_tail(struct list_head *new_,
struct list_head *head) struct list_head *head_)
{ {
list_add(new, head->prev, head); list_add(new_,head_->prev,head_);
} }
static static
@ -282,113 +270,6 @@ get_node_size(struct fuse *f)
return sizeof(struct node); return sizeof(struct node);
} }
#ifdef FUSE_NODE_SLAB
static
struct node_slab*
list_to_slab(struct list_head *head)
{
return (struct node_slab *) head;
}
static
struct node_slab*
node_to_slab(struct fuse *f, struct node *node)
{
return (struct node_slab *) (((uintptr_t) node) & ~((uintptr_t) f->pagesize - 1));
}
static
int
alloc_slab(struct fuse *f)
{
void *mem;
struct node_slab *slab;
char *start;
size_t num;
size_t i;
size_t node_size = get_node_size(f);
mem = mmap(NULL, f->pagesize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mem == MAP_FAILED)
return -1;
slab = mem;
init_list_head(&slab->freelist);
slab->used = 0;
num = (f->pagesize - sizeof(struct node_slab)) / node_size;
start = (char *) mem + f->pagesize - num * node_size;
for (i = 0; i < num; i++) {
struct list_head *n;
n = (struct list_head *) (start + i * node_size);
list_add_tail(n, &slab->freelist);
}
list_add_tail(&slab->list, &f->partial_slabs);
return 0;
}
static
struct node*
alloc_node(struct fuse *f)
{
struct node_slab *slab;
struct list_head *node;
if (list_empty(&f->partial_slabs)) {
int res = alloc_slab(f);
if (res != 0)
return NULL;
}
slab = list_to_slab(f->partial_slabs.next);
slab->used++;
node = slab->freelist.next;
list_del(node);
if (list_empty(&slab->freelist)) {
list_del(&slab->list);
list_add_tail(&slab->list, &f->full_slabs);
}
memset(node, 0, sizeof(struct node));
return (struct node *) node;
}
static
void
free_slab(struct fuse *f,
struct node_slab *slab)
{
int res;
list_del(&slab->list);
res = munmap(slab, f->pagesize);
if (res == -1)
fprintf(stderr, "fuse warning: munmap(%p) failed\n", slab);
}
static
void
free_node_mem(struct fuse *f,
struct node *node)
{
struct node_slab *slab = node_to_slab(f, node);
struct list_head *n = (struct list_head *) node;
slab->used--;
if (slab->used) {
if (list_empty(&slab->freelist)) {
list_del(&slab->list);
list_add_tail(&slab->list, &f->partial_slabs);
}
list_add_head(n, &slab->freelist);
} else {
free_slab(f, slab);
}
}
#else
static static
struct node* struct node*
alloc_node(struct fuse *f) alloc_node(struct fuse *f)
@ -404,7 +285,6 @@ free_node_mem(struct fuse *f,
(void) f; (void) f;
free(node); free(node);
} }
#endif
static static
size_t size_t
@ -496,13 +376,13 @@ void
node_table_reduce(struct node_table *t) node_table_reduce(struct node_table *t)
{ {
size_t newsize = t->size / 2; size_t newsize = t->size / 2;
void *newarray; node **newarray;
if (newsize < NODE_TABLE_MIN_SIZE) if (newsize < NODE_TABLE_MIN_SIZE)
return; return;
newarray = realloc(t->array, sizeof(struct node *) * newsize); newarray = (node**)realloc(t->array,sizeof(struct node*)*newsize);
if (newarray != NULL) if(newarray != NULL)
t->array = newarray; t->array = newarray;
t->size = newsize; t->size = newsize;
@ -557,14 +437,14 @@ unhash_id(struct fuse *f, struct node *node)
static int node_table_resize(struct node_table *t) static int node_table_resize(struct node_table *t)
{ {
size_t newsize = t->size * 2; size_t newsize = t->size * 2;
void *newarray; node **newarray;
newarray = realloc(t->array, sizeof(struct node *) * newsize); newarray = (node**)realloc(t->array,sizeof(struct node*)*newsize);
if (newarray == NULL) if(newarray == NULL)
return -1; return -1;
t->array = newarray; t->array = newarray;
memset(t->array + t->size, 0, t->size * sizeof(struct node *)); memset(t->array + t->size,0,t->size*sizeof(struct node*));
t->size = newsize; t->size = newsize;
t->split = 0; t->split = 0;
@ -780,7 +660,7 @@ next_id(struct fuse *f)
{ {
do do
{ {
f->ctr = ((f->ctr + 1) & UINT64_MAX); f->ctr = ((f->ctr + 1) & std::numeric_limits<uint64_t>::max());
if(f->ctr == 0) if(f->ctr == 0)
f->generation++; f->generation++;
} while((f->ctr == 0) || } while((f->ctr == 0) ||
@ -850,7 +730,12 @@ static struct node *find_node(struct fuse *f, fuse_ino_t parent,
return node; return node;
} }
static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name) static
char *
add_name(char **buf,
unsigned *bufsize,
char *s,
const char *name)
{ {
size_t len = strlen(name); size_t len = strlen(name);
@ -866,7 +751,7 @@ static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name)
newbufsize *= 2; newbufsize *= 2;
} }
newbuf = realloc(*buf, newbufsize); newbuf = (char*)realloc(*buf, newbufsize);
if (newbuf == NULL) if (newbuf == NULL)
return NULL; return NULL;
@ -917,7 +802,7 @@ static int try_get_path(struct fuse *f, fuse_ino_t nodeid, const char *name,
*path = NULL; *path = NULL;
err = -ENOMEM; err = -ENOMEM;
buf = malloc(bufsize); buf = (char*)malloc(bufsize);
if (buf == NULL) if (buf == NULL)
goto out_err; goto out_err;
@ -1124,17 +1009,19 @@ static int get_path_common(struct fuse *f, fuse_ino_t nodeid, const char *name,
pthread_mutex_lock(&f->lock); pthread_mutex_lock(&f->lock);
err = try_get_path(f, nodeid, name, path, wnode, true); err = try_get_path(f, nodeid, name, path, wnode, true);
if (err == -EAGAIN) { if(err == -EAGAIN)
struct lock_queue_element qe = { {
.nodeid1 = nodeid, struct lock_queue_element qe;
.name1 = name,
.path1 = path, qe.nodeid1 = nodeid;
.wnode1 = wnode, qe.name1 = name;
}; qe.path1 = path;
debug_path(f, "QUEUE PATH", nodeid, name, !!wnode); qe.wnode1 = wnode;
err = wait_path(f, &qe);
debug_path(f, "DEQUEUE PATH", nodeid, name, !!wnode); debug_path(f, "QUEUE PATH", nodeid, name, !!wnode);
} err = wait_path(f, &qe);
debug_path(f, "DEQUEUE PATH", nodeid, name, !!wnode);
}
pthread_mutex_unlock(&f->lock); pthread_mutex_unlock(&f->lock);
return err; return err;
@ -1188,24 +1075,25 @@ static int get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1,
pthread_mutex_lock(&f->lock); pthread_mutex_lock(&f->lock);
err = try_get_path2(f, nodeid1, name1, nodeid2, name2, err = try_get_path2(f, nodeid1, name1, nodeid2, name2,
path1, path2, wnode1, wnode2); path1, path2, wnode1, wnode2);
if (err == -EAGAIN) { if(err == -EAGAIN)
struct lock_queue_element qe = { {
.nodeid1 = nodeid1, struct lock_queue_element qe;
.name1 = name1,
.path1 = path1,
.wnode1 = wnode1,
.nodeid2 = nodeid2,
.name2 = name2,
.path2 = path2,
.wnode2 = wnode2,
};
debug_path(f, "QUEUE PATH1", nodeid1, name1, !!wnode1); qe.nodeid1 = nodeid1;
debug_path(f, " PATH2", nodeid2, name2, !!wnode2); qe.name1 = name1;
err = wait_path(f, &qe); qe.path1 = path1;
debug_path(f, "DEQUEUE PATH1", nodeid1, name1, !!wnode1); qe.wnode1 = wnode1;
debug_path(f, " PATH2", nodeid2, name2, !!wnode2); qe.nodeid2 = nodeid2;
} qe.name2 = name2;
qe.path2 = path2;
qe.wnode2 = wnode2;
debug_path(f, "QUEUE PATH1", nodeid1, name1, !!wnode1);
debug_path(f, " PATH2", nodeid2, name2, !!wnode2);
err = wait_path(f, &qe);
debug_path(f, "DEQUEUE PATH1", nodeid1, name1, !!wnode1);
debug_path(f, " PATH2", nodeid2, name2, !!wnode2);
}
pthread_mutex_unlock(&f->lock); pthread_mutex_unlock(&f->lock);
return err; return err;
@ -1261,9 +1149,9 @@ forget_node(struct fuse *f,
*/ */
while(node->nlookup == nlookup && node->treelock) while(node->nlookup == nlookup && node->treelock)
{ {
struct lock_queue_element qe = { struct lock_queue_element qe;
.nodeid1 = nodeid,
}; qe.nodeid1 = nodeid;
debug_path(f, "QUEUE PATH (forget)", nodeid, NULL, false); debug_path(f, "QUEUE PATH (forget)", nodeid, NULL, false);
queue_path(f, &qe); queue_path(f, &qe);
@ -1366,16 +1254,20 @@ struct fuse_intr_data {
int finished; int finished;
}; };
static void fuse_interrupt(fuse_req_t req, void *d_) static
void
fuse_interrupt(fuse_req_t req_,
fuse_intr_data *d_)
{ {
struct fuse_intr_data *d = d_; struct fuse_intr_data *d = d_;
struct fuse *f = req_fuse(req); struct fuse *f = req_fuse(req_);
if (d->id == pthread_self()) if(d->id == pthread_self())
return; return;
pthread_mutex_lock(&f->lock); pthread_mutex_lock(&f->lock);
while (!d->finished) { while (!d->finished)
{
struct timeval now; struct timeval now;
struct timespec timeout; struct timespec timeout;
@ -1395,7 +1287,7 @@ static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req,
d->finished = 1; d->finished = 1;
pthread_cond_broadcast(&d->cond); pthread_cond_broadcast(&d->cond);
pthread_mutex_unlock(&f->lock); pthread_mutex_unlock(&f->lock);
fuse_req_interrupt_func(req, NULL, NULL); fuse_req_interrupt_func(req,NULL,NULL);
pthread_cond_destroy(&d->cond); pthread_cond_destroy(&d->cond);
} }
@ -1404,7 +1296,7 @@ static void fuse_do_prepare_interrupt(fuse_req_t req, struct fuse_intr_data *d)
d->id = pthread_self(); d->id = pthread_self();
pthread_cond_init(&d->cond, NULL); pthread_cond_init(&d->cond, NULL);
d->finished = 0; d->finished = 0;
fuse_req_interrupt_func(req, fuse_interrupt, d); fuse_req_interrupt_func(req,fuse_interrupt,d);
} }
static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req, static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req,
@ -1617,9 +1509,12 @@ static void fuse_free_buf(struct fuse_bufvec *buf)
} }
} }
int fuse_fs_read_buf(struct fuse_fs *fs, int
struct fuse_bufvec **bufp, size_t size, off_t off, fuse_fs_read_buf(struct fuse_fs *fs,
struct fuse_file_info *fi) struct fuse_bufvec **bufp,
size_t size,
off_t off,
struct fuse_file_info *fi)
{ {
fuse_get_context()->private_data = fs->user_data; fuse_get_context()->private_data = fs->user_data;
if (fs->op.read || fs->op.read_buf) { if (fs->op.read || fs->op.read_buf) {
@ -1635,13 +1530,13 @@ int fuse_fs_read_buf(struct fuse_fs *fs,
res = fs->op.read_buf(bufp, size, off, fi); res = fs->op.read_buf(bufp, size, off, fi);
} else { } else {
struct fuse_bufvec *buf; struct fuse_bufvec *buf;
void *mem; char *mem;
buf = malloc(sizeof(struct fuse_bufvec)); buf = (struct fuse_bufvec*)malloc(sizeof(struct fuse_bufvec));
if (buf == NULL) if(buf == NULL)
return -ENOMEM; return -ENOMEM;
mem = malloc(size); mem = (char*)malloc(size);
if (mem == NULL) { if (mem == NULL) {
free(buf); free(buf);
return -ENOMEM; return -ENOMEM;
@ -1660,7 +1555,7 @@ int fuse_fs_read_buf(struct fuse_fs *fs,
(unsigned long long) fi->fh, (unsigned long long) fi->fh,
fuse_buf_size(*bufp), fuse_buf_size(*bufp),
(unsigned long long) off); (unsigned long long) off);
if (res >= 0 && fuse_buf_size(*bufp) > (int) size) if ((res >= 0) && fuse_buf_size(*bufp) > size)
fprintf(stderr, "fuse: read too many bytes\n"); fprintf(stderr, "fuse: read too many bytes\n");
if (res < 0) if (res < 0)
@ -1683,83 +1578,98 @@ int fuse_fs_read(struct fuse_fs *fs, char *mem, size_t size,
struct fuse_bufvec dst = FUSE_BUFVEC_INIT(size); struct fuse_bufvec dst = FUSE_BUFVEC_INIT(size);
dst.buf[0].mem = mem; dst.buf[0].mem = mem;
res = fuse_buf_copy(&dst, buf, 0); res = fuse_buf_copy(&dst, buf, FUSE_BUF_FLAG_NONE);
} }
fuse_free_buf(buf); fuse_free_buf(buf);
return res; return res;
} }
int fuse_fs_write_buf(struct fuse_fs *fs, int
struct fuse_bufvec *buf, off_t off, fuse_fs_write_buf(struct fuse_fs *fs,
struct fuse_file_info *fi) struct fuse_bufvec *buf,
off_t off,
struct fuse_file_info *fi)
{ {
fuse_get_context()->private_data = fs->user_data; fuse_get_context()->private_data = fs->user_data;
if (fs->op.write_buf || fs->op.write) { if(fs->op.write_buf || fs->op.write)
int res; {
size_t size = fuse_buf_size(buf); int res;
size_t size = fuse_buf_size(buf);
assert(buf->idx == 0 && buf->off == 0); assert(buf->idx == 0 && buf->off == 0);
if (fs->debug) if (fs->debug)
fprintf(stderr, fprintf(stderr,
"write%s[%llu] %zu bytes to %llu flags: 0x%x\n", "write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
fi->writepage ? "page" : "", fi->writepage ? "page" : "",
(unsigned long long) fi->fh, (unsigned long long) fi->fh,
size, size,
(unsigned long long) off, (unsigned long long) off,
fi->flags); fi->flags);
if (fs->op.write_buf) { if (fs->op.write_buf)
res = fs->op.write_buf(buf, off, fi); {
} else { res = fs->op.write_buf(buf, off, fi);
void *mem = NULL; }
struct fuse_buf *flatbuf; else
struct fuse_bufvec tmp = FUSE_BUFVEC_INIT(size); {
char *mem = NULL;
struct fuse_buf *flatbuf;
struct fuse_bufvec tmp = FUSE_BUFVEC_INIT(size);
if (buf->count == 1 && if((buf->count == 1) &&
!(buf->buf[0].flags & FUSE_BUF_IS_FD)) { !(buf->buf[0].flags & FUSE_BUF_FLAG_IS_FD))
flatbuf = &buf->buf[0]; {
} else { flatbuf = &buf->buf[0];
res = -ENOMEM; }
mem = malloc(size); else
if (mem == NULL) {
goto out; res = -ENOMEM;
mem = (char*)malloc(size);
if (mem == NULL)
goto out;
tmp.buf[0].mem = mem; tmp.buf[0].mem = mem;
res = fuse_buf_copy(&tmp, buf, 0); res = fuse_buf_copy(&tmp, buf, FUSE_BUF_FLAG_NONE);
if (res <= 0) if (res <= 0)
goto out_free; goto out_free;
tmp.buf[0].size = res; tmp.buf[0].size = res;
flatbuf = &tmp.buf[0]; flatbuf = &tmp.buf[0];
} }
res = fs->op.write(flatbuf->mem, flatbuf->size, res = fs->op.write(flatbuf->mem, flatbuf->size,
off, fi); off, fi);
out_free: out_free:
free(mem); free(mem);
}
out:
if (fs->debug && res >= 0)
fprintf(stderr, " write%s[%llu] %u bytes to %llu\n",
fi->writepage ? "page" : "",
(unsigned long long) fi->fh, res,
(unsigned long long) off);
if (res > (int) size)
fprintf(stderr, "fuse: wrote too many bytes\n");
return res;
}
else
{
return -ENOSYS;
} }
out:
if (fs->debug && res >= 0)
fprintf(stderr, " write%s[%llu] %u bytes to %llu\n",
fi->writepage ? "page" : "",
(unsigned long long) fi->fh, res,
(unsigned long long) off);
if (res > (int) size)
fprintf(stderr, "fuse: wrote too many bytes\n");
return res;
} else {
return -ENOSYS;
}
} }
int fuse_fs_write(struct fuse_fs *fs, const char *mem, int
size_t size, off_t off, struct fuse_file_info *fi) fuse_fs_write(struct fuse_fs *fs,
const char *mem,
size_t size,
off_t off,
struct fuse_file_info *fi)
{ {
struct fuse_bufvec bufv = FUSE_BUFVEC_INIT(size); struct fuse_bufvec bufv = FUSE_BUFVEC_INIT(size);
bufv.buf[0].mem = (void *) mem; bufv.buf[0].mem = (char*)mem;
return fuse_fs_write_buf(fs, &bufv, off, fi); return fuse_fs_write_buf(fs, &bufv, off, fi);
} }
@ -3199,7 +3109,7 @@ static void fuse_lib_read(fuse_req_t req, fuse_ino_t ino, size_t size,
fuse_finish_interrupt(f, req, &d); fuse_finish_interrupt(f, req, &d);
if (res == 0) if (res == 0)
fuse_reply_data(req, buf, FUSE_BUF_SPLICE_MOVE); fuse_reply_data(req, buf, FUSE_BUF_COPY_FLAG_SPLICE_MOVE);
else else
reply_err(req, res); reply_err(req, res);
@ -3338,7 +3248,7 @@ readdir_buf_size(fuse_dirents_t *d_,
size_t size_, size_t size_,
off_t off_) off_t off_)
{ {
if(off_ >= kv_size(d_->offs)) if(off_ >= (off_t)kv_size(d_->offs))
return 0; return 0;
if((kv_A(d_->offs,off_) + size_) > d_->data_len) if((kv_A(d_->offs,off_) + size_) > d_->data_len)
return (d_->data_len - kv_A(d_->offs,off_)); return (d_->data_len - kv_A(d_->offs,off_));
@ -3694,16 +3604,18 @@ static int locks_insert(struct node *node, struct lock *lock)
struct lock *newl2 = NULL; struct lock *newl2 = NULL;
if (lock->type != F_UNLCK || lock->start != 0 || if (lock->type != F_UNLCK || lock->start != 0 ||
lock->end != OFFSET_MAX) { lock->end != OFFSET_MAX)
newl1 = malloc(sizeof(struct lock)); {
newl2 = malloc(sizeof(struct lock)); newl1 = (struct lock*)malloc(sizeof(struct lock));
newl2 = (struct lock*)malloc(sizeof(struct lock));
if (!newl1 || !newl2) { if(!newl1 || !newl2)
free(newl1); {
free(newl2); free(newl1);
return -ENOLCK; free(newl2);
return -ENOLCK;
}
} }
}
for (lp = &node->locks; *lp;) { for (lp = &node->locks; *lp;) {
struct lock *l = *lp; struct lock *l = *lp;
@ -3721,14 +3633,14 @@ static int locks_insert(struct node *node, struct lock *lock)
lock->start = l->start; lock->start = l->start;
if (lock->end < l->end) if (lock->end < l->end)
lock->end = l->end; lock->end = l->end;
goto delete; goto _delete;
} else { } else {
if (l->end < lock->start) if (l->end < lock->start)
goto skip; goto skip;
if (lock->end < l->start) if (lock->end < l->start)
break; break;
if (lock->start <= l->start && l->end <= lock->end) if (lock->start <= l->start && l->end <= lock->end)
goto delete; goto _delete;
if (l->end <= lock->end) { if (l->end <= lock->end) {
l->end = lock->start - 1; l->end = lock->start - 1;
goto skip; goto skip;
@ -3747,7 +3659,7 @@ static int locks_insert(struct node *node, struct lock *lock)
lp = &l->next; lp = &l->next;
continue; continue;
delete: _delete:
delete_lock(lp); delete_lock(lp);
} }
if (lock->type != F_UNLCK) { if (lock->type != F_UNLCK) {
@ -3958,12 +3870,13 @@ static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, unsigned long cmd, vo
else else
fi = *llfi; fi = *llfi;
if (out_bufsz) { if(out_bufsz)
err = -ENOMEM; {
out_buf = malloc(out_bufsz); err = -ENOMEM;
if (!out_buf) out_buf = (char*)malloc(out_bufsz);
goto err; if (!out_buf)
} goto err;
}
assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz); assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
if (out_buf) if (out_buf)
@ -4049,7 +3962,8 @@ int fuse_clean_cache(struct fuse *f)
double age; double age;
next = curr->next; next = curr->next;
lnode = list_entry(curr, struct node_lru, lru); lnode = ({ const list_head *__mptr = (curr); (struct node_lru*)((char*)__mptr - offsetof(struct node_lru,lru));});
//lnode = list_entry(curr, struct node_lru, lru);
node = &lnode->node; node = &lnode->node;
age = diff_timespec(&now, &lnode->forget_time); age = diff_timespec(&now, &lnode->forget_time);
@ -4071,49 +3985,52 @@ int fuse_clean_cache(struct fuse *f)
return clean_delay(f); return clean_delay(f);
} }
static struct fuse_lowlevel_ops fuse_path_ops = { static struct fuse_lowlevel_ops fuse_path_ops =
.init = fuse_lib_init, {
.destroy = fuse_lib_destroy, fuse_lib_init,
.lookup = fuse_lib_lookup, fuse_lib_destroy,
.forget = fuse_lib_forget, fuse_lib_lookup,
.forget_multi = fuse_lib_forget_multi, fuse_lib_forget,
.getattr = fuse_lib_getattr, fuse_lib_getattr,
.setattr = fuse_lib_setattr, fuse_lib_setattr,
.access = fuse_lib_access, fuse_lib_readlink,
.readlink = fuse_lib_readlink, fuse_lib_mknod,
.mknod = fuse_lib_mknod, fuse_lib_mkdir,
.mkdir = fuse_lib_mkdir, fuse_lib_unlink,
.unlink = fuse_lib_unlink, fuse_lib_rmdir,
.rmdir = fuse_lib_rmdir, fuse_lib_symlink,
.symlink = fuse_lib_symlink, fuse_lib_rename,
.rename = fuse_lib_rename, fuse_lib_link,
.link = fuse_lib_link, fuse_lib_open,
.create = fuse_lib_create, fuse_lib_read,
.open = fuse_lib_open, NULL,
.read = fuse_lib_read, fuse_lib_flush,
.write_buf = fuse_lib_write_buf, fuse_lib_release,
.flush = fuse_lib_flush, fuse_lib_fsync,
.release = fuse_lib_release, fuse_lib_opendir,
.fsync = fuse_lib_fsync, fuse_lib_readdir,
.opendir = fuse_lib_opendir, fuse_lib_readdir_plus,
.readdir = fuse_lib_readdir, fuse_lib_releasedir,
.readdir_plus = fuse_lib_readdir_plus, fuse_lib_fsyncdir,
.releasedir = fuse_lib_releasedir, fuse_lib_statfs,
.fsyncdir = fuse_lib_fsyncdir, fuse_lib_setxattr,
.statfs = fuse_lib_statfs, fuse_lib_getxattr,
.setxattr = fuse_lib_setxattr, fuse_lib_listxattr,
.getxattr = fuse_lib_getxattr, fuse_lib_removexattr,
.listxattr = fuse_lib_listxattr, fuse_lib_access,
.removexattr = fuse_lib_removexattr, fuse_lib_create,
.getlk = fuse_lib_getlk, fuse_lib_getlk,
.setlk = fuse_lib_setlk, fuse_lib_setlk,
.flock = fuse_lib_flock, fuse_lib_bmap,
.bmap = fuse_lib_bmap, fuse_lib_ioctl,
.ioctl = fuse_lib_ioctl, fuse_lib_poll,
.poll = fuse_lib_poll, fuse_lib_write_buf,
.fallocate = fuse_lib_fallocate, NULL,
.copy_file_range = fuse_lib_copy_file_range, fuse_lib_forget_multi,
}; fuse_lib_flock,
fuse_lib_fallocate,
fuse_lib_copy_file_range
};
int fuse_notify_poll(struct fuse_pollhandle *ph) int fuse_notify_poll(struct fuse_pollhandle *ph)
{ {
@ -4342,7 +4259,7 @@ static int node_table_init(struct node_table *t)
static void *fuse_prune_nodes(void *fuse) static void *fuse_prune_nodes(void *fuse)
{ {
struct fuse *f = fuse; struct fuse *f = (struct fuse*)fuse;
int sleep_time; int sleep_time;
while(1) { while(1) {

View File

@ -57,11 +57,11 @@ int
fuse_dirents_buf_resize(fuse_dirents_t *d_, fuse_dirents_buf_resize(fuse_dirents_t *d_,
uint64_t size_) uint64_t size_)
{ {
void *p; char *p;
if((d_->data_len + size_) >= d_->buf_len) if((d_->data_len + size_) >= d_->buf_len)
{ {
p = realloc(d_->buf,(d_->buf_len * 2)); p = (char*)realloc(d_->buf,(d_->buf_len * 2));
if(p == NULL) if(p == NULL)
return -errno; return -errno;
@ -73,7 +73,7 @@ fuse_dirents_buf_resize(fuse_dirents_t *d_,
} }
static static
void* fuse_dirent_t*
fuse_dirents_dirent_alloc(fuse_dirents_t *d_, fuse_dirents_dirent_alloc(fuse_dirents_t *d_,
uint64_t namelen_) uint64_t namelen_)
{ {
@ -95,13 +95,13 @@ fuse_dirents_dirent_alloc(fuse_dirents_t *d_,
} }
static static
void* fuse_direntplus_t*
fuse_dirents_direntplus_alloc(fuse_dirents_t *d_, fuse_dirents_direntplus_alloc(fuse_dirents_t *d_,
uint64_t namelen_) uint64_t namelen_)
{ {
int rv; int rv;
uint64_t size; uint64_t size;
fuse_dirent_t *d; fuse_direntplus_t *d;
size = fuse_direntplus_size(namelen_); size = fuse_direntplus_size(namelen_);
@ -109,7 +109,7 @@ fuse_dirents_direntplus_alloc(fuse_dirents_t *d_,
if(rv) if(rv)
return NULL; return NULL;
d = (fuse_dirent_t*)&d_->buf[d_->data_len]; d = (fuse_direntplus_t*)&d_->buf[d_->data_len];
d_->data_len += size; d_->data_len += size;
@ -379,9 +379,9 @@ fuse_dirents_reset(fuse_dirents_t *d_)
int int
fuse_dirents_init(fuse_dirents_t *d_) fuse_dirents_init(fuse_dirents_t *d_)
{ {
void *buf; char *buf;
buf = calloc(DEFAULT_SIZE,1); buf = (char*)calloc(DEFAULT_SIZE,1);
if(buf == NULL) if(buf == NULL)
return -ENOMEM; return -ENOMEM;

View File

@ -88,12 +88,11 @@ fuse_kern_chan_new(int fd_)
{ {
long pagesize; long pagesize;
size_t bufsize; size_t bufsize;
struct fuse_chan_ops op = struct fuse_chan_ops op;
{
.receive = fuse_kern_chan_receive, op.receive = fuse_kern_chan_receive;
.send = fuse_kern_chan_send, op.send = fuse_kern_chan_send;
.destroy = fuse_kern_chan_destroy, op.destroy = fuse_kern_chan_destroy;
};
pagesize = sysconf(_SC_PAGESIZE); pagesize = sysconf(_SC_PAGESIZE);

View File

@ -68,12 +68,12 @@ static void *fuse_do_work(void *data)
while (!fuse_session_exited(mt->se)) { while (!fuse_session_exited(mt->se)) {
struct fuse_chan *ch = mt->prevch; struct fuse_chan *ch = mt->prevch;
struct fuse_buf fbuf = { struct fuse_buf fbuf;
.mem = w->buf,
.size = w->bufsize,
};
int res; int res;
fbuf.mem = w->buf;
fbuf.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_buf(mt->se, &fbuf, &ch);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
@ -134,14 +134,14 @@ int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg)
static int fuse_loop_start_thread(struct fuse_mt *mt) static int fuse_loop_start_thread(struct fuse_mt *mt)
{ {
int res; int res;
struct fuse_worker *w = malloc(sizeof(struct fuse_worker)); struct fuse_worker *w = (struct fuse_worker*)malloc(sizeof(struct fuse_worker));
if (!w) { if (!w) {
fprintf(stderr, "fuse: failed to allocate worker structure\n"); fprintf(stderr, "fuse: failed to allocate worker structure\n");
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->prevch);
w->buf = calloc(w->bufsize,1); w->buf = (char*)calloc(w->bufsize,1);
w->mt = mt; w->mt = mt;
if (!w->buf) { if (!w->buf) {
fprintf(stderr, "fuse: failed to allocate read buffer\n"); fprintf(stderr, "fuse: failed to allocate read buffer\n");

View File

@ -6,8 +6,6 @@
See the file COPYING.LIB See the file COPYING.LIB
*/ */
#define _GNU_SOURCE
#include "config.h" #include "config.h"
#include "fuse_i.h" #include "fuse_i.h"
#include "fuse_kernel.h" #include "fuse_kernel.h"
@ -166,7 +164,7 @@ static struct fuse_req *fuse_ll_alloc_req(struct fuse_ll *f)
static int fuse_send_msg(struct fuse_ll *f, struct fuse_chan *ch, static int fuse_send_msg(struct fuse_ll *f, struct fuse_chan *ch,
struct iovec *iov, int count) struct iovec *iov, int count)
{ {
struct fuse_out_header *out = iov[0].iov_base; struct fuse_out_header *out = (fuse_out_header*)iov[0].iov_base;
out->len = iov_length(iov, count); out->len = iov_length(iov, count);
if (f->debug) { if (f->debug) {
@ -235,7 +233,7 @@ int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
int res; int res;
struct iovec *padded_iov; struct iovec *padded_iov;
padded_iov = malloc((count + 1) * sizeof(struct iovec)); padded_iov = (struct iovec*)malloc((count + 1) * sizeof(struct iovec));
if (padded_iov == NULL) if (padded_iov == NULL)
return fuse_reply_err(req, ENOMEM); return fuse_reply_err(req, ENOMEM);
@ -434,7 +432,7 @@ static int fuse_send_data_iov_fallback(struct fuse_ll *f, struct fuse_chan *ch,
/* Optimize common case */ /* Optimize common case */
if (buf->count == 1 && buf->idx == 0 && buf->off == 0 && if (buf->count == 1 && buf->idx == 0 && buf->off == 0 &&
!(buf->buf[0].flags & FUSE_BUF_IS_FD)) { !(buf->buf[0].flags & FUSE_BUF_FLAG_IS_FD)) {
/* FIXME: also avoid memory copy if there are multiple buffers /* FIXME: also avoid memory copy if there are multiple buffers
but none of them contain an fd */ but none of them contain an fd */
@ -448,8 +446,8 @@ static int fuse_send_data_iov_fallback(struct fuse_ll *f, struct fuse_chan *ch,
if (res != 0) if (res != 0)
return res; return res;
mem_buf.buf[0].mem = mbuf; mem_buf.buf[0].mem = (char*)mbuf;
res = fuse_buf_copy(&mem_buf, buf, 0); res = fuse_buf_copy(&mem_buf,buf,FUSE_BUF_FLAG_NONE);
if (res < 0) { if (res < 0) {
free(mbuf); free(mbuf);
return -res; return -res;
@ -481,11 +479,11 @@ static void fuse_ll_pipe_free(struct fuse_ll_pipe *llp)
#ifdef HAVE_SPLICE #ifdef HAVE_SPLICE
static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f) static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f)
{ {
struct fuse_ll_pipe *llp = pthread_getspecific(f->pipe_key); struct fuse_ll_pipe *llp = (fuse_ll_pipe*)pthread_getspecific(f->pipe_key);
if (llp == NULL) { if (llp == NULL) {
int res; int res;
llp = malloc(sizeof(struct fuse_ll_pipe)); llp = (struct fuse_ll_pipe*)malloc(sizeof(struct fuse_ll_pipe));
if (llp == NULL) if (llp == NULL)
return NULL; return NULL;
@ -518,24 +516,30 @@ static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f)
static void fuse_ll_clear_pipe(struct fuse_ll *f) static void fuse_ll_clear_pipe(struct fuse_ll *f)
{ {
struct fuse_ll_pipe *llp = pthread_getspecific(f->pipe_key); struct fuse_ll_pipe *llp = (struct fuse_ll_pipe*)pthread_getspecific(f->pipe_key);
if (llp) { if(llp)
pthread_setspecific(f->pipe_key, NULL); {
fuse_ll_pipe_free(llp); pthread_setspecific(f->pipe_key,NULL);
} fuse_ll_pipe_free(llp);
}
} }
#if defined(HAVE_SPLICE) && defined(HAVE_VMSPLICE) #if defined(HAVE_SPLICE) && defined(HAVE_VMSPLICE)
static int read_back(int fd, char *buf, size_t len) static
int
read_back(int fd,
void *buf_,
size_t len)
{ {
int res; int res;
char *buf = (char*)buf_;
res = read(fd, buf, len); res = read(fd, buf, len);
if (res == -1) { if (res == -1) {
fprintf(stderr, "fuse: internal error: failed to read back from pipe: %s\n", strerror(errno)); fprintf(stderr, "fuse: internal error: failed to read back from pipe: %s\n", strerror(errno));
return -EIO; return -EIO;
} }
if (res != len) { if (res != (int)len) {
fprintf(stderr, "fuse: internal error: short read back from pipe: %i from %zi\n", res, len); fprintf(stderr, "fuse: internal error: short read back from pipe: %i from %zi\n", res, len);
return -EIO; return -EIO;
} }
@ -548,7 +552,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
{ {
int res; int res;
size_t len = fuse_buf_size(buf); size_t len = fuse_buf_size(buf);
struct fuse_out_header *out = iov[0].iov_base; struct fuse_out_header *out = (struct fuse_out_header*)iov[0].iov_base;
struct fuse_ll_pipe *llp; struct fuse_ll_pipe *llp;
int splice_flags; int splice_flags;
size_t pipesize; size_t pipesize;
@ -560,12 +564,12 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
if (f->broken_splice_nonblock) if (f->broken_splice_nonblock)
goto fallback; goto fallback;
if (flags & FUSE_BUF_NO_SPLICE) if (flags & FUSE_BUF_COPY_FLAG_NO_SPLICE)
goto fallback; goto fallback;
total_fd_size = 0; total_fd_size = 0;
for (idx = buf->idx; idx < buf->count; idx++) { for (idx = buf->idx; idx < buf->count; idx++) {
if (buf->buf[idx].flags & FUSE_BUF_IS_FD) { if (buf->buf[idx].flags & FUSE_BUF_FLAG_IS_FD) {
total_fd_size = buf->buf[idx].size; total_fd_size = buf->buf[idx].size;
if (idx == buf->idx) if (idx == buf->idx)
total_fd_size -= buf->off; total_fd_size -= buf->off;
@ -611,18 +615,18 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
if (res == -1) if (res == -1)
goto fallback; goto fallback;
if (res != headerlen) { if (res != (int)headerlen) {
res = -EIO; res = -EIO;
fprintf(stderr, "fuse: short vmsplice to pipe: %u/%zu\n", res, fprintf(stderr, "fuse: short vmsplice to pipe: %u/%zu\n", res,
headerlen); headerlen);
goto clear_pipe; goto clear_pipe;
} }
pipe_buf.buf[0].flags = FUSE_BUF_IS_FD; pipe_buf.buf[0].flags = FUSE_BUF_FLAG_IS_FD;
pipe_buf.buf[0].fd = llp->pipe[1]; pipe_buf.buf[0].fd = llp->pipe[1];
res = fuse_buf_copy(&pipe_buf, buf, res = fuse_buf_copy(&pipe_buf, buf,
FUSE_BUF_FORCE_SPLICE | FUSE_BUF_SPLICE_NONBLOCK); FUSE_BUF_COPY_FLAG_FORCE_SPLICE | FUSE_BUF_COPY_FLAG_SPLICE_NONBLOCK);
if (res < 0) { if (res < 0) {
if (res == -EAGAIN || res == -EINVAL) { if (res == -EAGAIN || res == -EINVAL) {
/* /*
@ -646,7 +650,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
goto clear_pipe; goto clear_pipe;
} }
if (res != 0 && res < len) { if (res != 0 && (res < (int)len)) {
struct fuse_bufvec mem_buf = FUSE_BUFVEC_INIT(len); struct fuse_bufvec mem_buf = FUSE_BUFVEC_INIT(len);
void *mbuf; void *mbuf;
size_t now_len = res; size_t now_len = res;
@ -663,9 +667,9 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
if (res != 0) if (res != 0)
goto clear_pipe; goto clear_pipe;
mem_buf.buf[0].mem = mbuf; mem_buf.buf[0].mem = (char*)mbuf;
mem_buf.off = now_len; mem_buf.off = now_len;
res = fuse_buf_copy(&mem_buf, buf, 0); res = fuse_buf_copy(&mem_buf, buf, FUSE_BUF_FLAG_NONE);
if (res > 0) { if (res > 0) {
char *tmpbuf; char *tmpbuf;
size_t extra_len = res; size_t extra_len = res;
@ -674,7 +678,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
* back the data from the pipe and then fall * back the data from the pipe and then fall
* back to regular write. * back to regular write.
*/ */
tmpbuf = malloc(headerlen); tmpbuf = (char*)malloc(headerlen);
if (tmpbuf == NULL) { if (tmpbuf == NULL) {
free(mbuf); free(mbuf);
res = ENOMEM; res = ENOMEM;
@ -686,7 +690,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
free(mbuf); free(mbuf);
goto clear_pipe; goto clear_pipe;
} }
res = read_back(llp->pipe[0], mbuf, now_len); res = read_back(llp->pipe[0],mbuf,now_len);
if (res != 0) { if (res != 0) {
free(mbuf); free(mbuf);
goto clear_pipe; goto clear_pipe;
@ -712,7 +716,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
} }
splice_flags = 0; splice_flags = 0;
if ((flags & FUSE_BUF_SPLICE_MOVE) && if ((flags & FUSE_BUF_COPY_FLAG_SPLICE_MOVE) &&
(f->conn.want & FUSE_CAP_SPLICE_MOVE)) (f->conn.want & FUSE_CAP_SPLICE_MOVE))
splice_flags |= SPLICE_F_MOVE; splice_flags |= SPLICE_F_MOVE;
@ -723,7 +727,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
perror("fuse: splice from pipe"); perror("fuse: splice from pipe");
goto clear_pipe; goto clear_pipe;
} }
if (res != out->len) { if (res != (int)out->len) {
res = -EIO; res = -EIO;
fprintf(stderr, "fuse: short splice from pipe: %u/%u\n", fprintf(stderr, "fuse: short splice from pipe: %u/%u\n",
res, out->len); res, out->len);
@ -750,8 +754,10 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
} }
#endif #endif
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, int
enum fuse_buf_copy_flags flags) fuse_reply_data(fuse_req_t req,
struct fuse_bufvec *bufv,
int flags)
{ {
struct iovec iov[2]; struct iovec iov[2];
struct fuse_out_header out; struct fuse_out_header out;
@ -827,7 +833,7 @@ static struct fuse_ioctl_iovec *fuse_ioctl_iovec_copy(const struct iovec *iov,
struct fuse_ioctl_iovec *fiov; struct fuse_ioctl_iovec *fiov;
size_t i; size_t i;
fiov = malloc(sizeof(fiov[0]) * count); fiov = (struct fuse_ioctl_iovec*)malloc(sizeof(fiov[0]) * count);
if (!fiov) if (!fiov)
return NULL; return NULL;
@ -942,7 +948,7 @@ int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov,
struct fuse_ioctl_out arg; struct fuse_ioctl_out arg;
int res; int res;
padded_iov = malloc((count + 2) * sizeof(struct iovec)); padded_iov = (struct iovec*)malloc((count + 2) * sizeof(struct iovec));
if (padded_iov == NULL) if (padded_iov == NULL)
return fuse_reply_err(req, ENOMEM); return fuse_reply_err(req, ENOMEM);
@ -992,8 +998,8 @@ static void do_forget(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
static void do_batch_forget(fuse_req_t req, fuse_ino_t nodeid, static void do_batch_forget(fuse_req_t req, fuse_ino_t nodeid,
const void *inarg) const void *inarg)
{ {
struct fuse_batch_forget_in *arg = (void *) inarg; struct fuse_batch_forget_in *arg = (struct fuse_batch_forget_in*)inarg;
struct fuse_forget_one *param = (void *) PARAM(arg); struct fuse_forget_one *param = (struct fuse_forget_one*)PARAM(arg);
unsigned int i; unsigned int i;
(void) nodeid; (void) nodeid;
@ -1270,13 +1276,12 @@ static void do_write_buf(fuse_req_t req, fuse_ino_t nodeid, const void *inarg,
const struct fuse_buf *ibuf) const struct fuse_buf *ibuf)
{ {
struct fuse_ll *f = req->f; struct fuse_ll *f = req->f;
struct fuse_bufvec bufv = { struct fuse_bufvec bufv;
.buf[0] = *ibuf,
.count = 1,
};
struct fuse_write_in *arg = (struct fuse_write_in *) inarg; struct fuse_write_in *arg = (struct fuse_write_in *) inarg;
struct fuse_file_info fi; struct fuse_file_info fi;
bufv.buf[0] = *ibuf;
bufv.count = 1;
memset(&fi, 0, sizeof(fi)); memset(&fi, 0, sizeof(fi));
fi.fh = arg->fh; fi.fh = arg->fh;
fi.writepage = arg->write_flags & 1; fi.writepage = arg->write_flags & 1;
@ -1285,11 +1290,11 @@ static void do_write_buf(fuse_req_t req, fuse_ino_t nodeid, const void *inarg,
bufv.buf[0].mem = ((char *) arg) + FUSE_COMPAT_WRITE_IN_SIZE; bufv.buf[0].mem = ((char *) arg) + FUSE_COMPAT_WRITE_IN_SIZE;
bufv.buf[0].size -= sizeof(struct fuse_in_header) + bufv.buf[0].size -= sizeof(struct fuse_in_header) +
FUSE_COMPAT_WRITE_IN_SIZE; FUSE_COMPAT_WRITE_IN_SIZE;
assert(!(bufv.buf[0].flags & FUSE_BUF_IS_FD)); assert(!(bufv.buf[0].flags & FUSE_BUF_FLAG_IS_FD));
} else { } else {
fi.lock_owner = arg->lock_owner; fi.lock_owner = arg->lock_owner;
fi.flags = arg->flags; fi.flags = arg->flags;
if (!(bufv.buf[0].flags & FUSE_BUF_IS_FD)) if (!(bufv.buf[0].flags & FUSE_BUF_FLAG_IS_FD))
bufv.buf[0].mem = PARAM(arg); bufv.buf[0].mem = PARAM(arg);
bufv.buf[0].size -= sizeof(struct fuse_in_header) + bufv.buf[0].size -= sizeof(struct fuse_in_header) +
@ -1306,7 +1311,7 @@ static void do_write_buf(fuse_req_t req, fuse_ino_t nodeid, const void *inarg,
out: out:
/* Need to reset the pipe if ->write_buf() didn't consume all data */ /* Need to reset the pipe if ->write_buf() didn't consume all data */
if ((ibuf->flags & FUSE_BUF_IS_FD) && bufv.idx < bufv.count) if ((ibuf->flags & FUSE_BUF_FLAG_IS_FD) && bufv.idx < bufv.count)
fuse_ll_clear_pipe(f); fuse_ll_clear_pipe(f);
} }
@ -1447,10 +1452,9 @@ static void do_statfs(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
if (req->f->op.statfs) if (req->f->op.statfs)
req->f->op.statfs(req, nodeid); req->f->op.statfs(req, nodeid);
else { else {
struct statvfs buf = { struct statvfs buf;
.f_namemax = 255, buf.f_namemax = 255;
.f_bsize = 512, buf.f_bsize = 512;
};
fuse_reply_statfs(req, &buf); fuse_reply_statfs(req, &buf);
} }
} }
@ -1600,7 +1604,7 @@ static int find_interrupted(struct fuse_ll *f, struct fuse_req *req)
data = curr->u.ni.data; data = curr->u.ni.data;
pthread_mutex_unlock(&f->lock); pthread_mutex_unlock(&f->lock);
if (func) if (func)
func(curr, data); func(curr,(fuse_intr_data*)data);
pthread_mutex_unlock(&curr->lock); pthread_mutex_unlock(&curr->lock);
pthread_mutex_lock(&f->lock); pthread_mutex_lock(&f->lock);
@ -1717,7 +1721,7 @@ static void do_poll(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
struct fuse_pollhandle *ph = NULL; struct fuse_pollhandle *ph = NULL;
if (arg->flags & FUSE_POLL_SCHEDULE_NOTIFY) { if (arg->flags & FUSE_POLL_SCHEDULE_NOTIFY) {
ph = malloc(sizeof(struct fuse_pollhandle)); ph = (struct fuse_pollhandle*)malloc(sizeof(struct fuse_pollhandle));
if (ph == NULL) { if (ph == NULL) {
fuse_reply_err(req, ENOMEM); fuse_reply_err(req, ENOMEM);
return; return;
@ -2146,7 +2150,7 @@ int fuse_lowlevel_notify_delete(struct fuse_chan *ch,
int fuse_lowlevel_notify_store(struct fuse_chan *ch, fuse_ino_t ino, int fuse_lowlevel_notify_store(struct fuse_chan *ch, fuse_ino_t ino,
off_t offset, struct fuse_bufvec *bufv, off_t offset, struct fuse_bufvec *bufv,
enum fuse_buf_copy_flags flags) int flags)
{ {
struct fuse_out_header out; struct fuse_out_header out;
struct fuse_notify_store_out outarg; struct fuse_notify_store_out outarg;
@ -2198,13 +2202,12 @@ static void fuse_ll_retrieve_reply(struct fuse_notify_req *nreq,
struct fuse_ll *f = req->f; struct fuse_ll *f = req->f;
struct fuse_retrieve_req *rreq = struct fuse_retrieve_req *rreq =
container_of(nreq, struct fuse_retrieve_req, nreq); container_of(nreq, struct fuse_retrieve_req, nreq);
const struct fuse_notify_retrieve_in *arg = inarg; const struct fuse_notify_retrieve_in *arg = (struct fuse_notify_retrieve_in*)inarg;
struct fuse_bufvec bufv = { struct fuse_bufvec bufv;
.buf[0] = *ibuf,
.count = 1,
};
if (!(bufv.buf[0].flags & FUSE_BUF_IS_FD)) bufv.buf[0] = *ibuf;
bufv.count = 1;
if (!(bufv.buf[0].flags & FUSE_BUF_FLAG_IS_FD))
bufv.buf[0].mem = PARAM(arg); bufv.buf[0].mem = PARAM(arg);
bufv.buf[0].size -= sizeof(struct fuse_in_header) + bufv.buf[0].size -= sizeof(struct fuse_in_header) +
@ -2225,7 +2228,7 @@ static void fuse_ll_retrieve_reply(struct fuse_notify_req *nreq,
} }
out: out:
free(rreq); free(rreq);
if ((ibuf->flags & FUSE_BUF_IS_FD) && bufv.idx < bufv.count) if ((ibuf->flags & FUSE_BUF_FLAG_IS_FD) && bufv.idx < bufv.count)
fuse_ll_clear_pipe(f); fuse_ll_clear_pipe(f);
} }
@ -2248,7 +2251,7 @@ int fuse_lowlevel_notify_retrieve(struct fuse_chan *ch, fuse_ino_t ino,
if (f->conn.proto_minor < 15) if (f->conn.proto_minor < 15)
return -ENOSYS; return -ENOSYS;
rreq = malloc(sizeof(*rreq)); rreq = (struct fuse_retrieve_req*)malloc(sizeof(*rreq));
if (rreq == NULL) if (rreq == NULL)
return -ENOMEM; return -ENOMEM;
@ -2297,7 +2300,7 @@ void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func,
req->u.ni.data = data; req->u.ni.data = data;
pthread_mutex_unlock(&req->f->lock); pthread_mutex_unlock(&req->f->lock);
if (req->interrupted && func) if (req->interrupted && func)
func(req, data); func(req,(fuse_intr_data*)data);
pthread_mutex_unlock(&req->lock); pthread_mutex_unlock(&req->lock);
} }
@ -2312,55 +2315,12 @@ int fuse_req_interrupted(fuse_req_t req)
return interrupted; return interrupted;
} }
typedef void (*fuse_ll_func_t)(fuse_req_t,fuse_ino_t,const void*);
static struct { static struct {
void (*func)(fuse_req_t, fuse_ino_t, const void *); fuse_ll_func_t func;
const char *name; const char *name;
} fuse_ll_ops[] = } fuse_ll_ops[FUSE_REMOVEMAPPING];
{
[FUSE_LOOKUP] = { do_lookup, "LOOKUP" },
[FUSE_FORGET] = { do_forget, "FORGET" },
[FUSE_GETATTR] = { do_getattr, "GETATTR" },
[FUSE_SETATTR] = { do_setattr, "SETATTR" },
[FUSE_READLINK] = { do_readlink, "READLINK" },
[FUSE_SYMLINK] = { do_symlink, "SYMLINK" },
[FUSE_MKNOD] = { do_mknod, "MKNOD" },
[FUSE_MKDIR] = { do_mkdir, "MKDIR" },
[FUSE_UNLINK] = { do_unlink, "UNLINK" },
[FUSE_RMDIR] = { do_rmdir, "RMDIR" },
[FUSE_RENAME] = { do_rename, "RENAME" },
[FUSE_LINK] = { do_link, "LINK" },
[FUSE_OPEN] = { do_open, "OPEN" },
[FUSE_READ] = { do_read, "READ" },
[FUSE_WRITE] = { do_write, "WRITE" },
[FUSE_STATFS] = { do_statfs, "STATFS" },
[FUSE_RELEASE] = { do_release, "RELEASE" },
[FUSE_FSYNC] = { do_fsync, "FSYNC" },
[FUSE_SETXATTR] = { do_setxattr, "SETXATTR" },
[FUSE_GETXATTR] = { do_getxattr, "GETXATTR" },
[FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" },
[FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" },
[FUSE_FLUSH] = { do_flush, "FLUSH" },
[FUSE_INIT] = { do_init, "INIT" },
[FUSE_OPENDIR] = { do_opendir, "OPENDIR" },
[FUSE_READDIR] = { do_readdir, "READDIR" },
[FUSE_READDIRPLUS] = { do_readdir_plus, "READDIR_PLUS" },
[FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" },
[FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" },
[FUSE_GETLK] = { do_getlk, "GETLK" },
[FUSE_SETLK] = { do_setlk, "SETLK" },
[FUSE_SETLKW] = { do_setlkw, "SETLKW" },
[FUSE_ACCESS] = { do_access, "ACCESS" },
[FUSE_CREATE] = { do_create, "CREATE" },
[FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
[FUSE_BMAP] = { do_bmap, "BMAP" },
[FUSE_IOCTL] = { do_ioctl, "IOCTL" },
[FUSE_POLL] = { do_poll, "POLL" },
[FUSE_FALLOCATE] = { do_fallocate, "FALLOCATE" },
[FUSE_DESTROY] = { do_destroy, "DESTROY" },
[FUSE_NOTIFY_REPLY] = { (void *) 1, "NOTIFY_REPLY" },
[FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
[FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" },
};
#define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0])) #define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
@ -2380,7 +2340,7 @@ static int fuse_ll_copy_from_pipe(struct fuse_bufvec *dst,
fprintf(stderr, "fuse: copy from pipe: %s\n", strerror(-res)); fprintf(stderr, "fuse: copy from pipe: %s\n", strerror(-res));
return res; return res;
} }
if (res < fuse_buf_size(dst)) { if (res < (int)fuse_buf_size(dst)) {
fprintf(stderr, "fuse: copy from pipe: short read\n"); fprintf(stderr, "fuse: copy from pipe: short read\n");
return -1; return -1;
} }
@ -2393,33 +2353,35 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
struct fuse_ll *f = (struct fuse_ll *) data; struct fuse_ll *f = (struct fuse_ll *) data;
const size_t write_header_size = sizeof(struct fuse_in_header) + const size_t write_header_size = sizeof(struct fuse_in_header) +
sizeof(struct fuse_write_in); sizeof(struct fuse_write_in);
struct fuse_bufvec bufv = { .buf[0] = *buf, .count = 1 }; struct fuse_bufvec bufv;
struct fuse_bufvec tmpbuf = FUSE_BUFVEC_INIT(write_header_size); struct fuse_bufvec tmpbuf = FUSE_BUFVEC_INIT(write_header_size);
struct fuse_in_header *in; struct fuse_in_header *in;
const void *inarg; const void *inarg;
struct fuse_req *req; struct fuse_req *req;
void *mbuf = NULL; char *mbuf = NULL;
int err; int err;
int res; int res;
if (buf->flags & FUSE_BUF_IS_FD) { bufv.buf[0] = *buf;
bufv.count = 1;
if (buf->flags & FUSE_BUF_FLAG_IS_FD) {
if (buf->size < tmpbuf.buf[0].size) if (buf->size < tmpbuf.buf[0].size)
tmpbuf.buf[0].size = buf->size; tmpbuf.buf[0].size = buf->size;
mbuf = malloc(tmpbuf.buf[0].size); mbuf = (char*)malloc(tmpbuf.buf[0].size);
if (mbuf == NULL) { if (mbuf == NULL) {
fprintf(stderr, "fuse: failed to allocate header\n"); fprintf(stderr, "fuse: failed to allocate header\n");
goto clear_pipe; goto clear_pipe;
} }
tmpbuf.buf[0].mem = mbuf; tmpbuf.buf[0].mem = (char*)mbuf;
res = fuse_ll_copy_from_pipe(&tmpbuf, &bufv); res = fuse_ll_copy_from_pipe(&tmpbuf, &bufv);
if (res < 0) if (res < 0)
goto clear_pipe; goto clear_pipe;
in = mbuf; in = (fuse_in_header*)mbuf;
} else { } else {
in = buf->mem; in = (fuse_in_header*)buf->mem;
} }
if (f->debug) { if (f->debug) {
@ -2431,19 +2393,20 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
} }
req = fuse_ll_alloc_req(f); req = fuse_ll_alloc_req(f);
if (req == NULL) { if (req == NULL)
struct fuse_out_header out = { {
.unique = in->unique, struct fuse_out_header out;
.error = -ENOMEM, struct iovec iov;
};
struct iovec iov = {
.iov_base = &out,
.iov_len = sizeof(struct fuse_out_header),
};
fuse_send_msg(f, ch, &iov, 1); out.unique = in->unique;
goto clear_pipe; out.error = -ENOMEM;
}
iov.iov_base = &out;
iov.iov_len = sizeof(struct fuse_out_header);
fuse_send_msg(f, ch, &iov, 1);
goto clear_pipe;
}
req->unique = in->unique; req->unique = in->unique;
req->ctx.uid = in->uid; req->ctx.uid = in->uid;
@ -2492,7 +2455,7 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
fuse_reply_err(intr, EAGAIN); fuse_reply_err(intr, EAGAIN);
} }
if ((buf->flags & FUSE_BUF_IS_FD) && write_header_size < buf->size && if ((buf->flags & FUSE_BUF_FLAG_IS_FD) && write_header_size < buf->size &&
(in->opcode != FUSE_WRITE || !f->op.write_buf) && (in->opcode != FUSE_WRITE || !f->op.write_buf) &&
in->opcode != FUSE_NOTIFY_REPLY) { in->opcode != FUSE_NOTIFY_REPLY) {
void *newmbuf; void *newmbuf;
@ -2501,7 +2464,7 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
newmbuf = realloc(mbuf, buf->size); newmbuf = realloc(mbuf, buf->size);
if (newmbuf == NULL) if (newmbuf == NULL)
goto reply_err; goto reply_err;
mbuf = newmbuf; mbuf = (char*)newmbuf;
tmpbuf = FUSE_BUFVEC_INIT(buf->size - write_header_size); tmpbuf = FUSE_BUFVEC_INIT(buf->size - write_header_size);
tmpbuf.buf[0].mem = mbuf + write_header_size; tmpbuf.buf[0].mem = mbuf + write_header_size;
@ -2511,7 +2474,7 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
if (res < 0) if (res < 0)
goto reply_err; goto reply_err;
in = mbuf; in = (fuse_in_header*)mbuf;
} }
inarg = (void *) &in[1]; inarg = (void *) &in[1];
@ -2529,7 +2492,7 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
reply_err: reply_err:
fuse_reply_err(req, err); fuse_reply_err(req, err);
clear_pipe: clear_pipe:
if (buf->flags & FUSE_BUF_IS_FD) if (buf->flags & FUSE_BUF_FLAG_IS_FD)
fuse_ll_clear_pipe(f); fuse_ll_clear_pipe(f);
goto out_free; goto out_free;
} }
@ -2537,10 +2500,10 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
static void fuse_ll_process(void *data, const char *buf, size_t len, static void fuse_ll_process(void *data, const char *buf, size_t len,
struct fuse_chan *ch) struct fuse_chan *ch)
{ {
struct fuse_buf fbuf = { struct fuse_buf fbuf;
.mem = (void *) buf,
.size = len, fbuf.mem = (char*)buf;
}; fbuf.size = len;
fuse_ll_process_buf(data, &fbuf, ch); fuse_ll_process_buf(data, &fbuf, ch);
} }
@ -2632,7 +2595,7 @@ static void fuse_ll_destroy(void *data)
if (f->op.destroy) if (f->op.destroy)
f->op.destroy(f->userdata); f->op.destroy(f->userdata);
} }
llp = pthread_getspecific(f->pipe_key); llp = (fuse_ll_pipe*)pthread_getspecific(f->pipe_key);
if (llp != NULL) if (llp != NULL)
fuse_ll_pipe_free(llp); fuse_ll_pipe_free(llp);
pthread_key_delete(f->pipe_key); pthread_key_delete(f->pipe_key);
@ -2642,7 +2605,7 @@ static void fuse_ll_destroy(void *data)
static void fuse_ll_pipe_destructor(void *data) static void fuse_ll_pipe_destructor(void *data)
{ {
struct fuse_ll_pipe *llp = data; struct fuse_ll_pipe *llp = (fuse_ll_pipe*)data;
fuse_ll_pipe_free(llp); fuse_ll_pipe_free(llp);
} }
@ -2651,7 +2614,7 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
struct fuse_chan **chp) struct fuse_chan **chp)
{ {
struct fuse_chan *ch = *chp; struct fuse_chan *ch = *chp;
struct fuse_ll *f = fuse_session_data(se); struct fuse_ll *f = (fuse_ll*)fuse_session_data(se);
size_t bufsize = buf->size; size_t bufsize = buf->size;
struct fuse_ll_pipe *llp; struct fuse_ll_pipe *llp;
struct fuse_buf tmpbuf; struct fuse_buf tmpbuf;
@ -2694,26 +2657,28 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
return -err; return -err;
} }
if (res < sizeof(struct fuse_in_header)) { if (res < (int)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;
} }
tmpbuf = (struct fuse_buf) { tmpbuf.size = (size_t)res;
.size = res, tmpbuf.flags = FUSE_BUF_FLAG_IS_FD;
.flags = FUSE_BUF_IS_FD, tmpbuf.fd = llp->pipe[0];
.fd = llp->pipe[0],
};
/* /*
* Don't bother with zero copy for small requests. * Don't bother with zero copy for small requests.
* fuse_loop_mt() needs to check for FORGET so this more than * fuse_loop_mt() needs to check for FORGET so this more than
* just an optimization. * just an optimization.
*/ */
if (res < sizeof(struct fuse_in_header) + if (res < (int)(sizeof(struct fuse_in_header) + sizeof(struct fuse_write_in) + pagesize)) {
sizeof(struct fuse_write_in) + pagesize) { struct fuse_bufvec src;
struct fuse_bufvec src = { .buf[0] = tmpbuf, .count = 1 }; struct fuse_bufvec dst;
struct fuse_bufvec dst = { .buf[0] = *buf, .count = 1 };
src.buf[0] = tmpbuf;
src.count = 1;
dst.buf[0] = *buf;
dst.count = 1;
res = fuse_buf_copy(&dst, &src, 0); res = fuse_buf_copy(&dst, &src, 0);
if (res < 0) { if (res < 0) {
@ -2722,7 +2687,7 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
fuse_ll_clear_pipe(f); fuse_ll_clear_pipe(f);
return res; return res;
} }
if (res < tmpbuf.size) { if (res < (int)tmpbuf.size) {
fprintf(stderr, "fuse: copy from pipe: short read\n"); fprintf(stderr, "fuse: copy from pipe: short read\n");
fuse_ll_clear_pipe(f); fuse_ll_clear_pipe(f);
return -EIO; return -EIO;
@ -2760,6 +2725,53 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
} }
#endif #endif
static
void
fuse_lowlevel_setup_ops(void)
{
fuse_ll_ops[FUSE_ACCESS] = { do_access, "ACCESS" };
fuse_ll_ops[FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" };
fuse_ll_ops[FUSE_BMAP] = { do_bmap, "BMAP" };
fuse_ll_ops[FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" };
fuse_ll_ops[FUSE_CREATE] = { do_create, "CREATE" };
fuse_ll_ops[FUSE_DESTROY] = { do_destroy, "DESTROY" };
fuse_ll_ops[FUSE_FALLOCATE] = { do_fallocate, "FALLOCATE" };
fuse_ll_ops[FUSE_FLUSH] = { do_flush, "FLUSH" };
fuse_ll_ops[FUSE_FORGET] = { do_forget, "FORGET" };
fuse_ll_ops[FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" };
fuse_ll_ops[FUSE_FSYNC] = { do_fsync, "FSYNC" };
fuse_ll_ops[FUSE_GETATTR] = { do_getattr, "GETATTR" };
fuse_ll_ops[FUSE_GETLK] = { do_getlk, "GETLK" };
fuse_ll_ops[FUSE_GETXATTR] = { do_getxattr, "GETXATTR" };
fuse_ll_ops[FUSE_INIT] = { do_init, "INIT" };
fuse_ll_ops[FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" };
fuse_ll_ops[FUSE_IOCTL] = { do_ioctl, "IOCTL" };
fuse_ll_ops[FUSE_LINK] = { do_link, "LINK" };
fuse_ll_ops[FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" };
fuse_ll_ops[FUSE_LOOKUP] = { do_lookup, "LOOKUP" };
fuse_ll_ops[FUSE_MKDIR] = { do_mkdir, "MKDIR" };
fuse_ll_ops[FUSE_MKNOD] = { do_mknod, "MKNOD" };
fuse_ll_ops[FUSE_OPENDIR] = { do_opendir, "OPENDIR" };
fuse_ll_ops[FUSE_OPEN] = { do_open, "OPEN" };
fuse_ll_ops[FUSE_POLL] = { do_poll, "POLL" };
fuse_ll_ops[FUSE_READDIR] = { do_readdir, "READDIR" };
fuse_ll_ops[FUSE_READDIRPLUS] = { do_readdir_plus, "READDIRPLUS" };
fuse_ll_ops[FUSE_READLINK] = { do_readlink, "READLINK" };
fuse_ll_ops[FUSE_READ] = { do_read, "READ" };
fuse_ll_ops[FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" };
fuse_ll_ops[FUSE_RELEASE] = { do_release, "RELEASE" };
fuse_ll_ops[FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" };
fuse_ll_ops[FUSE_RENAME] = { do_rename, "RENAME" };
fuse_ll_ops[FUSE_RMDIR] = { do_rmdir, "RMDIR" };
fuse_ll_ops[FUSE_SETATTR] = { do_setattr, "SETATTR" };
fuse_ll_ops[FUSE_SETLKW] = { do_setlkw, "SETLKW" };
fuse_ll_ops[FUSE_SETLK] = { do_setlk, "SETLK" };
fuse_ll_ops[FUSE_SETXATTR] = { do_setxattr, "SETXATTR" };
fuse_ll_ops[FUSE_STATFS] = { do_statfs, "STATFS" };
fuse_ll_ops[FUSE_SYMLINK] = { do_symlink, "SYMLINK" };
fuse_ll_ops[FUSE_UNLINK] = { do_unlink, "UNLINK" };
fuse_ll_ops[FUSE_WRITE] = { do_write, "WRITE" };
}
/* /*
* always call fuse_lowlevel_new_common() internally, to work around a * always call fuse_lowlevel_new_common() internally, to work around a
@ -2773,10 +2785,12 @@ struct fuse_session *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 = { struct fuse_session_ops sop;
.process = fuse_ll_process,
.destroy = fuse_ll_destroy, fuse_lowlevel_setup_ops();
};
sop.process = fuse_ll_process;
sop.destroy = fuse_ll_destroy;
if (sizeof(struct fuse_lowlevel_ops) < op_size) { if (sizeof(struct fuse_lowlevel_ops) < op_size) {
fprintf(stderr, "fuse: warning: library too old, some operations may not work\n"); fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");

View File

@ -75,14 +75,14 @@ int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data)
struct fuse_session *se; struct fuse_session *se;
struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL); struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL);
struct fuse_chan *ch; struct fuse_chan *ch;
struct fuse_session_ops sop = { struct fuse_session_ops sop;
.exit = mt_session_exit, struct fuse_chan_ops cop;
.exited = mt_session_exited,
.process = mt_session_proc, sop.exit = mt_session_exit;
}; sop.exited = mt_session_exited;
struct fuse_chan_ops cop = { sop.process = mt_session_proc;
.receive = mt_chan_receive,
}; cop.receive = mt_chan_receive;
pd.f = f; pd.f = f;
pd.prevch = prevch; pd.prevch = prevch;

View File

@ -63,7 +63,7 @@ fuse_opt_add_arg(struct fuse_args *args, const char *arg)
if (!newarg) if (!newarg)
return alloc_failed(); return alloc_failed();
newargv = realloc(args->argv, (args->argc + 2) * sizeof(char *)); newargv = (char**)realloc(args->argv, (args->argc + 2) * sizeof(char *));
if (!newargv) { if (!newargv) {
free(newarg); free(newarg);
return alloc_failed(); return alloc_failed();
@ -115,7 +115,7 @@ static int add_arg(struct fuse_opt_context *ctx, const char *arg)
static int add_opt_common(char **opts, const char *opt, int esc) static int add_opt_common(char **opts, const char *opt, int esc)
{ {
unsigned oldlen = *opts ? strlen(*opts) : 0; unsigned oldlen = *opts ? strlen(*opts) : 0;
char *d = realloc(*opts, oldlen + 1 + strlen(opt) * 2 + 1); char *d = (char*)realloc(*opts, oldlen + 1 + strlen(opt) * 2 + 1);
if (!d) if (!d)
return alloc_failed(); return alloc_failed();
@ -231,7 +231,7 @@ static int process_opt(struct fuse_opt_context *ctx,
if (call_proc(ctx, arg, opt->value, iso) == -1) if (call_proc(ctx, arg, opt->value, iso) == -1)
return -1; return -1;
} else { } else {
void *var = ctx->data + opt->offset; void *var = (char*)ctx->data + opt->offset;
if (sep && opt->templ[sep + 1]) { if (sep && opt->templ[sep + 1]) {
const char *param = arg + sep; const char *param = arg + sep;
if (opt->templ[sep] == '=') if (opt->templ[sep] == '=')
@ -257,7 +257,7 @@ static int process_opt_sep_arg(struct fuse_opt_context *ctx,
return -1; return -1;
param = ctx->argv[ctx->argctr]; param = ctx->argv[ctx->argctr];
newarg = malloc(sep + strlen(param) + 1); newarg = (char*)malloc(sep + strlen(param) + 1);
if (!newarg) if (!newarg)
return alloc_failed(); return alloc_failed();
@ -397,15 +397,14 @@ int fuse_opt_parse(struct fuse_args *args, void *data,
const struct fuse_opt opts[], fuse_opt_proc_t proc) const struct fuse_opt opts[], fuse_opt_proc_t proc)
{ {
int res; int res;
struct fuse_opt_context ctx = { struct fuse_opt_context ctx;
.data = data,
.opt = opts,
.proc = proc,
};
if (!args || !args->argv || !args->argc) if(!args || !args->argv || !args->argc)
return 0; return 0;
ctx.data = data;
ctx.opt = opts;
ctx.proc = proc;
ctx.argc = args->argc; ctx.argc = args->argc;
ctx.argv = args->argv; ctx.argv = args->argv;

View File

@ -79,8 +79,8 @@ void fuse_session_process_buf(struct fuse_session *se,
if (se->process_buf) { if (se->process_buf) {
se->process_buf(se->data, buf, ch); se->process_buf(se->data, buf, ch);
} else { } else {
assert(!(buf->flags & FUSE_BUF_IS_FD)); assert(!(buf->flags & FUSE_BUF_FLAG_IS_FD));
fuse_session_process(se->data, buf->mem, buf->size, ch); fuse_session_process((fuse_session*)se->data, buf->mem, buf->size, ch);
} }
} }

View File

@ -87,7 +87,7 @@ static void helper_version(void)
static int fuse_helper_opt_proc(void *data, const char *arg, int key, static int fuse_helper_opt_proc(void *data, const char *arg, int key,
struct fuse_args *outargs) struct fuse_args *outargs)
{ {
struct helper_opts *hopts = data; struct helper_opts *hopts = (helper_opts*)data;
switch (key) { switch (key) {
case KEY_HELP: case KEY_HELP:

View File

@ -205,7 +205,7 @@ static void set_mount_flag(const char *s, int *flags)
static int fuse_mount_opt_proc(void *data, const char *arg, int key, static int fuse_mount_opt_proc(void *data, const char *arg, int key,
struct fuse_args *outargs) struct fuse_args *outargs)
{ {
struct mount_opts *mo = data; struct mount_opts *mo = (mount_opts*)data;
switch (key) { switch (key) {
case KEY_ALLOW_ROOT: case KEY_ALLOW_ROOT:
@ -465,11 +465,11 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
if (res == -1) if (res == -1)
goto out_close; goto out_close;
source = malloc((mo->fsname ? strlen(mo->fsname) : 0) + source = (char*)malloc((mo->fsname ? strlen(mo->fsname) : 0) +
(mo->subtype ? strlen(mo->subtype) : 0) + (mo->subtype ? strlen(mo->subtype) : 0) +
strlen(devname) + 32); strlen(devname) + 32);
type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32); type = (char*)malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32);
if (!type || !source) { if (!type || !source) {
fprintf(stderr, "fuse: failed to allocate memory\n"); fprintf(stderr, "fuse: failed to allocate memory\n");
goto out_close; goto out_close;

View File

@ -235,7 +235,7 @@ static int may_unmount(const char *mnt, int quiet)
*/ */
static int check_is_mount_child(void *p) static int check_is_mount_child(void *p)
{ {
const char **a = p; const char **a = (const char**)p;
const char *last = a[0]; const char *last = a[0];
const char *mnt = a[1]; const char *mnt = a[1];
int res; int res;
@ -817,10 +817,10 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode,
fuse_mnt_check_empty(progname, mnt, rootmode, rootsize) == -1) fuse_mnt_check_empty(progname, mnt, rootmode, rootsize) == -1)
goto err; goto err;
source = malloc((fsname ? strlen(fsname) : 0) + source = (char*)malloc((fsname ? strlen(fsname) : 0) +
(subtype ? strlen(subtype) : 0) + strlen(dev) + 32); (subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
type = malloc((subtype ? strlen(subtype) : 0) + 32); type = (char*)malloc(((subtype != NULL) ? strlen(subtype) : 0) + 32);
if (!type || !source) { if (!type || !source) {
fprintf(stderr, "%s: failed to allocate memory\n", progname); fprintf(stderr, "%s: failed to allocate memory\n", progname);
goto err; goto err;

View File

@ -38,7 +38,7 @@ static void add_arg(char **cmdp, const char *opt)
{ {
size_t optlen = strlen(opt); size_t optlen = strlen(opt);
size_t cmdlen = *cmdp ? strlen(*cmdp) : 0; size_t cmdlen = *cmdp ? strlen(*cmdp) : 0;
char *cmd = xrealloc(*cmdp, cmdlen + optlen * 4 + 4); char *cmd = (char*)xrealloc(*cmdp, cmdlen + optlen * 4 + 4);
char *s; char *s;
s = cmd + cmdlen; s = cmd + cmdlen;
if (*cmdp) if (*cmdp)
@ -63,7 +63,7 @@ static char *add_option(const char *opt, char *options)
{ {
int oldlen = options ? strlen(options) : 0; int oldlen = options ? strlen(options) : 0;
options = xrealloc(options, oldlen + 1 + strlen(opt) + 1); options = (char*)xrealloc(options, oldlen + 1 + strlen(opt) + 1);
if (!oldlen) if (!oldlen)
strcpy(options, opt); strcpy(options, opt);
else { else {

View File

@ -41,7 +41,7 @@ namespace l
*src = FUSE_BUFVEC_INIT(size_); *src = FUSE_BUFVEC_INIT(size_);
src->buf->flags = (fuse_buf_flags)(FUSE_BUF_IS_FD|FUSE_BUF_FD_SEEK|FUSE_BUF_FD_RETRY); src->buf->flags = (FUSE_BUF_FLAG_IS_FD|FUSE_BUF_FLAG_FD_SEEK|FUSE_BUF_FLAG_FD_RETRY);
src->buf->fd = fd_; src->buf->fd = fd_;
src->buf->pos = offset_; src->buf->pos = offset_;

View File

@ -49,10 +49,9 @@ namespace l
{ {
size_t size = fuse_buf_size(src_); size_t size = fuse_buf_size(src_);
fuse_bufvec dst = FUSE_BUFVEC_INIT(size); fuse_bufvec dst = FUSE_BUFVEC_INIT(size);
const fuse_buf_copy_flags cpflags = const int cpflags = (FUSE_BUF_COPY_FLAG_SPLICE_MOVE|FUSE_BUF_COPY_FLAG_SPLICE_NONBLOCK);
(fuse_buf_copy_flags)(FUSE_BUF_SPLICE_MOVE|FUSE_BUF_SPLICE_NONBLOCK);
dst.buf->flags = (fuse_buf_flags)(FUSE_BUF_IS_FD|FUSE_BUF_FD_SEEK); dst.buf->flags = (FUSE_BUF_FLAG_IS_FD|FUSE_BUF_FLAG_FD_SEEK);
dst.buf->fd = fd_; dst.buf->fd = fd_;
dst.buf->pos = offset_; dst.buf->pos = offset_;