Refactor a few interfaces a bit to look more like fuse. fuse_args
is implemented as a very dummy version (i.e. totally unimplemented), so some effort is still needed there. After this change it is possible to compile and run ntfs-3g. It works read/write for ntfs images and shows no faults at least with superficial testing. I did not test it against a block device, only an image. Thanks to Tracy and Jason for help with the test image.
This commit is contained in:
parent
34d41b6ccb
commit
03c5e15dc2
|
@ -38,6 +38,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct fuse;
|
struct fuse;
|
||||||
|
struct fuse_args; /* XXXsupportme */
|
||||||
|
|
||||||
struct fuse_file_info {
|
struct fuse_file_info {
|
||||||
int32_t flags;
|
int32_t flags;
|
||||||
|
@ -165,15 +166,28 @@ typedef int (*fuse_opt_proc_t)(void *, const char *, int, struct fuse_args *);
|
||||||
int fuse_opt_add_arg(struct fuse_args *, const char *);
|
int fuse_opt_add_arg(struct fuse_args *, const char *);
|
||||||
void fuse_opt_free_args(struct fuse_args *);
|
void fuse_opt_free_args(struct fuse_args *);
|
||||||
int fuse_opt_parse(struct fuse_args *, void *, const struct fuse_opt *, fuse_opt_proc_t);
|
int fuse_opt_parse(struct fuse_args *, void *, const struct fuse_opt *, fuse_opt_proc_t);
|
||||||
|
|
||||||
|
struct fuse_chan *fuse_mount(const char *, struct fuse_args *);
|
||||||
|
struct fuse *fuse_new(struct fuse_chan *, struct fuse_args *,
|
||||||
|
const struct fuse_operations *, size_t, void *);
|
||||||
|
|
||||||
int fuse_main_real(int, char **, const struct fuse_operations *, size_t, void *);
|
int fuse_main_real(int, char **, const struct fuse_operations *, size_t, void *);
|
||||||
|
int fuse_loop(struct fuse *);
|
||||||
struct fuse_context *fuse_get_context(void);
|
struct fuse_context *fuse_get_context(void);
|
||||||
void fuse_exit(struct fuse *);
|
void fuse_exit(struct fuse *);
|
||||||
void fuse_unmount(const char *);
|
void fuse_destroy(struct fuse *);
|
||||||
|
|
||||||
|
void fuse_unmount(const char *, struct fuse_chan *);
|
||||||
|
|
||||||
|
#if FUSE_USE_VERSION == 22
|
||||||
|
#define fuse_unmount fuse_unmount_compat22
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void fuse_unmount_compat22(const char *);
|
||||||
|
|
||||||
#define fuse_main(argc, argv, op) \
|
#define fuse_main(argc, argv, op) \
|
||||||
fuse_main_real(argc, argv, op, sizeof(*(op)), NULL)
|
fuse_main_real(argc, argv, op, sizeof(*(op)), NULL)
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: refuse.c,v 1.37 2007/02/26 15:09:19 pooka Exp $ */
|
/* $NetBSD: refuse.c,v 1.38 2007/02/26 15:57:33 pooka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright © 2007 Alistair Crooks. All rights reserved.
|
* Copyright © 2007 Alistair Crooks. All rights reserved.
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#if !defined(lint)
|
#if !defined(lint)
|
||||||
__RCSID("$NetBSD: refuse.c,v 1.37 2007/02/26 15:09:19 pooka Exp $");
|
__RCSID("$NetBSD: refuse.c,v 1.38 2007/02/26 15:57:33 pooka Exp $");
|
||||||
#endif /* !lint */
|
#endif /* !lint */
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -66,9 +66,16 @@ struct fuse_config {
|
||||||
int intr_signal;
|
int intr_signal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fuse_chan {
|
||||||
|
const char *dir;
|
||||||
|
struct fuse_args *args;
|
||||||
|
|
||||||
|
struct puffs_usermount *pu;
|
||||||
|
};
|
||||||
|
|
||||||
/* this is the private fuse structure */
|
/* this is the private fuse structure */
|
||||||
struct fuse {
|
struct fuse {
|
||||||
struct fuse_session *se; /* fuse session pointer */
|
struct fuse_chan *fc; /* fuse channel pointer */
|
||||||
struct fuse_operations op; /* switch table of operations */
|
struct fuse_operations op; /* switch table of operations */
|
||||||
int compat; /* compat level -
|
int compat; /* compat level -
|
||||||
* not used in puffs_fuse */
|
* not used in puffs_fuse */
|
||||||
|
@ -84,7 +91,6 @@ struct fuse {
|
||||||
void *user_data;
|
void *user_data;
|
||||||
struct fuse_config conf;
|
struct fuse_config conf;
|
||||||
int intr_installed;
|
int intr_installed;
|
||||||
struct puffs_usermount *pu;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct puffs_fuse_dirh {
|
struct puffs_fuse_dirh {
|
||||||
|
@ -113,11 +119,7 @@ newrn(struct puffs_usermount *pu)
|
||||||
struct puffs_node *pn;
|
struct puffs_node *pn;
|
||||||
struct refusenode *rn;
|
struct refusenode *rn;
|
||||||
|
|
||||||
rn = malloc(sizeof(struct refusenode));
|
NEW(struct refusenode, rn, "newrn", exit(EXIT_FAILURE));
|
||||||
if (!rn)
|
|
||||||
abort(); /*XXX*/
|
|
||||||
|
|
||||||
memset(rn, 0, sizeof(struct refusenode));
|
|
||||||
pn = puffs_pn_new(pu, rn);
|
pn = puffs_pn_new(pu, rn);
|
||||||
|
|
||||||
return pn;
|
return pn;
|
||||||
|
@ -993,6 +995,65 @@ puffs_fuse_fs_statvfs(struct puffs_cc *pcc, struct statvfs *svfsb, pid_t pid)
|
||||||
int
|
int
|
||||||
fuse_main_real(int argc, char **argv, const struct fuse_operations *ops,
|
fuse_main_real(int argc, char **argv, const struct fuse_operations *ops,
|
||||||
size_t size, void *userdata)
|
size_t size, void *userdata)
|
||||||
|
{
|
||||||
|
struct fuse *fuse;
|
||||||
|
struct fuse_chan *fc;
|
||||||
|
char name[64];
|
||||||
|
char *slash;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* whilst this (assigning the pu_privdata in the puffs
|
||||||
|
* usermount struct to be the fuse struct) might seem like
|
||||||
|
* we are chasing our tail here, the logic is as follows:
|
||||||
|
+ the operation wrapper gets called with the puffs
|
||||||
|
calling conventions
|
||||||
|
+ we need to fix up args first
|
||||||
|
+ then call the fuse user-supplied operation
|
||||||
|
+ then we fix up any values on return that we need to
|
||||||
|
+ and fix up any nodes, etc
|
||||||
|
* so we need to be able to get at the fuse ops from within the
|
||||||
|
* puffs_usermount struct
|
||||||
|
*/
|
||||||
|
if ((slash = strrchr(*argv, '/')) == NULL) {
|
||||||
|
slash = *argv;
|
||||||
|
} else {
|
||||||
|
slash += 1;
|
||||||
|
}
|
||||||
|
(void) snprintf(name, sizeof(name), "refuse:%s", slash);
|
||||||
|
|
||||||
|
/* XXX: stuff name into fuse_args */
|
||||||
|
|
||||||
|
fc = fuse_mount(argv[argc - 1], NULL);
|
||||||
|
fuse = fuse_new(fc, NULL, ops, size, userdata);
|
||||||
|
|
||||||
|
ret = fuse_loop(fuse);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: just defer the operation until fuse_new() when we have more
|
||||||
|
* info on our hands. The real beef is why's this separate in fuse in
|
||||||
|
* the first place?
|
||||||
|
*/
|
||||||
|
/* ARGSUSED1 */
|
||||||
|
struct fuse_chan *
|
||||||
|
fuse_mount(const char *dir, struct fuse_args *args)
|
||||||
|
{
|
||||||
|
struct fuse_chan *fc;
|
||||||
|
|
||||||
|
NEW(struct fuse_chan, fc, "fuse_mount", exit(EXIT_FAILURE));
|
||||||
|
|
||||||
|
fc->dir = strdup(dir);
|
||||||
|
fc->args = args; /* XXXX: do we need to deep copy? */
|
||||||
|
|
||||||
|
return fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED1 */
|
||||||
|
struct fuse *
|
||||||
|
fuse_new(struct fuse_chan *fc, struct fuse_args *args,
|
||||||
|
const struct fuse_operations *ops, size_t size, void *userdata)
|
||||||
{
|
{
|
||||||
struct puffs_usermount *pu;
|
struct puffs_usermount *pu;
|
||||||
struct puffs_pathobj *po_root;
|
struct puffs_pathobj *po_root;
|
||||||
|
@ -1001,9 +1062,16 @@ fuse_main_real(int argc, char **argv, const struct fuse_operations *ops,
|
||||||
struct statvfs svfsb;
|
struct statvfs svfsb;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct fuse *fuse;
|
struct fuse *fuse;
|
||||||
char name[64];
|
|
||||||
char *slash;
|
NEW(struct fuse, fuse, "fuse_new", exit(EXIT_FAILURE));
|
||||||
int ret;
|
|
||||||
|
/* copy fuse ops to their own stucture */
|
||||||
|
(void) memcpy(&fuse->op, ops, sizeof(fuse->op));
|
||||||
|
|
||||||
|
fcon.fuse = fuse;
|
||||||
|
fcon.private_data = userdata;
|
||||||
|
|
||||||
|
fuse->fc = fc;
|
||||||
|
|
||||||
/* initialise the puffs operations structure */
|
/* initialise the puffs operations structure */
|
||||||
PUFFSOP_INIT(pops);
|
PUFFSOP_INIT(pops);
|
||||||
|
@ -1035,43 +1103,18 @@ fuse_main_real(int argc, char **argv, const struct fuse_operations *ops,
|
||||||
PUFFSOP_SET(pops, puffs_fuse, node, write);
|
PUFFSOP_SET(pops, puffs_fuse, node, write);
|
||||||
PUFFSOP_SET(pops, puffs_fuse, node, reclaim);
|
PUFFSOP_SET(pops, puffs_fuse, node, reclaim);
|
||||||
|
|
||||||
NEW(struct fuse, fuse, "fuse_main_real", exit(EXIT_FAILURE));
|
pu = puffs_mount(pops, fc->dir, MNT_NODEV | MNT_NOSUID,
|
||||||
|
"fiXXXme", NULL,
|
||||||
/* copy fuse ops to their own stucture */
|
PUFFS_FLAG_BUILDPATH
|
||||||
(void) memcpy(&fuse->op, ops, sizeof(fuse->op));
|
| PUFFS_FLAG_OPDUMP
|
||||||
|
| PUFFS_KFLAG_NOCACHE,
|
||||||
fcon.fuse = fuse;
|
0);
|
||||||
fcon.private_data = userdata;
|
|
||||||
|
|
||||||
/* whilst this (assigning the pu_privdata in the puffs
|
|
||||||
* usermount struct to be the fuse struct) might seem like
|
|
||||||
* we are chasing our tail here, the logic is as follows:
|
|
||||||
+ the operation wrapper gets called with the puffs
|
|
||||||
calling conventions
|
|
||||||
+ we need to fix up args first
|
|
||||||
+ then call the fuse user-supplied operation
|
|
||||||
+ then we fix up any values on return that we need to
|
|
||||||
+ and fix up any nodes, etc
|
|
||||||
* so we need to be able to get at the fuse ops from within the
|
|
||||||
* puffs_usermount struct
|
|
||||||
*/
|
|
||||||
if ((slash = strrchr(*argv, '/')) == NULL) {
|
|
||||||
slash = *argv;
|
|
||||||
} else {
|
|
||||||
slash += 1;
|
|
||||||
}
|
|
||||||
(void) snprintf(name, sizeof(name), "refuse:%s", slash);
|
|
||||||
pu = puffs_mount(pops, argv[argc - 1], MNT_NODEV | MNT_NOSUID,
|
|
||||||
name, fuse,
|
|
||||||
PUFFS_FLAG_BUILDPATH
|
|
||||||
| PUFFS_FLAG_OPDUMP
|
|
||||||
| PUFFS_KFLAG_NOCACHE,
|
|
||||||
0);
|
|
||||||
if (pu == NULL) {
|
if (pu == NULL) {
|
||||||
err(EXIT_FAILURE, "puffs_mount");
|
err(EXIT_FAILURE, "puffs_mount");
|
||||||
}
|
}
|
||||||
|
fc->pu = pu;
|
||||||
|
pu->pu_privdata = fuse;
|
||||||
|
|
||||||
fuse->pu = pu;
|
|
||||||
pu->pu_pn_root = newrn(pu);
|
pu->pu_pn_root = newrn(pu);
|
||||||
rn_root = pu->pu_pn_root->pn_data;
|
rn_root = pu->pu_pn_root->pn_data;
|
||||||
rn_root->flags |= RN_ROOT;
|
rn_root->flags |= RN_ROOT;
|
||||||
|
@ -1092,16 +1135,28 @@ fuse_main_real(int argc, char **argv, const struct fuse_operations *ops,
|
||||||
if (fuse->op.init)
|
if (fuse->op.init)
|
||||||
fcon.private_data = fuse->op.init(NULL); /* XXX */
|
fcon.private_data = fuse->op.init(NULL); /* XXX */
|
||||||
|
|
||||||
statvfs(argv[argc - 1], &svfsb); /* XXX - not really the correct dir */
|
puffs_zerostatvfs(&svfsb);
|
||||||
if (puffs_start(pu, pu->pu_pn_root, &svfsb) == -1) {
|
if (puffs_start(pu, pu->pu_pn_root, &svfsb) == -1) {
|
||||||
err(EXIT_FAILURE, "puffs_start");
|
err(EXIT_FAILURE, "puffs_start");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = puffs_mainloop(fuse->pu, PUFFSLOOP_NODAEMON);
|
return fuse;
|
||||||
|
}
|
||||||
|
|
||||||
(void) free(po_root->po_path);
|
int
|
||||||
|
fuse_loop(struct fuse *fuse)
|
||||||
|
{
|
||||||
|
|
||||||
|
return puffs_mainloop(fuse->fc->pu, PUFFSLOOP_NODAEMON);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fuse_destroy(struct fuse *fuse)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/* XXXXXX: missing stuff */
|
||||||
FREE(fuse);
|
FREE(fuse);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED0 */
|
/* ARGSUSED0 */
|
||||||
|
@ -1121,10 +1176,10 @@ fuse_get_context()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fuse_exit(struct fuse *f)
|
fuse_exit(struct fuse *fuse)
|
||||||
{
|
{
|
||||||
|
|
||||||
puffs_exit(f->pu, 1);
|
puffs_exit(fuse->fc->pu, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1133,7 +1188,15 @@ fuse_exit(struct fuse *f)
|
||||||
*/
|
*/
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
void
|
void
|
||||||
fuse_unmount(const char *mp)
|
fuse_unmount(const char *mp, struct fuse_chan *fc)
|
||||||
|
{
|
||||||
|
|
||||||
|
puffs_exit(fc->pu, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
void
|
||||||
|
fuse_unmount_compat22(const char *mp)
|
||||||
{
|
{
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue