mirror of
https://github.com/trapexit/mergerfs.git
synced 2024-11-22 05:55:09 +08:00
checkpoint
This commit is contained in:
parent
eaa2593a4b
commit
a5a6b45463
|
@ -46,10 +46,10 @@ SRC = \
|
|||
lib/mount.c
|
||||
OBJS = $(SRC:lib/%.c=build/%.o)
|
||||
DEPS = $(SRC:lib/%.c=build/%.d)
|
||||
CFLAGS ?= \
|
||||
CXXFLAGS ?= \
|
||||
$(OPT_FLAGS)
|
||||
CFLAGS := \
|
||||
${CFLAGS} \
|
||||
CXXFLAGS := \
|
||||
${CXXFLAGS} \
|
||||
-Wall \
|
||||
-pipe \
|
||||
-MMD
|
||||
|
@ -85,17 +85,17 @@ build/libfuse.a: objects
|
|||
utils: mergerfs-fusermount mount.mergerfs
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
build/%.o: lib/%.c
|
||||
$(CC) $(CFLAGS) $(FUSE_FLAGS) -c $< -o $@
|
||||
$(CXX) $(CXXFLAGS) $(FUSE_FLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
|
|
|
@ -280,14 +280,15 @@ void fuse_pollhandle_destroy(struct fuse_pollhandle *ph);
|
|||
/**
|
||||
* Buffer flags
|
||||
*/
|
||||
enum fuse_buf_flags {
|
||||
/**
|
||||
#define FUSE_BUF_FLAG_NONE (1 << 0)
|
||||
|
||||
/**
|
||||
* Buffer contains a file descriptor
|
||||
*
|
||||
* If this flag is set, the .fd field is valid, otherwise the
|
||||
* .mem fields is valid.
|
||||
*/
|
||||
FUSE_BUF_IS_FD = (1 << 1),
|
||||
#define FUSE_BUF_FLAG_IS_FD (1 << 1)
|
||||
|
||||
/**
|
||||
* Seek on the file descriptor
|
||||
|
@ -296,7 +297,7 @@ enum fuse_buf_flags {
|
|||
* used to seek to the given offset before performing
|
||||
* operation on file descriptor.
|
||||
*/
|
||||
FUSE_BUF_FD_SEEK = (1 << 2),
|
||||
#define FUSE_BUF_FLAG_FD_SEEK (1 << 2)
|
||||
|
||||
/**
|
||||
* 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
|
||||
* detected.
|
||||
*/
|
||||
FUSE_BUF_FD_RETRY = (1 << 3),
|
||||
};
|
||||
#define FUSE_BUF_FLAG_FD_RETRY (1 << 3)
|
||||
|
||||
/**
|
||||
* Buffer copy flags
|
||||
*/
|
||||
enum fuse_buf_copy_flags {
|
||||
/**
|
||||
* 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),
|
||||
#define FUSE_BUF_COPY_FLAG_NONE 0
|
||||
|
||||
/**
|
||||
* Force splice
|
||||
*
|
||||
* Always use splice(2) to copy data from one file descriptor
|
||||
* to another. If splice is not available, return -EINVAL.
|
||||
*/
|
||||
FUSE_BUF_FORCE_SPLICE = (1 << 2),
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
#define FUSE_BUF_COPY_FLAG_NO_SPLICE (1 << 1)
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
FUSE_BUF_SPLICE_MOVE = (1 << 3),
|
||||
/**
|
||||
* Force splice
|
||||
*
|
||||
* Always use splice(2) to copy data from one file descriptor
|
||||
* to another. If splice is not available, return -EINVAL.
|
||||
*/
|
||||
#define FUSE_BUF_COPY_FLAG_FORCE_SPLICE (1 << 2)
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -365,14 +366,14 @@ struct fuse_buf {
|
|||
/**
|
||||
* Buffer flags
|
||||
*/
|
||||
enum fuse_buf_flags flags;
|
||||
int flags;
|
||||
|
||||
/**
|
||||
* Memory pointer
|
||||
*
|
||||
* Used unless FUSE_BUF_IS_FD flag is set.
|
||||
*/
|
||||
void *mem;
|
||||
char *mem;
|
||||
|
||||
/**
|
||||
* File descriptor
|
||||
|
@ -427,7 +428,7 @@ struct fuse_bufvec {
|
|||
/* .off = */ 0, \
|
||||
/* .buf = */ { /* [0] = */ { \
|
||||
/* .size = */ (size__), \
|
||||
/* .flags = */ (enum fuse_buf_flags) 0, \
|
||||
/* .flags = */ 0, \
|
||||
/* .mem = */ NULL, \
|
||||
/* .fd = */ -1, \
|
||||
/* .pos = */ 0, \
|
||||
|
@ -450,8 +451,7 @@ size_t fuse_buf_size(const struct fuse_bufvec *bufv);
|
|||
* @param flags flags controlling the copy
|
||||
* @return actual number of bytes copied or -errno on error
|
||||
*/
|
||||
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src,
|
||||
enum fuse_buf_copy_flags flags);
|
||||
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, int flags);
|
||||
|
||||
/* ----------------------------------------------------------- *
|
||||
* Signal handling *
|
||||
|
|
|
@ -1202,8 +1202,7 @@ int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size);
|
|||
* @param flags flags controlling the copy
|
||||
* @return zero for success, -errno for failure to send reply
|
||||
*/
|
||||
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv,
|
||||
enum fuse_buf_copy_flags flags);
|
||||
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, int flags);
|
||||
|
||||
/**
|
||||
* 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,
|
||||
off_t offset, struct fuse_bufvec *bufv,
|
||||
enum fuse_buf_copy_flags flags);
|
||||
int flags);
|
||||
/**
|
||||
* 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 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
|
||||
|
@ -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 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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,15 +6,16 @@
|
|||
See the file COPYING.LIB
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "config.h"
|
||||
#include "fuse_i.h"
|
||||
#include "fuse_lowlevel.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
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;
|
||||
|
||||
for (i = 0; i < bufv->count; i++) {
|
||||
if (bufv->buf[i].size == SIZE_MAX)
|
||||
size = SIZE_MAX;
|
||||
if (bufv->buf[i].size == std::numeric_limits<size_t>::max())
|
||||
size = std::numeric_limits<size_t>::max();
|
||||
else
|
||||
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;
|
||||
|
||||
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,
|
||||
dst->pos + dst_off);
|
||||
} else {
|
||||
|
@ -59,7 +60,7 @@ static ssize_t fuse_buf_write(const struct fuse_buf *dst, size_t dst_off,
|
|||
break;
|
||||
|
||||
copied += res;
|
||||
if (!(dst->flags & FUSE_BUF_FD_RETRY))
|
||||
if (!(dst->flags & FUSE_BUF_FLAG_FD_RETRY))
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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,
|
||||
src->pos + src_off);
|
||||
} else {
|
||||
|
@ -93,7 +94,7 @@ static ssize_t fuse_buf_read(const struct fuse_buf *dst, size_t dst_off,
|
|||
break;
|
||||
|
||||
copied += res;
|
||||
if (!(src->flags & FUSE_BUF_FD_RETRY))
|
||||
if (!(src->flags & FUSE_BUF_FLAG_FD_RETRY))
|
||||
break;
|
||||
|
||||
dst_off += res;
|
||||
|
@ -104,52 +105,56 @@ static ssize_t fuse_buf_read(const struct fuse_buf *dst, size_t dst_off,
|
|||
return copied;
|
||||
}
|
||||
|
||||
static ssize_t 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)
|
||||
static
|
||||
ssize_t
|
||||
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];
|
||||
struct fuse_buf tmp = {
|
||||
.size = sizeof(buf),
|
||||
.flags = 0,
|
||||
};
|
||||
ssize_t res;
|
||||
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) {
|
||||
size_t this_len = min_size(tmp.size, len);
|
||||
size_t read_len;
|
||||
while(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);
|
||||
if (res < 0) {
|
||||
if (!copied)
|
||||
return res;
|
||||
break;
|
||||
res = fuse_buf_read(&tmp, 0, src, src_off, this_len);
|
||||
if (res < 0) {
|
||||
if (!copied)
|
||||
return res;
|
||||
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;
|
||||
}
|
||||
|
@ -157,7 +162,7 @@ static ssize_t fuse_buf_fd_to_fd(const struct fuse_buf *dst, size_t dst_off,
|
|||
#ifdef HAVE_SPLICE
|
||||
static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_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;
|
||||
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;
|
||||
size_t copied = 0;
|
||||
|
||||
if (flags & FUSE_BUF_SPLICE_MOVE)
|
||||
if (flags & FUSE_BUF_COPY_FLAG_SPLICE_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;
|
||||
|
||||
if (src->flags & FUSE_BUF_FD_SEEK) {
|
||||
if (src->flags & FUSE_BUF_FLAG_FD_SEEK) {
|
||||
srcpos_val = src->pos + src_off;
|
||||
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 = &dstpos_val;
|
||||
}
|
||||
|
@ -188,7 +193,7 @@ static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
|
|||
if (copied)
|
||||
break;
|
||||
|
||||
if (errno != EINVAL || (flags & FUSE_BUF_FORCE_SPLICE))
|
||||
if (errno != EINVAL || (flags & FUSE_BUF_COPY_FLAG_FORCE_SPLICE))
|
||||
return -errno;
|
||||
|
||||
/* 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;
|
||||
|
||||
copied += res;
|
||||
if (!(src->flags & FUSE_BUF_FD_RETRY) &&
|
||||
!(dst->flags & FUSE_BUF_FD_RETRY)) {
|
||||
if (!(src->flags & FUSE_BUF_FLAG_FD_RETRY) &&
|
||||
!(dst->flags & FUSE_BUF_FLAG_FD_RETRY)) {
|
||||
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,
|
||||
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 dst_is_fd = dst->flags & FUSE_BUF_IS_FD;
|
||||
int src_is_fd = src->flags & FUSE_BUF_FLAG_IS_FD;
|
||||
int dst_is_fd = dst->flags & FUSE_BUF_FLAG_IS_FD;
|
||||
|
||||
if (!src_is_fd && !dst_is_fd) {
|
||||
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);
|
||||
} else if (!dst_is_fd) {
|
||||
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);
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
ssize_t fuse_buf_copy(struct fuse_bufvec *dstv, struct fuse_bufvec *srcv,
|
||||
enum fuse_buf_copy_flags flags)
|
||||
ssize_t
|
||||
fuse_buf_copy(struct fuse_bufvec *dstv,
|
||||
struct fuse_bufvec *srcv,
|
||||
int flags)
|
||||
{
|
||||
size_t copied = 0;
|
||||
|
||||
if (dstv == srcv)
|
||||
if(dstv == srcv)
|
||||
return fuse_buf_size(dstv);
|
||||
|
||||
for (;;) {
|
||||
for (;;)
|
||||
{
|
||||
const struct fuse_buf *src = fuse_bufvec_current(srcv);
|
||||
const struct fuse_buf *dst = fuse_bufvec_current(dstv);
|
||||
size_t src_len;
|
||||
size_t dst_len;
|
||||
size_t len;
|
||||
ssize_t src_len;
|
||||
ssize_t dst_len;
|
||||
ssize_t len;
|
||||
ssize_t res;
|
||||
|
||||
if (src == NULL || dst == NULL)
|
||||
if(src == NULL || dst == NULL)
|
||||
break;
|
||||
|
||||
src_len = src->size - srcv->off;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
|
||||
/* For pthread_rwlock_t */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "config.h"
|
||||
#include "fuse_i.h"
|
||||
|
@ -18,6 +17,8 @@
|
|||
#include "fuse_kernel.h"
|
||||
#include "fuse_dirents.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
|
@ -39,15 +40,9 @@
|
|||
#include <time.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_UNKNOWN_INO UINT64_MAX
|
||||
#define FUSE_UNKNOWN_INO std::numeric_limits<uint64_t>::max()
|
||||
#define OFFSET_MAX 0x7fffffffffffffffLL
|
||||
|
||||
#define NODE_TABLE_MIN_SIZE 8192
|
||||
|
@ -102,13 +97,6 @@ struct node_table
|
|||
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 *next;
|
||||
|
@ -216,32 +204,32 @@ list_empty(const struct list_head *head)
|
|||
|
||||
static
|
||||
void
|
||||
list_add(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
list_add(struct list_head *new_,
|
||||
struct list_head *prev_,
|
||||
struct list_head *next_)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
next_->prev = new_;
|
||||
new_->next = next_;
|
||||
new_->prev = prev_;
|
||||
prev_->next = new_;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
list_add_head(struct list_head *new,
|
||||
struct list_head *head)
|
||||
list_add_head(struct list_head *new_,
|
||||
struct list_head *head_)
|
||||
{
|
||||
list_add(new, head, head->next);
|
||||
list_add(new_,head_,head_->next);
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
void
|
||||
list_add_tail(struct list_head *new,
|
||||
struct list_head *head)
|
||||
list_add_tail(struct list_head *new_,
|
||||
struct list_head *head_)
|
||||
{
|
||||
list_add(new, head->prev, head);
|
||||
list_add(new_,head_->prev,head_);
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -282,113 +270,6 @@ get_node_size(struct fuse *f)
|
|||
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
|
||||
struct node*
|
||||
alloc_node(struct fuse *f)
|
||||
|
@ -404,7 +285,6 @@ free_node_mem(struct fuse *f,
|
|||
(void) f;
|
||||
free(node);
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
size_t
|
||||
|
@ -496,13 +376,13 @@ void
|
|||
node_table_reduce(struct node_table *t)
|
||||
{
|
||||
size_t newsize = t->size / 2;
|
||||
void *newarray;
|
||||
node **newarray;
|
||||
|
||||
if (newsize < NODE_TABLE_MIN_SIZE)
|
||||
return;
|
||||
|
||||
newarray = realloc(t->array, sizeof(struct node *) * newsize);
|
||||
if (newarray != NULL)
|
||||
newarray = (node**)realloc(t->array,sizeof(struct node*)*newsize);
|
||||
if(newarray != NULL)
|
||||
t->array = newarray;
|
||||
|
||||
t->size = newsize;
|
||||
|
@ -557,14 +437,14 @@ unhash_id(struct fuse *f, struct node *node)
|
|||
static int node_table_resize(struct node_table *t)
|
||||
{
|
||||
size_t newsize = t->size * 2;
|
||||
void *newarray;
|
||||
node **newarray;
|
||||
|
||||
newarray = realloc(t->array, sizeof(struct node *) * newsize);
|
||||
if (newarray == NULL)
|
||||
newarray = (node**)realloc(t->array,sizeof(struct node*)*newsize);
|
||||
if(newarray == NULL)
|
||||
return -1;
|
||||
|
||||
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->split = 0;
|
||||
|
||||
|
@ -780,7 +660,7 @@ next_id(struct fuse *f)
|
|||
{
|
||||
do
|
||||
{
|
||||
f->ctr = ((f->ctr + 1) & UINT64_MAX);
|
||||
f->ctr = ((f->ctr + 1) & std::numeric_limits<uint64_t>::max());
|
||||
if(f->ctr == 0)
|
||||
f->generation++;
|
||||
} while((f->ctr == 0) ||
|
||||
|
@ -850,7 +730,12 @@ static struct node *find_node(struct fuse *f, fuse_ino_t parent,
|
|||
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);
|
||||
|
||||
|
@ -866,7 +751,7 @@ static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name)
|
|||
newbufsize *= 2;
|
||||
}
|
||||
|
||||
newbuf = realloc(*buf, newbufsize);
|
||||
newbuf = (char*)realloc(*buf, newbufsize);
|
||||
if (newbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -917,7 +802,7 @@ static int try_get_path(struct fuse *f, fuse_ino_t nodeid, const char *name,
|
|||
*path = NULL;
|
||||
|
||||
err = -ENOMEM;
|
||||
buf = malloc(bufsize);
|
||||
buf = (char*)malloc(bufsize);
|
||||
if (buf == NULL)
|
||||
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);
|
||||
err = try_get_path(f, nodeid, name, path, wnode, true);
|
||||
if (err == -EAGAIN) {
|
||||
struct lock_queue_element qe = {
|
||||
.nodeid1 = nodeid,
|
||||
.name1 = name,
|
||||
.path1 = path,
|
||||
.wnode1 = wnode,
|
||||
};
|
||||
debug_path(f, "QUEUE PATH", nodeid, name, !!wnode);
|
||||
err = wait_path(f, &qe);
|
||||
debug_path(f, "DEQUEUE PATH", nodeid, name, !!wnode);
|
||||
}
|
||||
if(err == -EAGAIN)
|
||||
{
|
||||
struct lock_queue_element qe;
|
||||
|
||||
qe.nodeid1 = nodeid;
|
||||
qe.name1 = name;
|
||||
qe.path1 = path;
|
||||
qe.wnode1 = 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);
|
||||
|
||||
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);
|
||||
err = try_get_path2(f, nodeid1, name1, nodeid2, name2,
|
||||
path1, path2, wnode1, wnode2);
|
||||
if (err == -EAGAIN) {
|
||||
struct lock_queue_element qe = {
|
||||
.nodeid1 = nodeid1,
|
||||
.name1 = name1,
|
||||
.path1 = path1,
|
||||
.wnode1 = wnode1,
|
||||
.nodeid2 = nodeid2,
|
||||
.name2 = name2,
|
||||
.path2 = path2,
|
||||
.wnode2 = wnode2,
|
||||
};
|
||||
if(err == -EAGAIN)
|
||||
{
|
||||
struct lock_queue_element qe;
|
||||
|
||||
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);
|
||||
}
|
||||
qe.nodeid1 = nodeid1;
|
||||
qe.name1 = name1;
|
||||
qe.path1 = path1;
|
||||
qe.wnode1 = wnode1;
|
||||
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);
|
||||
|
||||
return err;
|
||||
|
@ -1261,9 +1149,9 @@ forget_node(struct fuse *f,
|
|||
*/
|
||||
while(node->nlookup == nlookup && node->treelock)
|
||||
{
|
||||
struct lock_queue_element qe = {
|
||||
.nodeid1 = nodeid,
|
||||
};
|
||||
struct lock_queue_element qe;
|
||||
|
||||
qe.nodeid1 = nodeid;
|
||||
|
||||
debug_path(f, "QUEUE PATH (forget)", nodeid, NULL, false);
|
||||
queue_path(f, &qe);
|
||||
|
@ -1366,16 +1254,20 @@ struct fuse_intr_data {
|
|||
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 *f = req_fuse(req);
|
||||
struct fuse *f = req_fuse(req_);
|
||||
|
||||
if (d->id == pthread_self())
|
||||
if(d->id == pthread_self())
|
||||
return;
|
||||
|
||||
pthread_mutex_lock(&f->lock);
|
||||
while (!d->finished) {
|
||||
while (!d->finished)
|
||||
{
|
||||
struct timeval now;
|
||||
struct timespec timeout;
|
||||
|
||||
|
@ -1395,7 +1287,7 @@ static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req,
|
|||
d->finished = 1;
|
||||
pthread_cond_broadcast(&d->cond);
|
||||
pthread_mutex_unlock(&f->lock);
|
||||
fuse_req_interrupt_func(req, NULL, NULL);
|
||||
fuse_req_interrupt_func(req,NULL,NULL);
|
||||
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();
|
||||
pthread_cond_init(&d->cond, NULL);
|
||||
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,
|
||||
|
@ -1617,9 +1509,12 @@ static void fuse_free_buf(struct fuse_bufvec *buf)
|
|||
}
|
||||
}
|
||||
|
||||
int fuse_fs_read_buf(struct fuse_fs *fs,
|
||||
struct fuse_bufvec **bufp, size_t size, off_t off,
|
||||
struct fuse_file_info *fi)
|
||||
int
|
||||
fuse_fs_read_buf(struct fuse_fs *fs,
|
||||
struct fuse_bufvec **bufp,
|
||||
size_t size,
|
||||
off_t off,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
fuse_get_context()->private_data = fs->user_data;
|
||||
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);
|
||||
} else {
|
||||
struct fuse_bufvec *buf;
|
||||
void *mem;
|
||||
char *mem;
|
||||
|
||||
buf = malloc(sizeof(struct fuse_bufvec));
|
||||
if (buf == NULL)
|
||||
buf = (struct fuse_bufvec*)malloc(sizeof(struct fuse_bufvec));
|
||||
if(buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
mem = malloc(size);
|
||||
mem = (char*)malloc(size);
|
||||
if (mem == NULL) {
|
||||
free(buf);
|
||||
return -ENOMEM;
|
||||
|
@ -1660,7 +1555,7 @@ int fuse_fs_read_buf(struct fuse_fs *fs,
|
|||
(unsigned long long) fi->fh,
|
||||
fuse_buf_size(*bufp),
|
||||
(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");
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int fuse_fs_write_buf(struct fuse_fs *fs,
|
||||
struct fuse_bufvec *buf, off_t off,
|
||||
struct fuse_file_info *fi)
|
||||
int
|
||||
fuse_fs_write_buf(struct fuse_fs *fs,
|
||||
struct fuse_bufvec *buf,
|
||||
off_t off,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
fuse_get_context()->private_data = fs->user_data;
|
||||
if (fs->op.write_buf || fs->op.write) {
|
||||
int res;
|
||||
size_t size = fuse_buf_size(buf);
|
||||
if(fs->op.write_buf || fs->op.write)
|
||||
{
|
||||
int res;
|
||||
size_t size = fuse_buf_size(buf);
|
||||
|
||||
assert(buf->idx == 0 && buf->off == 0);
|
||||
if (fs->debug)
|
||||
fprintf(stderr,
|
||||
"write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
|
||||
fi->writepage ? "page" : "",
|
||||
(unsigned long long) fi->fh,
|
||||
size,
|
||||
(unsigned long long) off,
|
||||
fi->flags);
|
||||
assert(buf->idx == 0 && buf->off == 0);
|
||||
if (fs->debug)
|
||||
fprintf(stderr,
|
||||
"write%s[%llu] %zu bytes to %llu flags: 0x%x\n",
|
||||
fi->writepage ? "page" : "",
|
||||
(unsigned long long) fi->fh,
|
||||
size,
|
||||
(unsigned long long) off,
|
||||
fi->flags);
|
||||
|
||||
if (fs->op.write_buf) {
|
||||
res = fs->op.write_buf(buf, off, fi);
|
||||
} else {
|
||||
void *mem = NULL;
|
||||
struct fuse_buf *flatbuf;
|
||||
struct fuse_bufvec tmp = FUSE_BUFVEC_INIT(size);
|
||||
if (fs->op.write_buf)
|
||||
{
|
||||
res = fs->op.write_buf(buf, off, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *mem = NULL;
|
||||
struct fuse_buf *flatbuf;
|
||||
struct fuse_bufvec tmp = FUSE_BUFVEC_INIT(size);
|
||||
|
||||
if (buf->count == 1 &&
|
||||
!(buf->buf[0].flags & FUSE_BUF_IS_FD)) {
|
||||
flatbuf = &buf->buf[0];
|
||||
} else {
|
||||
res = -ENOMEM;
|
||||
mem = malloc(size);
|
||||
if (mem == NULL)
|
||||
goto out;
|
||||
if((buf->count == 1) &&
|
||||
!(buf->buf[0].flags & FUSE_BUF_FLAG_IS_FD))
|
||||
{
|
||||
flatbuf = &buf->buf[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
res = -ENOMEM;
|
||||
mem = (char*)malloc(size);
|
||||
if (mem == NULL)
|
||||
goto out;
|
||||
|
||||
tmp.buf[0].mem = mem;
|
||||
res = fuse_buf_copy(&tmp, buf, 0);
|
||||
if (res <= 0)
|
||||
goto out_free;
|
||||
tmp.buf[0].mem = mem;
|
||||
res = fuse_buf_copy(&tmp, buf, FUSE_BUF_FLAG_NONE);
|
||||
if (res <= 0)
|
||||
goto out_free;
|
||||
|
||||
tmp.buf[0].size = res;
|
||||
flatbuf = &tmp.buf[0];
|
||||
}
|
||||
tmp.buf[0].size = res;
|
||||
flatbuf = &tmp.buf[0];
|
||||
}
|
||||
|
||||
res = fs->op.write(flatbuf->mem, flatbuf->size,
|
||||
off, fi);
|
||||
out_free:
|
||||
free(mem);
|
||||
res = fs->op.write(flatbuf->mem, flatbuf->size,
|
||||
off, fi);
|
||||
out_free:
|
||||
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,
|
||||
size_t size, off_t off, struct fuse_file_info *fi)
|
||||
int
|
||||
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);
|
||||
|
||||
bufv.buf[0].mem = (void *) mem;
|
||||
bufv.buf[0].mem = (char*)mem;
|
||||
|
||||
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);
|
||||
|
||||
if (res == 0)
|
||||
fuse_reply_data(req, buf, FUSE_BUF_SPLICE_MOVE);
|
||||
fuse_reply_data(req, buf, FUSE_BUF_COPY_FLAG_SPLICE_MOVE);
|
||||
else
|
||||
reply_err(req, res);
|
||||
|
||||
|
@ -3338,7 +3248,7 @@ readdir_buf_size(fuse_dirents_t *d_,
|
|||
size_t size_,
|
||||
off_t off_)
|
||||
{
|
||||
if(off_ >= kv_size(d_->offs))
|
||||
if(off_ >= (off_t)kv_size(d_->offs))
|
||||
return 0;
|
||||
if((kv_A(d_->offs,off_) + size_) > d_->data_len)
|
||||
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;
|
||||
|
||||
if (lock->type != F_UNLCK || lock->start != 0 ||
|
||||
lock->end != OFFSET_MAX) {
|
||||
newl1 = malloc(sizeof(struct lock));
|
||||
newl2 = malloc(sizeof(struct lock));
|
||||
lock->end != OFFSET_MAX)
|
||||
{
|
||||
newl1 = (struct lock*)malloc(sizeof(struct lock));
|
||||
newl2 = (struct lock*)malloc(sizeof(struct lock));
|
||||
|
||||
if (!newl1 || !newl2) {
|
||||
free(newl1);
|
||||
free(newl2);
|
||||
return -ENOLCK;
|
||||
if(!newl1 || !newl2)
|
||||
{
|
||||
free(newl1);
|
||||
free(newl2);
|
||||
return -ENOLCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (lp = &node->locks; *lp;) {
|
||||
struct lock *l = *lp;
|
||||
|
@ -3721,14 +3633,14 @@ static int locks_insert(struct node *node, struct lock *lock)
|
|||
lock->start = l->start;
|
||||
if (lock->end < l->end)
|
||||
lock->end = l->end;
|
||||
goto delete;
|
||||
goto _delete;
|
||||
} else {
|
||||
if (l->end < lock->start)
|
||||
goto skip;
|
||||
if (lock->end < l->start)
|
||||
break;
|
||||
if (lock->start <= l->start && l->end <= lock->end)
|
||||
goto delete;
|
||||
goto _delete;
|
||||
if (l->end <= lock->end) {
|
||||
l->end = lock->start - 1;
|
||||
goto skip;
|
||||
|
@ -3747,7 +3659,7 @@ static int locks_insert(struct node *node, struct lock *lock)
|
|||
lp = &l->next;
|
||||
continue;
|
||||
|
||||
delete:
|
||||
_delete:
|
||||
delete_lock(lp);
|
||||
}
|
||||
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
|
||||
fi = *llfi;
|
||||
|
||||
if (out_bufsz) {
|
||||
err = -ENOMEM;
|
||||
out_buf = malloc(out_bufsz);
|
||||
if (!out_buf)
|
||||
goto err;
|
||||
}
|
||||
if(out_bufsz)
|
||||
{
|
||||
err = -ENOMEM;
|
||||
out_buf = (char*)malloc(out_bufsz);
|
||||
if (!out_buf)
|
||||
goto err;
|
||||
}
|
||||
|
||||
assert(!in_bufsz || !out_bufsz || in_bufsz == out_bufsz);
|
||||
if (out_buf)
|
||||
|
@ -4049,7 +3962,8 @@ int fuse_clean_cache(struct fuse *f)
|
|||
double age;
|
||||
|
||||
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;
|
||||
|
||||
age = diff_timespec(&now, &lnode->forget_time);
|
||||
|
@ -4071,49 +3985,52 @@ int fuse_clean_cache(struct fuse *f)
|
|||
return clean_delay(f);
|
||||
}
|
||||
|
||||
static struct fuse_lowlevel_ops fuse_path_ops = {
|
||||
.init = fuse_lib_init,
|
||||
.destroy = fuse_lib_destroy,
|
||||
.lookup = fuse_lib_lookup,
|
||||
.forget = fuse_lib_forget,
|
||||
.forget_multi = fuse_lib_forget_multi,
|
||||
.getattr = fuse_lib_getattr,
|
||||
.setattr = fuse_lib_setattr,
|
||||
.access = fuse_lib_access,
|
||||
.readlink = fuse_lib_readlink,
|
||||
.mknod = fuse_lib_mknod,
|
||||
.mkdir = fuse_lib_mkdir,
|
||||
.unlink = fuse_lib_unlink,
|
||||
.rmdir = fuse_lib_rmdir,
|
||||
.symlink = fuse_lib_symlink,
|
||||
.rename = fuse_lib_rename,
|
||||
.link = fuse_lib_link,
|
||||
.create = fuse_lib_create,
|
||||
.open = fuse_lib_open,
|
||||
.read = fuse_lib_read,
|
||||
.write_buf = fuse_lib_write_buf,
|
||||
.flush = fuse_lib_flush,
|
||||
.release = fuse_lib_release,
|
||||
.fsync = fuse_lib_fsync,
|
||||
.opendir = fuse_lib_opendir,
|
||||
.readdir = fuse_lib_readdir,
|
||||
.readdir_plus = fuse_lib_readdir_plus,
|
||||
.releasedir = fuse_lib_releasedir,
|
||||
.fsyncdir = fuse_lib_fsyncdir,
|
||||
.statfs = fuse_lib_statfs,
|
||||
.setxattr = fuse_lib_setxattr,
|
||||
.getxattr = fuse_lib_getxattr,
|
||||
.listxattr = fuse_lib_listxattr,
|
||||
.removexattr = fuse_lib_removexattr,
|
||||
.getlk = fuse_lib_getlk,
|
||||
.setlk = fuse_lib_setlk,
|
||||
.flock = fuse_lib_flock,
|
||||
.bmap = fuse_lib_bmap,
|
||||
.ioctl = fuse_lib_ioctl,
|
||||
.poll = fuse_lib_poll,
|
||||
.fallocate = fuse_lib_fallocate,
|
||||
.copy_file_range = fuse_lib_copy_file_range,
|
||||
};
|
||||
static struct fuse_lowlevel_ops fuse_path_ops =
|
||||
{
|
||||
fuse_lib_init,
|
||||
fuse_lib_destroy,
|
||||
fuse_lib_lookup,
|
||||
fuse_lib_forget,
|
||||
fuse_lib_getattr,
|
||||
fuse_lib_setattr,
|
||||
fuse_lib_readlink,
|
||||
fuse_lib_mknod,
|
||||
fuse_lib_mkdir,
|
||||
fuse_lib_unlink,
|
||||
fuse_lib_rmdir,
|
||||
fuse_lib_symlink,
|
||||
fuse_lib_rename,
|
||||
fuse_lib_link,
|
||||
fuse_lib_open,
|
||||
fuse_lib_read,
|
||||
NULL,
|
||||
fuse_lib_flush,
|
||||
fuse_lib_release,
|
||||
fuse_lib_fsync,
|
||||
fuse_lib_opendir,
|
||||
fuse_lib_readdir,
|
||||
fuse_lib_readdir_plus,
|
||||
fuse_lib_releasedir,
|
||||
fuse_lib_fsyncdir,
|
||||
fuse_lib_statfs,
|
||||
fuse_lib_setxattr,
|
||||
fuse_lib_getxattr,
|
||||
fuse_lib_listxattr,
|
||||
fuse_lib_removexattr,
|
||||
fuse_lib_access,
|
||||
fuse_lib_create,
|
||||
fuse_lib_getlk,
|
||||
fuse_lib_setlk,
|
||||
fuse_lib_bmap,
|
||||
fuse_lib_ioctl,
|
||||
fuse_lib_poll,
|
||||
fuse_lib_write_buf,
|
||||
NULL,
|
||||
fuse_lib_forget_multi,
|
||||
fuse_lib_flock,
|
||||
fuse_lib_fallocate,
|
||||
fuse_lib_copy_file_range
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
struct fuse *f = fuse;
|
||||
struct fuse *f = (struct fuse*)fuse;
|
||||
int sleep_time;
|
||||
|
||||
while(1) {
|
||||
|
|
|
@ -57,11 +57,11 @@ int
|
|||
fuse_dirents_buf_resize(fuse_dirents_t *d_,
|
||||
uint64_t size_)
|
||||
{
|
||||
void *p;
|
||||
char *p;
|
||||
|
||||
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)
|
||||
return -errno;
|
||||
|
||||
|
@ -73,7 +73,7 @@ fuse_dirents_buf_resize(fuse_dirents_t *d_,
|
|||
}
|
||||
|
||||
static
|
||||
void*
|
||||
fuse_dirent_t*
|
||||
fuse_dirents_dirent_alloc(fuse_dirents_t *d_,
|
||||
uint64_t namelen_)
|
||||
{
|
||||
|
@ -95,13 +95,13 @@ fuse_dirents_dirent_alloc(fuse_dirents_t *d_,
|
|||
}
|
||||
|
||||
static
|
||||
void*
|
||||
fuse_direntplus_t*
|
||||
fuse_dirents_direntplus_alloc(fuse_dirents_t *d_,
|
||||
uint64_t namelen_)
|
||||
{
|
||||
int rv;
|
||||
uint64_t size;
|
||||
fuse_dirent_t *d;
|
||||
fuse_direntplus_t *d;
|
||||
|
||||
size = fuse_direntplus_size(namelen_);
|
||||
|
||||
|
@ -109,7 +109,7 @@ fuse_dirents_direntplus_alloc(fuse_dirents_t *d_,
|
|||
if(rv)
|
||||
return NULL;
|
||||
|
||||
d = (fuse_dirent_t*)&d_->buf[d_->data_len];
|
||||
d = (fuse_direntplus_t*)&d_->buf[d_->data_len];
|
||||
|
||||
d_->data_len += size;
|
||||
|
||||
|
@ -379,9 +379,9 @@ fuse_dirents_reset(fuse_dirents_t *d_)
|
|||
int
|
||||
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)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -88,12 +88,11 @@ 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,
|
||||
};
|
||||
struct fuse_chan_ops op;
|
||||
|
||||
op.receive = fuse_kern_chan_receive;
|
||||
op.send = fuse_kern_chan_send;
|
||||
op.destroy = fuse_kern_chan_destroy;
|
||||
|
||||
pagesize = sysconf(_SC_PAGESIZE);
|
||||
|
||||
|
|
|
@ -68,12 +68,12 @@ static void *fuse_do_work(void *data)
|
|||
|
||||
while (!fuse_session_exited(mt->se)) {
|
||||
struct fuse_chan *ch = mt->prevch;
|
||||
struct fuse_buf fbuf = {
|
||||
.mem = w->buf,
|
||||
.size = w->bufsize,
|
||||
};
|
||||
struct fuse_buf fbuf;
|
||||
int res;
|
||||
|
||||
fbuf.mem = w->buf;
|
||||
fbuf.size = w->bufsize;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
res = fuse_session_receive_buf(mt->se, &fbuf, &ch);
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
fprintf(stderr, "fuse: failed to allocate worker structure\n");
|
||||
return -1;
|
||||
}
|
||||
memset(w, 0, sizeof(struct fuse_worker));
|
||||
w->bufsize = fuse_chan_bufsize(mt->prevch);
|
||||
w->buf = calloc(w->bufsize,1);
|
||||
w->buf = (char*)calloc(w->bufsize,1);
|
||||
w->mt = mt;
|
||||
if (!w->buf) {
|
||||
fprintf(stderr, "fuse: failed to allocate read buffer\n");
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
See the file COPYING.LIB
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "config.h"
|
||||
#include "fuse_i.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,
|
||||
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);
|
||||
if (f->debug) {
|
||||
|
@ -235,7 +233,7 @@ int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
|
|||
int res;
|
||||
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)
|
||||
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 */
|
||||
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
|
||||
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)
|
||||
return res;
|
||||
|
||||
mem_buf.buf[0].mem = mbuf;
|
||||
res = fuse_buf_copy(&mem_buf, buf, 0);
|
||||
mem_buf.buf[0].mem = (char*)mbuf;
|
||||
res = fuse_buf_copy(&mem_buf,buf,FUSE_BUF_FLAG_NONE);
|
||||
if (res < 0) {
|
||||
free(mbuf);
|
||||
return -res;
|
||||
|
@ -481,11 +479,11 @@ static void fuse_ll_pipe_free(struct fuse_ll_pipe *llp)
|
|||
#ifdef HAVE_SPLICE
|
||||
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) {
|
||||
int res;
|
||||
|
||||
llp = malloc(sizeof(struct fuse_ll_pipe));
|
||||
llp = (struct fuse_ll_pipe*)malloc(sizeof(struct fuse_ll_pipe));
|
||||
if (llp == 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)
|
||||
{
|
||||
struct fuse_ll_pipe *llp = pthread_getspecific(f->pipe_key);
|
||||
if (llp) {
|
||||
pthread_setspecific(f->pipe_key, NULL);
|
||||
fuse_ll_pipe_free(llp);
|
||||
}
|
||||
struct fuse_ll_pipe *llp = (struct fuse_ll_pipe*)pthread_getspecific(f->pipe_key);
|
||||
if(llp)
|
||||
{
|
||||
pthread_setspecific(f->pipe_key,NULL);
|
||||
fuse_ll_pipe_free(llp);
|
||||
}
|
||||
}
|
||||
|
||||
#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;
|
||||
char *buf = (char*)buf_;
|
||||
|
||||
res = read(fd, buf, len);
|
||||
if (res == -1) {
|
||||
fprintf(stderr, "fuse: internal error: failed to read back from pipe: %s\n", strerror(errno));
|
||||
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);
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -548,7 +552,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
|
|||
{
|
||||
int res;
|
||||
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;
|
||||
int splice_flags;
|
||||
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)
|
||||
goto fallback;
|
||||
|
||||
if (flags & FUSE_BUF_NO_SPLICE)
|
||||
if (flags & FUSE_BUF_COPY_FLAG_NO_SPLICE)
|
||||
goto fallback;
|
||||
|
||||
total_fd_size = 0;
|
||||
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;
|
||||
if (idx == buf->idx)
|
||||
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)
|
||||
goto fallback;
|
||||
|
||||
if (res != headerlen) {
|
||||
if (res != (int)headerlen) {
|
||||
res = -EIO;
|
||||
fprintf(stderr, "fuse: short vmsplice to pipe: %u/%zu\n", res,
|
||||
headerlen);
|
||||
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];
|
||||
|
||||
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 == -EAGAIN || res == -EINVAL) {
|
||||
/*
|
||||
|
@ -646,7 +650,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
|
|||
goto clear_pipe;
|
||||
}
|
||||
|
||||
if (res != 0 && res < len) {
|
||||
if (res != 0 && (res < (int)len)) {
|
||||
struct fuse_bufvec mem_buf = FUSE_BUFVEC_INIT(len);
|
||||
void *mbuf;
|
||||
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)
|
||||
goto clear_pipe;
|
||||
|
||||
mem_buf.buf[0].mem = mbuf;
|
||||
mem_buf.buf[0].mem = (char*)mbuf;
|
||||
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) {
|
||||
char *tmpbuf;
|
||||
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 to regular write.
|
||||
*/
|
||||
tmpbuf = malloc(headerlen);
|
||||
tmpbuf = (char*)malloc(headerlen);
|
||||
if (tmpbuf == NULL) {
|
||||
free(mbuf);
|
||||
res = ENOMEM;
|
||||
|
@ -686,7 +690,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
|
|||
free(mbuf);
|
||||
goto clear_pipe;
|
||||
}
|
||||
res = read_back(llp->pipe[0], mbuf, now_len);
|
||||
res = read_back(llp->pipe[0],mbuf,now_len);
|
||||
if (res != 0) {
|
||||
free(mbuf);
|
||||
goto clear_pipe;
|
||||
|
@ -712,7 +716,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
|
|||
}
|
||||
|
||||
splice_flags = 0;
|
||||
if ((flags & FUSE_BUF_SPLICE_MOVE) &&
|
||||
if ((flags & FUSE_BUF_COPY_FLAG_SPLICE_MOVE) &&
|
||||
(f->conn.want & FUSE_CAP_SPLICE_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");
|
||||
goto clear_pipe;
|
||||
}
|
||||
if (res != out->len) {
|
||||
if (res != (int)out->len) {
|
||||
res = -EIO;
|
||||
fprintf(stderr, "fuse: short splice from pipe: %u/%u\n",
|
||||
res, out->len);
|
||||
|
@ -750,8 +754,10 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
|
|||
}
|
||||
#endif
|
||||
|
||||
int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv,
|
||||
enum fuse_buf_copy_flags flags)
|
||||
int
|
||||
fuse_reply_data(fuse_req_t req,
|
||||
struct fuse_bufvec *bufv,
|
||||
int flags)
|
||||
{
|
||||
struct iovec iov[2];
|
||||
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;
|
||||
size_t i;
|
||||
|
||||
fiov = malloc(sizeof(fiov[0]) * count);
|
||||
fiov = (struct fuse_ioctl_iovec*)malloc(sizeof(fiov[0]) * count);
|
||||
if (!fiov)
|
||||
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;
|
||||
int res;
|
||||
|
||||
padded_iov = malloc((count + 2) * sizeof(struct iovec));
|
||||
padded_iov = (struct iovec*)malloc((count + 2) * sizeof(struct iovec));
|
||||
if (padded_iov == NULL)
|
||||
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,
|
||||
const void *inarg)
|
||||
{
|
||||
struct fuse_batch_forget_in *arg = (void *) inarg;
|
||||
struct fuse_forget_one *param = (void *) PARAM(arg);
|
||||
struct fuse_batch_forget_in *arg = (struct fuse_batch_forget_in*)inarg;
|
||||
struct fuse_forget_one *param = (struct fuse_forget_one*)PARAM(arg);
|
||||
unsigned int i;
|
||||
|
||||
(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)
|
||||
{
|
||||
struct fuse_ll *f = req->f;
|
||||
struct fuse_bufvec bufv = {
|
||||
.buf[0] = *ibuf,
|
||||
.count = 1,
|
||||
};
|
||||
struct fuse_bufvec bufv;
|
||||
struct fuse_write_in *arg = (struct fuse_write_in *) inarg;
|
||||
struct fuse_file_info fi;
|
||||
|
||||
bufv.buf[0] = *ibuf;
|
||||
bufv.count = 1;
|
||||
memset(&fi, 0, sizeof(fi));
|
||||
fi.fh = arg->fh;
|
||||
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].size -= sizeof(struct fuse_in_header) +
|
||||
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 {
|
||||
fi.lock_owner = arg->lock_owner;
|
||||
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].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:
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
@ -1447,10 +1452,9 @@ static void do_statfs(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
|
|||
if (req->f->op.statfs)
|
||||
req->f->op.statfs(req, nodeid);
|
||||
else {
|
||||
struct statvfs buf = {
|
||||
.f_namemax = 255,
|
||||
.f_bsize = 512,
|
||||
};
|
||||
struct statvfs buf;
|
||||
buf.f_namemax = 255;
|
||||
buf.f_bsize = 512;
|
||||
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;
|
||||
pthread_mutex_unlock(&f->lock);
|
||||
if (func)
|
||||
func(curr, data);
|
||||
func(curr,(fuse_intr_data*)data);
|
||||
pthread_mutex_unlock(&curr->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;
|
||||
|
||||
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) {
|
||||
fuse_reply_err(req, ENOMEM);
|
||||
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,
|
||||
off_t offset, struct fuse_bufvec *bufv,
|
||||
enum fuse_buf_copy_flags flags)
|
||||
int flags)
|
||||
{
|
||||
struct fuse_out_header out;
|
||||
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_retrieve_req *rreq =
|
||||
container_of(nreq, struct fuse_retrieve_req, nreq);
|
||||
const struct fuse_notify_retrieve_in *arg = inarg;
|
||||
struct fuse_bufvec bufv = {
|
||||
.buf[0] = *ibuf,
|
||||
.count = 1,
|
||||
};
|
||||
const struct fuse_notify_retrieve_in *arg = (struct fuse_notify_retrieve_in*)inarg;
|
||||
struct fuse_bufvec bufv;
|
||||
|
||||
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].size -= sizeof(struct fuse_in_header) +
|
||||
|
@ -2225,7 +2228,7 @@ static void fuse_ll_retrieve_reply(struct fuse_notify_req *nreq,
|
|||
}
|
||||
out:
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -2248,7 +2251,7 @@ int fuse_lowlevel_notify_retrieve(struct fuse_chan *ch, fuse_ino_t ino,
|
|||
if (f->conn.proto_minor < 15)
|
||||
return -ENOSYS;
|
||||
|
||||
rreq = malloc(sizeof(*rreq));
|
||||
rreq = (struct fuse_retrieve_req*)malloc(sizeof(*rreq));
|
||||
if (rreq == NULL)
|
||||
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;
|
||||
pthread_mutex_unlock(&req->f->lock);
|
||||
if (req->interrupted && func)
|
||||
func(req, data);
|
||||
func(req,(fuse_intr_data*)data);
|
||||
pthread_mutex_unlock(&req->lock);
|
||||
}
|
||||
|
||||
|
@ -2312,55 +2315,12 @@ int fuse_req_interrupted(fuse_req_t req)
|
|||
return interrupted;
|
||||
}
|
||||
|
||||
typedef void (*fuse_ll_func_t)(fuse_req_t,fuse_ino_t,const void*);
|
||||
|
||||
static struct {
|
||||
void (*func)(fuse_req_t, fuse_ino_t, const void *);
|
||||
fuse_ll_func_t func;
|
||||
const char *name;
|
||||
} fuse_ll_ops[] =
|
||||
{
|
||||
[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" },
|
||||
};
|
||||
} fuse_ll_ops[FUSE_REMOVEMAPPING];
|
||||
|
||||
#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));
|
||||
return res;
|
||||
}
|
||||
if (res < fuse_buf_size(dst)) {
|
||||
if (res < (int)fuse_buf_size(dst)) {
|
||||
fprintf(stderr, "fuse: copy from pipe: short read\n");
|
||||
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;
|
||||
const size_t write_header_size = sizeof(struct fuse_in_header) +
|
||||
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_in_header *in;
|
||||
const void *inarg;
|
||||
struct fuse_req *req;
|
||||
void *mbuf = NULL;
|
||||
char *mbuf = NULL;
|
||||
int err;
|
||||
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)
|
||||
tmpbuf.buf[0].size = buf->size;
|
||||
|
||||
mbuf = malloc(tmpbuf.buf[0].size);
|
||||
mbuf = (char*)malloc(tmpbuf.buf[0].size);
|
||||
if (mbuf == NULL) {
|
||||
fprintf(stderr, "fuse: failed to allocate header\n");
|
||||
goto clear_pipe;
|
||||
}
|
||||
tmpbuf.buf[0].mem = mbuf;
|
||||
tmpbuf.buf[0].mem = (char*)mbuf;
|
||||
|
||||
res = fuse_ll_copy_from_pipe(&tmpbuf, &bufv);
|
||||
if (res < 0)
|
||||
goto clear_pipe;
|
||||
|
||||
in = mbuf;
|
||||
in = (fuse_in_header*)mbuf;
|
||||
} else {
|
||||
in = buf->mem;
|
||||
in = (fuse_in_header*)buf->mem;
|
||||
}
|
||||
|
||||
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);
|
||||
if (req == NULL) {
|
||||
struct fuse_out_header out = {
|
||||
.unique = in->unique,
|
||||
.error = -ENOMEM,
|
||||
};
|
||||
struct iovec iov = {
|
||||
.iov_base = &out,
|
||||
.iov_len = sizeof(struct fuse_out_header),
|
||||
};
|
||||
if (req == NULL)
|
||||
{
|
||||
struct fuse_out_header out;
|
||||
struct iovec iov;
|
||||
|
||||
fuse_send_msg(f, ch, &iov, 1);
|
||||
goto clear_pipe;
|
||||
}
|
||||
out.unique = in->unique;
|
||||
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->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);
|
||||
}
|
||||
|
||||
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_NOTIFY_REPLY) {
|
||||
void *newmbuf;
|
||||
|
@ -2501,7 +2464,7 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
|
|||
newmbuf = realloc(mbuf, buf->size);
|
||||
if (newmbuf == NULL)
|
||||
goto reply_err;
|
||||
mbuf = newmbuf;
|
||||
mbuf = (char*)newmbuf;
|
||||
|
||||
tmpbuf = FUSE_BUFVEC_INIT(buf->size - 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)
|
||||
goto reply_err;
|
||||
|
||||
in = mbuf;
|
||||
in = (fuse_in_header*)mbuf;
|
||||
}
|
||||
|
||||
inarg = (void *) &in[1];
|
||||
|
@ -2529,7 +2492,7 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
|
|||
reply_err:
|
||||
fuse_reply_err(req, err);
|
||||
clear_pipe:
|
||||
if (buf->flags & FUSE_BUF_IS_FD)
|
||||
if (buf->flags & FUSE_BUF_FLAG_IS_FD)
|
||||
fuse_ll_clear_pipe(f);
|
||||
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,
|
||||
struct fuse_chan *ch)
|
||||
{
|
||||
struct fuse_buf fbuf = {
|
||||
.mem = (void *) buf,
|
||||
.size = len,
|
||||
};
|
||||
struct fuse_buf fbuf;
|
||||
|
||||
fbuf.mem = (char*)buf;
|
||||
fbuf.size = len;
|
||||
|
||||
fuse_ll_process_buf(data, &fbuf, ch);
|
||||
}
|
||||
|
@ -2632,7 +2595,7 @@ static void fuse_ll_destroy(void *data)
|
|||
if (f->op.destroy)
|
||||
f->op.destroy(f->userdata);
|
||||
}
|
||||
llp = pthread_getspecific(f->pipe_key);
|
||||
llp = (fuse_ll_pipe*)pthread_getspecific(f->pipe_key);
|
||||
if (llp != NULL)
|
||||
fuse_ll_pipe_free(llp);
|
||||
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)
|
||||
{
|
||||
struct fuse_ll_pipe *llp = data;
|
||||
struct fuse_ll_pipe *llp = (fuse_ll_pipe*)data;
|
||||
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 *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;
|
||||
struct fuse_ll_pipe *llp;
|
||||
struct fuse_buf tmpbuf;
|
||||
|
@ -2694,26 +2657,28 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
|
|||
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");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
tmpbuf = (struct fuse_buf) {
|
||||
.size = res,
|
||||
.flags = FUSE_BUF_IS_FD,
|
||||
.fd = llp->pipe[0],
|
||||
};
|
||||
tmpbuf.size = (size_t)res;
|
||||
tmpbuf.flags = FUSE_BUF_FLAG_IS_FD;
|
||||
tmpbuf.fd = llp->pipe[0];
|
||||
|
||||
/*
|
||||
* Don't bother with zero copy for small requests.
|
||||
* fuse_loop_mt() needs to check for FORGET so this more than
|
||||
* just an optimization.
|
||||
*/
|
||||
if (res < sizeof(struct fuse_in_header) +
|
||||
sizeof(struct fuse_write_in) + pagesize) {
|
||||
struct fuse_bufvec src = { .buf[0] = tmpbuf, .count = 1 };
|
||||
struct fuse_bufvec dst = { .buf[0] = *buf, .count = 1 };
|
||||
if (res < (int)(sizeof(struct fuse_in_header) + sizeof(struct fuse_write_in) + pagesize)) {
|
||||
struct fuse_bufvec src;
|
||||
struct fuse_bufvec dst;
|
||||
|
||||
src.buf[0] = tmpbuf;
|
||||
src.count = 1;
|
||||
dst.buf[0] = *buf;
|
||||
dst.count = 1;
|
||||
|
||||
res = fuse_buf_copy(&dst, &src, 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);
|
||||
return res;
|
||||
}
|
||||
if (res < tmpbuf.size) {
|
||||
if (res < (int)tmpbuf.size) {
|
||||
fprintf(stderr, "fuse: copy from pipe: short read\n");
|
||||
fuse_ll_clear_pipe(f);
|
||||
return -EIO;
|
||||
|
@ -2760,6 +2725,53 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
|
|||
}
|
||||
#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
|
||||
|
@ -2773,10 +2785,12 @@ struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,
|
|||
int err;
|
||||
struct fuse_ll *f;
|
||||
struct fuse_session *se;
|
||||
struct fuse_session_ops sop = {
|
||||
.process = fuse_ll_process,
|
||||
.destroy = fuse_ll_destroy,
|
||||
};
|
||||
struct fuse_session_ops sop;
|
||||
|
||||
fuse_lowlevel_setup_ops();
|
||||
|
||||
sop.process = fuse_ll_process;
|
||||
sop.destroy = fuse_ll_destroy;
|
||||
|
||||
if (sizeof(struct fuse_lowlevel_ops) < op_size) {
|
||||
fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");
|
||||
|
|
|
@ -75,14 +75,14 @@ int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data)
|
|||
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,
|
||||
};
|
||||
struct fuse_session_ops sop;
|
||||
struct fuse_chan_ops cop;
|
||||
|
||||
sop.exit = mt_session_exit;
|
||||
sop.exited = mt_session_exited;
|
||||
sop.process = mt_session_proc;
|
||||
|
||||
cop.receive = mt_chan_receive;
|
||||
|
||||
pd.f = f;
|
||||
pd.prevch = prevch;
|
||||
|
|
|
@ -63,7 +63,7 @@ fuse_opt_add_arg(struct fuse_args *args, const char *arg)
|
|||
if (!newarg)
|
||||
return alloc_failed();
|
||||
|
||||
newargv = realloc(args->argv, (args->argc + 2) * sizeof(char *));
|
||||
newargv = (char**)realloc(args->argv, (args->argc + 2) * sizeof(char *));
|
||||
if (!newargv) {
|
||||
free(newarg);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
return -1;
|
||||
} else {
|
||||
void *var = ctx->data + opt->offset;
|
||||
void *var = (char*)ctx->data + opt->offset;
|
||||
if (sep && opt->templ[sep + 1]) {
|
||||
const char *param = arg + sep;
|
||||
if (opt->templ[sep] == '=')
|
||||
|
@ -257,7 +257,7 @@ static int process_opt_sep_arg(struct fuse_opt_context *ctx,
|
|||
return -1;
|
||||
|
||||
param = ctx->argv[ctx->argctr];
|
||||
newarg = malloc(sep + strlen(param) + 1);
|
||||
newarg = (char*)malloc(sep + strlen(param) + 1);
|
||||
if (!newarg)
|
||||
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)
|
||||
{
|
||||
int res;
|
||||
struct fuse_opt_context ctx = {
|
||||
.data = data,
|
||||
.opt = opts,
|
||||
.proc = proc,
|
||||
};
|
||||
struct fuse_opt_context ctx;
|
||||
|
||||
if (!args || !args->argv || !args->argc)
|
||||
if(!args || !args->argv || !args->argc)
|
||||
return 0;
|
||||
|
||||
ctx.data = data;
|
||||
ctx.opt = opts;
|
||||
ctx.proc = proc;
|
||||
ctx.argc = args->argc;
|
||||
ctx.argv = args->argv;
|
||||
|
||||
|
|
|
@ -79,8 +79,8 @@ void fuse_session_process_buf(struct fuse_session *se,
|
|||
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);
|
||||
assert(!(buf->flags & FUSE_BUF_FLAG_IS_FD));
|
||||
fuse_session_process((fuse_session*)se->data, buf->mem, buf->size, ch);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ static void helper_version(void)
|
|||
static int fuse_helper_opt_proc(void *data, const char *arg, int key,
|
||||
struct fuse_args *outargs)
|
||||
{
|
||||
struct helper_opts *hopts = data;
|
||||
struct helper_opts *hopts = (helper_opts*)data;
|
||||
|
||||
switch (key) {
|
||||
case KEY_HELP:
|
||||
|
|
|
@ -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,
|
||||
struct fuse_args *outargs)
|
||||
{
|
||||
struct mount_opts *mo = data;
|
||||
struct mount_opts *mo = (mount_opts*)data;
|
||||
|
||||
switch (key) {
|
||||
case KEY_ALLOW_ROOT:
|
||||
|
@ -465,11 +465,11 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
|
|||
if (res == -1)
|
||||
goto out_close;
|
||||
|
||||
source = malloc((mo->fsname ? strlen(mo->fsname) : 0) +
|
||||
(mo->subtype ? strlen(mo->subtype) : 0) +
|
||||
strlen(devname) + 32);
|
||||
source = (char*)malloc((mo->fsname ? strlen(mo->fsname) : 0) +
|
||||
(mo->subtype ? strlen(mo->subtype) : 0) +
|
||||
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) {
|
||||
fprintf(stderr, "fuse: failed to allocate memory\n");
|
||||
goto out_close;
|
||||
|
|
|
@ -235,7 +235,7 @@ static int may_unmount(const char *mnt, int quiet)
|
|||
*/
|
||||
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 *mnt = a[1];
|
||||
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)
|
||||
goto err;
|
||||
|
||||
source = malloc((fsname ? strlen(fsname) : 0) +
|
||||
(subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
|
||||
source = (char*)malloc((fsname ? strlen(fsname) : 0) +
|
||||
(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) {
|
||||
fprintf(stderr, "%s: failed to allocate memory\n", progname);
|
||||
goto err;
|
||||
|
|
|
@ -38,7 +38,7 @@ static void add_arg(char **cmdp, const char *opt)
|
|||
{
|
||||
size_t optlen = strlen(opt);
|
||||
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;
|
||||
s = cmd + cmdlen;
|
||||
if (*cmdp)
|
||||
|
@ -63,7 +63,7 @@ static char *add_option(const char *opt, char *options)
|
|||
{
|
||||
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)
|
||||
strcpy(options, opt);
|
||||
else {
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace l
|
|||
|
||||
*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->pos = offset_;
|
||||
|
||||
|
|
|
@ -49,10 +49,9 @@ namespace l
|
|||
{
|
||||
size_t size = fuse_buf_size(src_);
|
||||
fuse_bufvec dst = FUSE_BUFVEC_INIT(size);
|
||||
const fuse_buf_copy_flags cpflags =
|
||||
(fuse_buf_copy_flags)(FUSE_BUF_SPLICE_MOVE|FUSE_BUF_SPLICE_NONBLOCK);
|
||||
const int cpflags = (FUSE_BUF_COPY_FLAG_SPLICE_MOVE|FUSE_BUF_COPY_FLAG_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->pos = offset_;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user