Browse Source

Major cleanup of libfuse to remove unneeded features

* Remove request interrupt code. Required tracking of all requests unnecesssarily.
* Remove all debugging printing. Have plans to do full replacement.
* Remove deprecated functions.
* Remove unneeded error checking.
* Remove "userdata" which was unused.
* Remove allow_root feature.
pull/954/head
Antonio SJ Musumeci 3 years ago
parent
commit
43a6d66e3c
  1. 64
      libfuse/include/fuse.h
  2. 30
      libfuse/include/fuse_lowlevel.h
  3. 787
      libfuse/lib/fuse.c
  4. 22
      libfuse/lib/fuse_i.h
  5. 836
      libfuse/lib/fuse_lowlevel.c
  6. 22
      libfuse/lib/helper.c
  7. 15
      libfuse/lib/mount_bsd.c
  8. 15
      libfuse/lib/mount_generic.c
  9. 4
      libfuse/util/fusermount.c
  10. 39
      src/fuse_bmap.cpp
  11. 29
      src/fuse_bmap.hpp
  12. 2
      src/fuse_destroy.cpp
  13. 2
      src/fuse_destroy.hpp
  14. 33
      src/fuse_lock.cpp
  15. 29
      src/fuse_lock.hpp
  16. 37
      src/fuse_poll.cpp
  17. 17
      src/fuse_poll.hpp
  18. 88
      src/fuse_read.cpp
  19. 28
      src/fuse_read_buf.cpp
  20. 6
      src/fuse_read_buf.hpp
  21. 21
      src/mergerfs.cpp

64
libfuse/include/fuse.h

@ -140,12 +140,6 @@ struct fuse_operations
/** Change the size of a file */
int (*truncate) (const char *, off_t);
/** Change the access and/or modification times of a file
*
* Deprecated, use utimens() instead.
*/
int (*utime) (const char *, struct utimbuf *);
/** File open operation
*
* No creation (O_CREAT, O_EXCL) and by default also no
@ -165,35 +159,6 @@ struct fuse_operations
*/
int (*open) (const char *, fuse_file_info_t *);
/** Read data from an open file
*
* Read should return exactly the number of bytes requested except
* on EOF or error, otherwise the rest of the data will be
* substituted with zeroes. An exception to this is when the
* 'direct_io' mount option is specified, in which case the return
* value of the read system call will reflect the return value of
* this operation.
*
* Changed in version 2.2
*/
int (*read) (const fuse_file_info_t *,
char *,
size_t,
off_t);
/** Write data to an open file
*
* Write should return exactly the number of bytes requested
* except on error. An exception to this is when the 'direct_io'
* mount option is specified (see read operation).
*
* Changed in version 2.2
*/
int (*write) (const fuse_file_info_t *,
const char *,
size_t,
off_t);
/** Get file system statistics
*
* The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
@ -340,7 +305,7 @@ struct fuse_operations
*
* Introduced in version 2.3
*/
void (*destroy) (void *);
void (*destroy) (void);
/**
* Check file access permissions
@ -606,9 +571,6 @@ struct fuse_context
/** Thread ID of the calling process */
pid_t pid;
/** Private filesystem data */
void *private_data;
/** Umask of the calling process (introduced in version 2.8) */
mode_t umask;
};
@ -633,15 +595,13 @@ struct fuse_context
* @param argc the argument counter passed to the main() function
* @param argv the argument vector passed to the main() function
* @param op the file system operation
* @param user_data user data supplied in the context during the init() method
* @return 0 on success, nonzero on failure
*/
/*
int fuse_main(int argc, char *argv[], const struct fuse_operations *op,
void *user_data);
int fuse_main(int argc, char *argv[], const struct fuse_operations *op);
*/
#define fuse_main(argc, argv, op, user_data) \
fuse_main_real(argc, argv, op, sizeof(*(op)), user_data)
#define fuse_main(argc, argv, op) \
fuse_main_real(argc, argv, op, sizeof(*(op)))
/* ----------------------------------------------------------- *
* More detailed API *
@ -654,12 +614,10 @@ struct fuse_context
* @param args argument vector
* @param op the filesystem operations
* @param op_size the size of the fuse_operations structure
* @param user_data user data supplied in the context during the init() method
* @return the created FUSE handle
*/
struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *op, size_t op_size,
void *user_data);
const struct fuse_operations *op, size_t op_size);
/**
* Destroy the FUSE handle.
@ -729,8 +687,7 @@ int fuse_is_lib_option(const char *opt);
*
* Do not call this directly, use fuse_main()
*/
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
size_t op_size, void *user_data);
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, size_t op_size);
/**
* Start the cleanup thread when using option "remember".
@ -813,8 +770,6 @@ int fuse_fs_read(struct fuse_fs *fs, char *buf, size_t size,
int fuse_fs_read_buf(struct fuse_fs *fs,
struct fuse_bufvec **bufp, size_t size, off_t off,
fuse_file_info_t *fi);
int fuse_fs_write(struct fuse_fs *fs, const char *buf,
size_t size, off_t off, fuse_file_info_t *fi);
int fuse_fs_write_buf(struct fuse_fs *fs,
struct fuse_bufvec *buf, off_t off,
fuse_file_info_t *fi);
@ -889,11 +844,9 @@ int fuse_notify_poll(fuse_pollhandle_t *ph);
*
* @param op the filesystem operations
* @param op_size the size of the fuse_operations structure
* @param user_data user data supplied in the context during the init() method
* @return a new filesystem object
*/
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
void *user_data);
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size);
/* ----------------------------------------------------------- *
* Advanced API for event handling, don't worry about this... *
@ -908,8 +861,7 @@ typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *);
/** This is the part of fuse_main() before the event loop */
struct fuse *fuse_setup(int argc, char *argv[],
const struct fuse_operations *op, size_t op_size,
char **mountpoint,
void *user_data);
char **mountpoint);
/** This is the part of fuse_main() after the event loop */
void fuse_teardown(struct fuse *fuse, char *mountpoint);

30
libfuse/include/fuse_lowlevel.h

@ -1482,36 +1482,6 @@ const struct fuse_ctx *fuse_req_ctx(fuse_req_t req);
*/
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]);
/**
* Callback function for an interrupt
*
* @param req interrupted request
* @param data user data
*/
typedef void (*fuse_interrupt_func_t)(fuse_req_t req, void *data);
/**
* Register/unregister callback for an interrupt
*
* If an interrupt has already happened, then the callback function is
* called from within this function, hence it's not possible for
* interrupts to be lost.
*
* @param req request handle
* @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 *data);
/**
* Check if a request has already been interrupted
*
* @param req request handle
* @return 1 if the request has been interrupted, 0 otherwise
*/
int fuse_req_interrupted(fuse_req_t req);
/* ----------------------------------------------------------- *
* Filesystem setup *
* ----------------------------------------------------------- */

787
libfuse/lib/fuse.c
File diff suppressed because it is too large
View File

22
libfuse/lib/fuse_i.h

@ -35,23 +35,9 @@ struct fuse_req
{
struct fuse_ll *f;
uint64_t unique;
int ctr;
pthread_mutex_t lock;
struct fuse_ctx ctx;
struct fuse_chan *ch;
int interrupted;
unsigned int ioctl_64bit : 1;
union {
struct {
uint64_t unique;
} i;
struct {
fuse_interrupt_func_t func;
void *data;
} ni;
} u;
struct fuse_req *next;
struct fuse_req *prev;
};
struct fuse_notify_req
@ -66,7 +52,6 @@ struct fuse_notify_req
struct fuse_ll
{
int debug;
int allow_root;
int no_remote_posix_lock;
int no_remote_flock;
int big_writes;
@ -81,8 +66,6 @@ struct fuse_ll
void *userdata;
uid_t owner;
struct fuse_conn_info conn;
struct fuse_req list;
struct fuse_req interrupts;
pthread_mutex_t lock;
int got_destroy;
pthread_key_t pipe_key;
@ -100,7 +83,7 @@ struct fuse_cmd
struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *op,
size_t op_size, void *user_data);
size_t op_size);
struct fuse_chan *fuse_kern_chan_new(int fd);
@ -122,7 +105,6 @@ struct fuse *fuse_setup_common(int argc, char *argv[],
const struct fuse_operations *op,
size_t op_size,
char **mountpoint,
int *fd,
void *user_data);
int *fd);
int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg);

836
libfuse/lib/fuse_lowlevel.c
File diff suppressed because it is too large
View File

22
libfuse/lib/helper.c

