mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-02-02 05:57:15 +08:00
libfuse cleanup: remove cuse
This commit is contained in:
parent
5f12fb6a5f
commit
3bfdd78434
|
@ -31,7 +31,6 @@ INSTALLMAN1DIR = $(DESTDIR)$(MAN1DIR)
|
||||||
|
|
||||||
SRC = \
|
SRC = \
|
||||||
lib/buffer.c \
|
lib/buffer.c \
|
||||||
lib/cuse_lowlevel.c \
|
|
||||||
lib/fuse_dirents.c \
|
lib/fuse_dirents.c \
|
||||||
lib/fuse.c \
|
lib/fuse.c \
|
||||||
lib/fuse_kern_chan.c \
|
lib/fuse_kern_chan.c \
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
## Process this file with automake to produce Makefile.in
|
|
||||||
|
|
||||||
fuseincludedir=$(includedir)/fuse
|
|
||||||
|
|
||||||
fuseinclude_HEADERS = \
|
|
||||||
fuse.h \
|
|
||||||
fuse_compat.h \
|
|
||||||
fuse_common.h \
|
|
||||||
fuse_common_compat.h \
|
|
||||||
fuse_lowlevel.h \
|
|
||||||
fuse_lowlevel_compat.h \
|
|
||||||
fuse_opt.h \
|
|
||||||
cuse_lowlevel.h
|
|
||||||
|
|
||||||
include_HEADERS = old/fuse.h ulockmgr.h
|
|
||||||
|
|
||||||
noinst_HEADERS = fuse_kernel.h
|
|
|
@ -1,87 +0,0 @@
|
||||||
/*
|
|
||||||
CUSE: Character device in Userspace
|
|
||||||
Copyright (C) 2008-2009 SUSE Linux Products GmbH
|
|
||||||
Copyright (C) 2008-2009 Tejun Heo <tj@kernel.org>
|
|
||||||
|
|
||||||
This program can be distributed under the terms of the GNU LGPLv2.
|
|
||||||
See the file COPYING.LIB.
|
|
||||||
|
|
||||||
Read example/cusexmp.c for usages.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CUSE_LOWLEVEL_H_
|
|
||||||
#define _CUSE_LOWLEVEL_H_
|
|
||||||
|
|
||||||
#ifndef FUSE_USE_VERSION
|
|
||||||
#define FUSE_USE_VERSION 29
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "fuse_lowlevel.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/uio.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CUSE_UNRESTRICTED_IOCTL (1 << 0) /* use unrestricted ioctl */
|
|
||||||
|
|
||||||
struct fuse_session;
|
|
||||||
|
|
||||||
struct cuse_info {
|
|
||||||
unsigned dev_major;
|
|
||||||
unsigned dev_minor;
|
|
||||||
unsigned dev_info_argc;
|
|
||||||
const char **dev_info_argv;
|
|
||||||
unsigned flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Most ops behave almost identically to the matching fuse_lowlevel
|
|
||||||
* ops except that they don't take @ino.
|
|
||||||
*
|
|
||||||
* init_done : called after initialization is complete
|
|
||||||
* read/write : always direct IO, simultaneous operations allowed
|
|
||||||
* ioctl : might be in unrestricted mode depending on ci->flags
|
|
||||||
*/
|
|
||||||
struct cuse_lowlevel_ops {
|
|
||||||
void (*init) (void *userdata, struct fuse_conn_info *conn);
|
|
||||||
void (*init_done) (void *userdata);
|
|
||||||
void (*destroy) (void *userdata);
|
|
||||||
void (*open) (fuse_req_t req, struct fuse_file_info *fi);
|
|
||||||
void (*read) (fuse_req_t req, size_t size, off_t off,
|
|
||||||
struct fuse_file_info *fi);
|
|
||||||
void (*write) (fuse_req_t req, const char *buf, size_t size, off_t off,
|
|
||||||
struct fuse_file_info *fi);
|
|
||||||
void (*flush) (fuse_req_t req, struct fuse_file_info *fi);
|
|
||||||
void (*release) (fuse_req_t req, struct fuse_file_info *fi);
|
|
||||||
void (*fsync) (fuse_req_t req, int datasync, struct fuse_file_info *fi);
|
|
||||||
void (*ioctl) (fuse_req_t req, int cmd, void *arg,
|
|
||||||
struct fuse_file_info *fi, unsigned int flags,
|
|
||||||
const void *in_buf, size_t in_bufsz, size_t out_bufsz);
|
|
||||||
void (*poll) (fuse_req_t req, struct fuse_file_info *fi,
|
|
||||||
struct fuse_pollhandle *ph);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fuse_session *cuse_lowlevel_new(struct fuse_args *args,
|
|
||||||
const struct cuse_info *ci,
|
|
||||||
const struct cuse_lowlevel_ops *clop,
|
|
||||||
void *userdata);
|
|
||||||
|
|
||||||
struct fuse_session *cuse_lowlevel_setup(int argc, char *argv[],
|
|
||||||
const struct cuse_info *ci,
|
|
||||||
const struct cuse_lowlevel_ops *clop,
|
|
||||||
int *multithreaded, void *userdata);
|
|
||||||
|
|
||||||
void cuse_lowlevel_teardown(struct fuse_session *se);
|
|
||||||
|
|
||||||
int cuse_lowlevel_main(int argc, char *argv[], const struct cuse_info *ci,
|
|
||||||
const struct cuse_lowlevel_ops *clop, void *userdata);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _CUSE_LOWLEVEL_H_ */
|
|
|
@ -1,371 +0,0 @@
|
||||||
/*
|
|
||||||
CUSE: Character device in Userspace
|
|
||||||
Copyright (C) 2008 SUSE Linux Products GmbH
|
|
||||||
Copyright (C) 2008 Tejun Heo <teheo@suse.de>
|
|
||||||
|
|
||||||
This program can be distributed under the terms of the GNU LGPLv2.
|
|
||||||
See the file COPYING.LIB.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "cuse_lowlevel.h"
|
|
||||||
#include "fuse_kernel.h"
|
|
||||||
#include "fuse_i.h"
|
|
||||||
#include "fuse_opt.h"
|
|
||||||
#include "fuse_misc.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
struct cuse_data {
|
|
||||||
struct cuse_lowlevel_ops clop;
|
|
||||||
unsigned max_read;
|
|
||||||
unsigned dev_major;
|
|
||||||
unsigned dev_minor;
|
|
||||||
unsigned flags;
|
|
||||||
unsigned dev_info_len;
|
|
||||||
char dev_info[];
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct cuse_lowlevel_ops *req_clop(fuse_req_t req)
|
|
||||||
{
|
|
||||||
return &req->f->cuse_data->clop;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cuse_fll_open(fuse_req_t req, fuse_ino_t ino,
|
|
||||||
struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
(void)ino;
|
|
||||||
req_clop(req)->open(req, fi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cuse_fll_read(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
||||||
off_t off, struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
(void)ino;
|
|
||||||
req_clop(req)->read(req, size, off, fi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cuse_fll_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
|
|
||||||
size_t size, off_t off, struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
(void)ino;
|
|
||||||
req_clop(req)->write(req, buf, size, off, fi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cuse_fll_flush(fuse_req_t req, fuse_ino_t ino,
|
|
||||||
struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
(void)ino;
|
|
||||||
req_clop(req)->flush(req, fi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cuse_fll_release(fuse_req_t req, fuse_ino_t ino,
|
|
||||||
struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
(void)ino;
|
|
||||||
req_clop(req)->release(req, fi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cuse_fll_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
|
|
||||||
struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
(void)ino;
|
|
||||||
req_clop(req)->fsync(req, datasync, fi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cuse_fll_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
|
|
||||||
struct fuse_file_info *fi, unsigned int flags,
|
|
||||||
const void *in_buf, size_t in_bufsz, size_t out_bufsz)
|
|
||||||
{
|
|
||||||
(void)ino;
|
|
||||||
req_clop(req)->ioctl(req, cmd, arg, fi, flags, in_buf, in_bufsz,
|
|
||||||
out_bufsz);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cuse_fll_poll(fuse_req_t req, fuse_ino_t ino,
|
|
||||||
struct fuse_file_info *fi, struct fuse_pollhandle *ph)
|
|
||||||
{
|
|
||||||
(void)ino;
|
|
||||||
req_clop(req)->poll(req, fi, ph);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t cuse_pack_info(int argc, const char **argv, char *buf)
|
|
||||||
{
|
|
||||||
size_t size = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
len = strlen(argv[i]) + 1;
|
|
||||||
size += len;
|
|
||||||
if (buf) {
|
|
||||||
memcpy(buf, argv[i], len);
|
|
||||||
buf += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct cuse_data *cuse_prep_data(const struct cuse_info *ci,
|
|
||||||
const struct cuse_lowlevel_ops *clop)
|
|
||||||
{
|
|
||||||
struct cuse_data *cd;
|
|
||||||
size_t dev_info_len;
|
|
||||||
|
|
||||||
dev_info_len = cuse_pack_info(ci->dev_info_argc, ci->dev_info_argv,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (dev_info_len > CUSE_INIT_INFO_MAX) {
|
|
||||||
fprintf(stderr, "cuse: dev_info (%zu) too large, limit=%u\n",
|
|
||||||
dev_info_len, CUSE_INIT_INFO_MAX);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
cd = calloc(1, sizeof(*cd) + dev_info_len);
|
|
||||||
if (!cd) {
|
|
||||||
fprintf(stderr, "cuse: failed to allocate cuse_data\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&cd->clop, clop, sizeof(cd->clop));
|
|
||||||
cd->max_read = 131072;
|
|
||||||
cd->dev_major = ci->dev_major;
|
|
||||||
cd->dev_minor = ci->dev_minor;
|
|
||||||
cd->dev_info_len = dev_info_len;
|
|
||||||
cd->flags = ci->flags;
|
|
||||||
cuse_pack_info(ci->dev_info_argc, ci->dev_info_argv, cd->dev_info);
|
|
||||||
|
|
||||||
return cd;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fuse_session *cuse_lowlevel_new(struct fuse_args *args,
|
|
||||||
const struct cuse_info *ci,
|
|
||||||
const struct cuse_lowlevel_ops *clop,
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
struct fuse_lowlevel_ops lop;
|
|
||||||
struct cuse_data *cd;
|
|
||||||
struct fuse_session *se;
|
|
||||||
struct fuse_ll *ll;
|
|
||||||
|
|
||||||
cd = cuse_prep_data(ci, clop);
|
|
||||||
if (!cd)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
memset(&lop, 0, sizeof(lop));
|
|
||||||
lop.init = clop->init;
|
|
||||||
lop.destroy = clop->destroy;
|
|
||||||
lop.open = clop->open ? cuse_fll_open : NULL;
|
|
||||||
lop.read = clop->read ? cuse_fll_read : NULL;
|
|
||||||
lop.write = clop->write ? cuse_fll_write : NULL;
|
|
||||||
lop.flush = clop->flush ? cuse_fll_flush : NULL;
|
|
||||||
lop.release = clop->release ? cuse_fll_release : NULL;
|
|
||||||
lop.fsync = clop->fsync ? cuse_fll_fsync : NULL;
|
|
||||||
lop.ioctl = clop->ioctl ? cuse_fll_ioctl : NULL;
|
|
||||||
lop.poll = clop->poll ? cuse_fll_poll : NULL;
|
|
||||||
|
|
||||||
se = fuse_lowlevel_new_common(args, &lop, sizeof(lop), userdata);
|
|
||||||
if (!se) {
|
|
||||||
free(cd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ll = se->data;
|
|
||||||
ll->cuse_data = cd;
|
|
||||||
|
|
||||||
return se;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cuse_reply_init(fuse_req_t req, struct cuse_init_out *arg,
|
|
||||||
char *dev_info, unsigned dev_info_len)
|
|
||||||
{
|
|
||||||
struct iovec iov[3];
|
|
||||||
|
|
||||||
iov[1].iov_base = arg;
|
|
||||||
iov[1].iov_len = sizeof(struct cuse_init_out);
|
|
||||||
iov[2].iov_base = dev_info;
|
|
||||||
iov[2].iov_len = dev_info_len;
|
|
||||||
|
|
||||||
return fuse_send_reply_iov_nofree(req, 0, iov, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
|
|
||||||
{
|
|
||||||
struct fuse_init_in *arg = (struct fuse_init_in *) inarg;
|
|
||||||
struct cuse_init_out outarg;
|
|
||||||
struct fuse_ll *f = req->f;
|
|
||||||
struct cuse_data *cd = f->cuse_data;
|
|
||||||
size_t bufsize = fuse_chan_bufsize(req->ch);
|
|
||||||
struct cuse_lowlevel_ops *clop = req_clop(req);
|
|
||||||
|
|
||||||
(void) nodeid;
|
|
||||||
if (f->debug) {
|
|
||||||
fprintf(stderr, "CUSE_INIT: %u.%u\n", arg->major, arg->minor);
|
|
||||||
fprintf(stderr, "flags=0x%08x\n", arg->flags);
|
|
||||||
}
|
|
||||||
f->conn.proto_major = arg->major;
|
|
||||||
f->conn.proto_minor = arg->minor;
|
|
||||||
f->conn.capable = 0;
|
|
||||||
f->conn.want = 0;
|
|
||||||
|
|
||||||
if (arg->major < 7) {
|
|
||||||
fprintf(stderr, "cuse: unsupported protocol version: %u.%u\n",
|
|
||||||
arg->major, arg->minor);
|
|
||||||
fuse_reply_err(req, EPROTO);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bufsize < FUSE_MIN_READ_BUFFER) {
|
|
||||||
fprintf(stderr, "cuse: warning: buffer size too small: %zu\n",
|
|
||||||
bufsize);
|
|
||||||
bufsize = FUSE_MIN_READ_BUFFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
bufsize -= 4096;
|
|
||||||
if (bufsize < f->conn.max_write)
|
|
||||||
f->conn.max_write = bufsize;
|
|
||||||
|
|
||||||
f->got_init = 1;
|
|
||||||
if (f->op.init)
|
|
||||||
f->op.init(f->userdata, &f->conn);
|
|
||||||
|
|
||||||
memset(&outarg, 0, sizeof(outarg));
|
|
||||||
outarg.major = FUSE_KERNEL_VERSION;
|
|
||||||
outarg.minor = FUSE_KERNEL_MINOR_VERSION;
|
|
||||||
outarg.flags = cd->flags;
|
|
||||||
outarg.max_read = cd->max_read;
|
|
||||||
outarg.max_write = f->conn.max_write;
|
|
||||||
outarg.dev_major = cd->dev_major;
|
|
||||||
outarg.dev_minor = cd->dev_minor;
|
|
||||||
|
|
||||||
if (f->debug) {
|
|
||||||
fprintf(stderr, " CUSE_INIT: %u.%u\n",
|
|
||||||
outarg.major, outarg.minor);
|
|
||||||
fprintf(stderr, " flags=0x%08x\n", outarg.flags);
|
|
||||||
fprintf(stderr, " max_read=0x%08x\n", outarg.max_read);
|
|
||||||
fprintf(stderr, " max_write=0x%08x\n", outarg.max_write);
|
|
||||||
fprintf(stderr, " dev_major=%u\n", outarg.dev_major);
|
|
||||||
fprintf(stderr, " dev_minor=%u\n", outarg.dev_minor);
|
|
||||||
fprintf(stderr, " dev_info: %.*s\n", cd->dev_info_len,
|
|
||||||
cd->dev_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
cuse_reply_init(req, &outarg, cd->dev_info, cd->dev_info_len);
|
|
||||||
|
|
||||||
if (clop->init_done)
|
|
||||||
clop->init_done(f->userdata);
|
|
||||||
|
|
||||||
fuse_free_req(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fuse_session *cuse_lowlevel_setup(int argc, char *argv[],
|
|
||||||
const struct cuse_info *ci,
|
|
||||||
const struct cuse_lowlevel_ops *clop,
|
|
||||||
int *multithreaded, void *userdata)
|
|
||||||
{
|
|
||||||
const char *devname = "/dev/cuse";
|
|
||||||
static const struct fuse_opt kill_subtype_opts[] = {
|
|
||||||
FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_DISCARD),
|
|
||||||
FUSE_OPT_END
|
|
||||||
};
|
|
||||||
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
|
|
||||||
struct fuse_session *se;
|
|
||||||
struct fuse_chan *ch;
|
|
||||||
int fd;
|
|
||||||
int foreground;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
res = fuse_parse_cmdline(&args, NULL, multithreaded, &foreground);
|
|
||||||
if (res == -1)
|
|
||||||
goto err_args;
|
|
||||||
|
|
||||||
res = fuse_opt_parse(&args, NULL, kill_subtype_opts, NULL);
|
|
||||||
if (res == -1)
|
|
||||||
goto err_args;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
|
|
||||||
* would ensue.
|
|
||||||
*/
|
|
||||||
do {
|
|
||||||
fd = open("/dev/null", O_RDWR);
|
|
||||||
if (fd > 2)
|
|
||||||
close(fd);
|
|
||||||
} while (fd >= 0 && fd <= 2);
|
|
||||||
|
|
||||||
se = cuse_lowlevel_new(&args, ci, clop, userdata);
|
|
||||||
fuse_opt_free_args(&args);
|
|
||||||
if (se == NULL)
|
|
||||||
goto err_args;
|
|
||||||
|
|
||||||
fd = open(devname, O_RDWR);
|
|
||||||
if (fd == -1) {
|
|
||||||
if (errno == ENODEV || errno == ENOENT)
|
|
||||||
fprintf(stderr, "cuse: device not found, try 'modprobe cuse' first\n");
|
|
||||||
else
|
|
||||||
fprintf(stderr, "cuse: failed to open %s: %s\n",
|
|
||||||
devname, strerror(errno));
|
|
||||||
goto err_se;
|
|
||||||
}
|
|
||||||
|
|
||||||
ch = fuse_kern_chan_new(fd);
|
|
||||||
if (!ch) {
|
|
||||||
close(fd);
|
|
||||||
goto err_se;
|
|
||||||
}
|
|
||||||
|
|
||||||
fuse_session_add_chan(se, ch);
|
|
||||||
|
|
||||||
res = fuse_set_signal_handlers(se);
|
|
||||||
if (res == -1)
|
|
||||||
goto err_se;
|
|
||||||
|
|
||||||
res = fuse_daemonize(foreground);
|
|
||||||
if (res == -1)
|
|
||||||
goto err_sig;
|
|
||||||
|
|
||||||
return se;
|
|
||||||
|
|
||||||
err_sig:
|
|
||||||
fuse_remove_signal_handlers(se);
|
|
||||||
err_se:
|
|
||||||
fuse_session_destroy(se);
|
|
||||||
err_args:
|
|
||||||
fuse_opt_free_args(&args);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cuse_lowlevel_teardown(struct fuse_session *se)
|
|
||||||
{
|
|
||||||
fuse_remove_signal_handlers(se);
|
|
||||||
fuse_session_destroy(se);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cuse_lowlevel_main(int argc, char *argv[], const struct cuse_info *ci,
|
|
||||||
const struct cuse_lowlevel_ops *clop, void *userdata)
|
|
||||||
{
|
|
||||||
struct fuse_session *se;
|
|
||||||
int multithreaded;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
se = cuse_lowlevel_setup(argc, argv, ci, clop, &multithreaded,
|
|
||||||
userdata);
|
|
||||||
if (se == NULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (multithreaded)
|
|
||||||
res = fuse_session_loop_mt(se, 0);
|
|
||||||
else
|
|
||||||
res = fuse_session_loop(se);
|
|
||||||
|
|
||||||
cuse_lowlevel_teardown(se);
|
|
||||||
if (res == -1)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -76,7 +76,6 @@ struct fuse_ll
|
||||||
int no_splice_read;
|
int no_splice_read;
|
||||||
struct fuse_lowlevel_ops op;
|
struct fuse_lowlevel_ops op;
|
||||||
int got_init;
|
int got_init;
|
||||||
struct cuse_data *cuse_data;
|
|
||||||
void *userdata;
|
void *userdata;
|
||||||
uid_t owner;
|
uid_t owner;
|
||||||
struct fuse_conn_info conn;
|
struct fuse_conn_info conn;
|
||||||
|
@ -129,6 +128,4 @@ struct fuse *fuse_setup_common(int argc, char *argv[],
|
||||||
void *user_data,
|
void *user_data,
|
||||||
int compat);
|
int compat);
|
||||||
|
|
||||||
void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeide, const void *inarg);
|
|
||||||
|
|
||||||
int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg);
|
int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg);
|
||||||
|
|
|
@ -2377,7 +2377,6 @@ static struct {
|
||||||
[FUSE_NOTIFY_REPLY] = { (void *) 1, "NOTIFY_REPLY" },
|
[FUSE_NOTIFY_REPLY] = { (void *) 1, "NOTIFY_REPLY" },
|
||||||
[FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
|
[FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
|
||||||
[FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" },
|
[FUSE_COPY_FILE_RANGE] = { do_copy_file_range, "COPY_FILE_RANGE" },
|
||||||
[CUSE_INIT] = { cuse_lowlevel_init, "CUSE_INIT" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
|
#define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
|
||||||
|
@ -2470,13 +2469,15 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
|
||||||
req->ch = ch;
|
req->ch = ch;
|
||||||
|
|
||||||
err = EIO;
|
err = EIO;
|
||||||
if (!f->got_init) {
|
if(!f->got_init)
|
||||||
|
{
|
||||||
enum fuse_opcode expected;
|
enum fuse_opcode expected;
|
||||||
|
|
||||||
expected = f->cuse_data ? CUSE_INIT : FUSE_INIT;
|
expected = FUSE_INIT;
|
||||||
if (in->opcode != expected)
|
if (in->opcode != expected)
|
||||||
goto reply_err;
|
goto reply_err;
|
||||||
} else if (in->opcode == FUSE_INIT || in->opcode == CUSE_INIT)
|
}
|
||||||
|
else if(in->opcode == FUSE_INIT)
|
||||||
goto reply_err;
|
goto reply_err;
|
||||||
|
|
||||||
err = EACCES;
|
err = EACCES;
|
||||||
|
@ -2653,7 +2654,6 @@ static void fuse_ll_destroy(void *data)
|
||||||
fuse_ll_pipe_free(llp);
|
fuse_ll_pipe_free(llp);
|
||||||
pthread_key_delete(f->pipe_key);
|
pthread_key_delete(f->pipe_key);
|
||||||
pthread_mutex_destroy(&f->lock);
|
pthread_mutex_destroy(&f->lock);
|
||||||
free(f->cuse_data);
|
|
||||||
free(f);
|
free(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2857,75 +2857,6 @@ struct fuse_session *fuse_lowlevel_new(struct fuse_args *args,
|
||||||
return fuse_lowlevel_new_common(args, op, op_size, userdata);
|
return fuse_lowlevel_new_common(args, op, op_size, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef linux
|
|
||||||
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
|
|
||||||
{
|
|
||||||
char *buf;
|
|
||||||
size_t bufsize = 1024;
|
|
||||||
char path[128];
|
|
||||||
int ret;
|
|
||||||
int fd;
|
|
||||||
unsigned long pid = req->ctx.pid;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
sprintf(path, "/proc/%lu/task/%lu/status", pid, pid);
|
|
||||||
|
|
||||||
retry:
|
|
||||||
buf = malloc(bufsize);
|
|
||||||
if (buf == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
ret = -EIO;
|
|
||||||
fd = open(path, O_RDONLY);
|
|
||||||
if (fd == -1)
|
|
||||||
goto out_free;
|
|
||||||
|
|
||||||
ret = read(fd, buf, bufsize);
|
|
||||||
close(fd);
|
|
||||||
if (ret == -1) {
|
|
||||||
ret = -EIO;
|
|
||||||
goto out_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == bufsize) {
|
|
||||||
free(buf);
|
|
||||||
bufsize *= 4;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = -EIO;
|
|
||||||
s = strstr(buf, "\nGroups:");
|
|
||||||
if (s == NULL)
|
|
||||||
goto out_free;
|
|
||||||
|
|
||||||
s += 8;
|
|
||||||
ret = 0;
|
|
||||||
while (1) {
|
|
||||||
char *end;
|
|
||||||
unsigned long val = strtoul(s, &end, 0);
|
|
||||||
if (end == s)
|
|
||||||
break;
|
|
||||||
|
|
||||||
s = end;
|
|
||||||
if (ret < size)
|
|
||||||
list[ret] = val;
|
|
||||||
ret++;
|
|
||||||
}
|
|
||||||
|
|
||||||
out_free:
|
|
||||||
free(buf);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else /* linux */
|
|
||||||
/*
|
|
||||||
* This is currently not implemented on other than Linux...
|
|
||||||
*/
|
|
||||||
int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[])
|
|
||||||
{
|
|
||||||
return -ENOSYS;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__FreeBSD__) && !defined(__NetBSD__)
|
#if !defined(__FreeBSD__) && !defined(__NetBSD__)
|
||||||
|
|
||||||
static void fill_open_compat(struct fuse_open_out *arg,
|
static void fill_open_compat(struct fuse_open_out *arg,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user