@ -290,8 +290,7 @@ struct fuse *fuse_setup_common(int argc, char *argv[],
const struct fuse_operations *op,
size_t op_size,
char **mountpoint,
int *fd,
void *user_data)
int *fd)
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
struct fuse_chan *ch;
@ -309,7 +308,7 @@ struct fuse *fuse_setup_common(int argc, char *argv[],
goto err_free;
}
fuse = fuse_new_common(ch, &args, op, op_size, user_data);
fuse = fuse_new_common(ch, &args, op, op_size);
fuse_opt_free_args(&args);
if (fuse == NULL)
goto err_unmount;
@ -338,10 +337,10 @@ struct fuse *fuse_setup_common(int argc, char *argv[],
struct fuse *fuse_setup(int argc, char *argv[],
const struct fuse_operations *op, size_t op_size,
char **mountpoint, void *user_data)
char **mountpoint)
{
return fuse_setup_common(argc, argv, op, op_size, mountpoint,
NULL, user_data);
NULL);
}
static void fuse_teardown_common(struct fuse *fuse, char *mountpoint)
@ -360,8 +359,7 @@ void fuse_teardown(struct fuse *fuse, char *mountpoint)
}
static int fuse_main_common(int argc, char *argv[],
const struct fuse_operations *op, size_t op_size,
void *user_data)
const struct fuse_operations *op, size_t op_size)
{
struct fuse *fuse;
char *mountpoint;
@ -369,7 +367,7 @@ static int fuse_main_common(int argc, char *argv[],
fuse = fuse_setup_common(argc, argv, op, op_size,
&mountpoint,
NULL, user_data);
NULL);
if (fuse == NULL)
return 1;
@ -382,10 +380,12 @@ static int fuse_main_common(int argc, char *argv[],
return 0;
}
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
size_t op_size, void *user_data)
int fuse_main_real(int argc,
char *argv[],
const struct fuse_operations *op,
size_t op_size)
{
return fuse_main_common(argc, argv, op, op_size, user_data);
return fuse_main_common(argc, argv, op, op_size);
}
#undef fuse_main

15
libfuse/lib/mount_bsd.c

@ -28,7 +28,6 @@
#define FUSE_DEV_TRUNK "/dev/fuse"
enum {
KEY_ALLOW_ROOT,
KEY_RO,
KEY_HELP,
KEY_VERSION,
@ -37,7 +36,6 @@ enum {
struct mount_opts {
int allow_other;
int allow_root;
int ishelp;
char *kernel_opts;
};
@ -47,8 +45,6 @@ struct mount_opts {
static const struct fuse_opt fuse_mount_opts[] = {
{ "allow_other", offsetof(struct mount_opts, allow_other), 1 },
{ "allow_root", offsetof(struct mount_opts, allow_root), 1 },
FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
FUSE_OPT_KEY("-r", KEY_RO),
FUSE_OPT_KEY("-h", KEY_HELP),
FUSE_OPT_KEY("--help", KEY_HELP),
@ -102,7 +98,6 @@ static const struct fuse_opt fuse_mount_opts[] = {
static void mount_help(void)
{
fprintf(stderr,
" -o allow_root allow access to root\n"
);
system(FUSERMOUNT_PROG " --help");
fputc('\n', stderr);
@ -119,12 +114,6 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key,
struct mount_opts *mo = data;
switch (key) {
case KEY_ALLOW_ROOT:
if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
fuse_opt_add_arg(outargs, "-oallow_root") == -1)
return -1;
return 0;
case KEY_RO:
arg = "ro";
/* fall through */
@ -328,10 +317,6 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
return -1;
if (mo.allow_other && mo.allow_root) {
fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
goto out;
}
if (mo.ishelp)
return 0;

15
libfuse/lib/mount_generic.c

@ -55,7 +55,6 @@ enum {
KEY_FUSERMOUNT_OPT,
KEY_SUBTYPE_OPT,
KEY_MTAB_OPT,
KEY_ALLOW_ROOT,
KEY_RO,
KEY_HELP,
KEY_VERSION,
@ -63,7 +62,6 @@ enum {
struct mount_opts {
int allow_other;
int allow_root;
int ishelp;
int flags;
int nonempty;
@ -81,14 +79,12 @@ struct mount_opts {
static const struct fuse_opt fuse_mount_opts[] = {
FUSE_MOUNT_OPT("allow_other", allow_other),
FUSE_MOUNT_OPT("allow_root", allow_root),
FUSE_MOUNT_OPT("nonempty", nonempty),
FUSE_MOUNT_OPT("blkdev", blkdev),
FUSE_MOUNT_OPT("auto_unmount", auto_unmount),
FUSE_MOUNT_OPT("fsname=%s", fsname),
FUSE_MOUNT_OPT("subtype=%s", subtype),
FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
FUSE_OPT_KEY("nonempty", KEY_FUSERMOUNT_OPT),
FUSE_OPT_KEY("auto_unmount", KEY_FUSERMOUNT_OPT),
FUSE_OPT_KEY("blkdev", KEY_FUSERMOUNT_OPT),
@ -129,7 +125,6 @@ static void mount_help(void)
{
fprintf(stderr,
" -o allow_other allow access to other users\n"
" -o allow_root allow access to root\n"
" -o auto_unmount auto unmount on process termination\n"
" -o nonempty allow mounts over non-empty file/dir\n"
" -o default_permissions enable permission checking by kernel\n"
@ -208,12 +203,6 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key,
struct mount_opts *mo = data;
switch (key) {
case KEY_ALLOW_ROOT:
if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
fuse_opt_add_arg(outargs, "-oallow_root") == -1)
return -1;
return 0;
case KEY_RO:
arg = "ro";
/* fall through */
@ -575,10 +564,6 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
return -1;
if (mo.allow_other && mo.allow_root) {
fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
goto out;
}
res = 0;
if (mo.ishelp)
goto out;

4
libfuse/util/fusermount.c

@ -782,9 +782,7 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode,
skip_option = 1;
}
}
if (getuid() != 0 && !user_allow_other &&
(opt_eq(s, len, "allow_other") ||
opt_eq(s, len, "allow_root"))) {
if (getuid() != 0 && !user_allow_other && opt_eq(s, len, "allow_other")) {
fprintf(stderr, "%s: option %.*s only allowed if 'user_allow_other' is set in /etc/fuse.conf\n", progname, len, s);
goto err;
}

39
src/fuse_bmap.cpp

@ -0,0 +1,39 @@
/*
ISC License
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include <cstdint>
#include <stddef.h>
namespace FUSE
{
int
bmap(const char *fusepath_,
size_t blocksize_,
uint64_t *idx_)
{
(void)fusepath_;
(void)blocksize_;
(void)idx_;
return -ENOSYS;
}
}

29
src/fuse_bmap.hpp

@ -0,0 +1,29 @@
/*
ISC License
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse.h"
namespace FUSE
{
int
bmap(const char *fusepath,
size_t blocksize,
uint64_t *idx);
}

2
src/fuse_destroy.cpp

@ -17,7 +17,7 @@
namespace FUSE
{
void
destroy(void *)
destroy(void)
{
}

2
src/fuse_destroy.hpp

@ -20,5 +20,5 @@
namespace FUSE
{
void
destroy(void *);
destroy(void);
}

33
src/fuse_lock.cpp

@ -0,0 +1,33 @@
/*
ISC License
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fuse.h"
namespace FUSE
{
int
lock(const fuse_file_info_t *ffi,
int cmd,
struct flock *flock)
{
return -ENOSYS;
}
}

29
src/fuse_lock.hpp

@ -0,0 +1,29 @@
/*
ISC License
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse.h"
namespace FUSE
{
int
lock(const fuse_file_info_t *ffi,
int cmd,
struct flock *flock);
}

37
src/fuse_poll.cpp

@ -0,0 +1,37 @@
/*
ISC License
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fuse.h"
namespace FUSE
{
int
poll(const fuse_file_info_t *ffi_,
fuse_pollhandle_t *ph_,
unsigned *reventsp_)
{
(void)ffi_;
(void)ph_;
(void)reventsp_;
return -ENOSYS;
}
}

17
src/fuse_read.hpp → src/fuse_poll.hpp

@ -1,5 +1,7 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
ISC License
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@ -22,14 +24,7 @@
namespace FUSE
{
int
read(const fuse_file_info_t *ffi,
char *buf,
size_t count,
off_t offset);
int
read_null(const fuse_file_info_t *ffi,
char *buf,
size_t count,
off_t offset);
poll(const fuse_file_info_t *ffi,
fuse_pollhandle_t *ph,
unsigned *reventsp);
}

88
src/fuse_read.cpp

@ -1,88 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_read.hpp"
#include "fuse.h"
namespace l
{
static
inline
int
read_regular(const int fd_,
void *buf_,
const size_t count_,
const off_t offset_)
{
int rv;
rv = fs::pread(fd_,buf_,count_,offset_);
if(rv == -1)
return -errno;
if(rv == 0)
return 0;
return count_;
}
static
inline
int
read_direct_io(const int fd_,
void *buf_,
const size_t count_,
const off_t offset_)
{
int rv;
rv = fs::pread(fd_,buf_,count_,offset_);
if(rv == -1)
return -errno;
return rv;
}
}
namespace FUSE
{
int
read(const fuse_file_info_t *ffi_,
char *buf_,
size_t count_,
off_t offset_)
{
FileInfo *fi;
fi = reinterpret_cast<FileInfo*>(ffi_->fh);
if(ffi_->direct_io)
return l::read_direct_io(fi->fd,buf_,count_,offset_);
return l::read_regular(fi->fd,buf_,count_,offset_);
}
int
read_null(const fuse_file_info_t *ffi_,
char *buf_,
size_t count_,
off_t offset_)
{
return count_;
}
}

28
src/fuse_read_buf.cpp

@ -67,4 +67,32 @@ namespace FUSE
size_,
offset_);
}
int
read_buf_null(const fuse_file_info_t *ffi_,
fuse_bufvec **bufp_,
size_t size_,
off_t offset_)
{
void *mem;
struct fuse_bufvec *buf;
buf = (struct fuse_bufvec*)malloc(sizeof(struct fuse_bufvec));
if(buf == NULL)
return -ENOMEM;
mem = (void*)calloc(1,size_);
if(mem == NULL)
{
free(buf);
return -ENOMEM;
}
*buf = FUSE_BUFVEC_INIT(size_);
buf->buf[0].mem = mem;
*bufp_ = buf;
return 0;
}
}

6
src/fuse_read_buf.hpp

@ -28,4 +28,10 @@ namespace FUSE
struct fuse_bufvec **buf,
size_t size,
off_t offset);
int
read_buf_null(const fuse_file_info_t *ffi,
struct fuse_bufvec **buf,
size_t size,
off_t offset);
}

21
src/mergerfs.cpp

@ -21,6 +21,7 @@
#include "strvec.hpp"
#include "fuse_access.hpp"
#include "fuse_bmap.hpp"
#include "fuse_chmod.hpp"
#include "fuse_chown.hpp"
#include "fuse_copy_file_range.hpp"
@ -43,12 +44,13 @@
#include "fuse_ioctl.hpp"
#include "fuse_link.hpp"
#include "fuse_listxattr.hpp"
#include "fuse_lock.hpp"
#include "fuse_mkdir.hpp"
#include "fuse_mknod.hpp"
#include "fuse_open.hpp"
#include "fuse_opendir.hpp"
#include "fuse_poll.hpp"
#include "fuse_prepare_hide.hpp"
#include "fuse_read.hpp"
#include "fuse_read_buf.hpp"
#include "fuse_readdir.hpp"
#include "fuse_readdir_plus.hpp"
@ -64,7 +66,6 @@
#include "fuse_truncate.hpp"
#include "fuse_unlink.hpp"
#include "fuse_utimens.hpp"
#include "fuse_write.hpp"
#include "fuse_write_buf.hpp"
#include "fuse.h"
@ -83,7 +84,7 @@ namespace l
const bool nullrw_)
{
ops_.access = FUSE::access;
ops_.bmap = NULL;
ops_.bmap = FUSE::bmap;
ops_.chmod = FUSE::chmod;
ops_.chown = FUSE::chown;
ops_.copy_file_range = FUSE::copy_file_range;
@ -93,7 +94,7 @@ namespace l
ops_.fchmod = FUSE::fchmod;
ops_.fchown = FUSE::fchown;
ops_.fgetattr = FUSE::fgetattr;
ops_.flock = NULL; // FUSE::flock;
ops_.flock = FUSE::flock;
ops_.flush = FUSE::flush;
ops_.free_hide = FUSE::free_hide;
ops_.fsync = FUSE::fsync;
@ -106,15 +107,14 @@ namespace l
ops_.ioctl = FUSE::ioctl;
ops_.link = FUSE::link;
ops_.listxattr = FUSE::listxattr;
ops_.lock = NULL;
ops_.lock = FUSE::lock;
ops_.mkdir = FUSE::mkdir;
ops_.mknod = FUSE::mknod;
ops_.open = FUSE::open;
ops_.opendir = FUSE::opendir;
ops_.poll = NULL;
ops_.poll = FUSE::poll;;
ops_.prepare_hide = FUSE::prepare_hide;
ops_.read = (nullrw_ ? FUSE::read_null : FUSE::read);
ops_.read_buf = (nullrw_ ? NULL : FUSE::read_buf);
ops_.read_buf = (nullrw_ ? FUSE::read_buf_null : FUSE::read_buf);
ops_.readdir = FUSE::readdir;
ops_.readdir_plus = FUSE::readdir_plus;
ops_.readlink = FUSE::readlink;
@ -128,9 +128,7 @@ namespace l
ops_.symlink = FUSE::symlink;
ops_.truncate = FUSE::truncate;
ops_.unlink = FUSE::unlink;
ops_.utime = NULL; /* deprecated; use utimens() */
ops_.utimens = FUSE::utimens;
ops_.write = (nullrw_ ? FUSE::write_null : FUSE::write);
ops_.write_buf = (nullrw_ ? FUSE::write_buf_null : FUSE::write_buf);
return;
@ -173,8 +171,7 @@ namespace l
return fuse_main(args.argc,
args.argv,
&ops,
NULL);
&ops);
}
}

Loading…
Cancel
Save