diff options
author | Stefan Siegl <stesie@brokenpipe.de> | 2006-08-04 12:16:12 +0000 |
---|---|---|
committer | Stefan Siegl <stesie@brokenpipe.de> | 2006-08-04 12:16:12 +0000 |
commit | 3f8581c976ced07cb78b29f2c44531a38d6c7f6c (patch) | |
tree | 127fe0856bc26005bc6b73e4cd950bf5eba266d5 | |
parent | 2c6df679a905af1e2ac627138078a7069ada5c76 (diff) |
added support for libfuse 2.5 api
-rw-r--r-- | src/fuse_i.h | 37 | ||||
-rw-r--r-- | src/main.c | 50 | ||||
-rw-r--r-- | src/netfs.c | 203 |
3 files changed, 212 insertions, 78 deletions
diff --git a/src/fuse_i.h b/src/fuse_i.h index 16589129b..7694951f0 100644 --- a/src/fuse_i.h +++ b/src/fuse_i.h @@ -32,13 +32,37 @@ /* pointer to the fuse_operations structure of this translator process */ extern const struct fuse_operations_compat22 *fuse_ops_compat22; extern const struct fuse_operations_compat2 *fuse_ops_compat2; - -#define FUSE_OP_HAVE(a) ((fuse_ops_compat22) ? \ - (fuse_ops_compat22->a != NULL) : \ - (fuse_ops_compat2->a != NULL)) -#define FUSE_OP_CALL(a,b...) ((fuse_ops_compat22) ? \ +extern const struct fuse_operations *fuse_ops25; + +#define FUSE_OP_HAVE(a) (fuse_ops25 ? \ + (fuse_ops25->a != NULL) \ + : ((fuse_ops_compat22) ? \ + (fuse_ops_compat22->a != NULL) : \ + (fuse_ops_compat2->a != NULL))) +#define FUSE_OP_CALL(a,b...) (fuse_ops25 ? \ + (fuse_ops25->a(b)) : \ + ((fuse_ops_compat22) ? \ (fuse_ops_compat22->a(b)) : \ - (fuse_ops_compat2->a(b))) + (fuse_ops_compat2->a(b)))) + +#define FUSE_OP_HAVE22(a) (fuse_ops25 ? \ + (fuse_ops25->a != NULL) \ + : ((fuse_ops_compat22) ? \ + (fuse_ops_compat22->a != NULL) : 0)) + +#define FUSE_OP_CALL22(a,b...) (fuse_ops25 ? \ + (fuse_ops25->a(b)) : \ + ((fuse_ops_compat22) ? \ + (fuse_ops_compat22->a(b)) : (0))) + +#define NN_INFO(dir) (fuse_ops25 ? \ + ((void *) &(dir)->nn->info.info25) \ + : ((void *) &(dir)->nn->info.compat22)) + +#define NN_INFO_APPLY(node,key) do { \ + if(fuse_ops25) (node)->nn->info.info25.key; \ + else (node)->nn->info.compat22.key; \ + } while(0) /***************************************************************************** *** netnodes (in memory representation of libfuse's files or directories) *** @@ -57,6 +81,7 @@ struct netnode { */ union { struct fuse_file_info_compat22 compat22; + struct fuse_file_info info25; } info; /* pointer to our parent's netnode, if any */ diff --git a/src/main.c b/src/main.c index bdaade9c4..996dfdd4b 100644 --- a/src/main.c +++ b/src/main.c @@ -35,6 +35,7 @@ struct _libfuse_params libfuse_params = { 0 }; /* pointer to the fuse_operations structure of this translator process */ const struct fuse_operations_compat22 *fuse_ops_compat22 = NULL; const struct fuse_operations_compat2 *fuse_ops_compat2 = NULL; +const struct fuse_operations *fuse_ops25 = NULL; /* the port where to write out debug messages to, NULL to omit these */ FILE *debug_port = NULL; @@ -42,6 +43,9 @@ FILE *debug_port = NULL; /* the private data pointer returned from init() callback */ void *fsys_privdata = NULL; +/* bootstrap fuse translator */ +static int fuse_bootstrap(const char *mountpoint); + /* Interpret a __single__ mount option * The option itself `opt' may be modified during this call. @@ -271,7 +275,11 @@ int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, size_t op_size) { - assert(0); + fuse_parse_argv(argc, argv); + + int fd = fuse_mount(argv[0], NULL); + return (libfuse_params.disable_mt ? fuse_loop : fuse_loop_mt) + (fuse_new(fd, NULL, op, op_size)); } @@ -304,7 +312,26 @@ struct fuse * fuse_new(int fd, struct fuse_args *args, const struct fuse_operations *op, size_t op_size) { - assert(0); + (void) op_size; /* FIXME, see what the real Fuse library does with + * this argument */ + + if(fd != FUSE_MAGIC) + return NULL; + + if(args && args->allocated) + { + int i; + for(i = 0; i < args->argc; i ++) + if(fuse_parse_opt(args->argv[i])) + return NULL; + } + + fuse_ops25 = op; + + if(op->init) + fsys_privdata = op->init(); + + return (void *) FUSE_MAGIC; /* we don't have a fuse structure, sorry. */ } @@ -339,7 +366,15 @@ fuse_new_compat22(int fd, const char *opts, int fuse_mount(const char *mountpoint, struct fuse_args *args) { - assert(0); + if(args && args->allocated) + { + int i; + for(i = 0; i < args->argc; i ++) + if(fuse_parse_opt(args->argv[i])) + return 0; + } + + return fuse_bootstrap(mountpoint); } @@ -349,6 +384,12 @@ fuse_mount_compat22(const char *mountpoint, const char *opts) if(fuse_parse_opts(opts)) return 0; + return fuse_bootstrap(mountpoint); +} + +static int +fuse_bootstrap(const char *mountpoint) +{ mach_port_t bootstrap, ul_node; task_get_bootstrap_port(mach_task_self(), &bootstrap); @@ -519,6 +560,7 @@ fuse_loop_mt(struct fuse *f) void fuse_exit(struct fuse *f) { + (void) f; /* * well, we should make fuse_main exit, this is, we would have to * cancel ports_manage_port_operations_one_thread. however this is @@ -531,6 +573,8 @@ fuse_exit(struct fuse *f) int fuse_exited(struct fuse *f) { + (void) f; + /* * if fuse_exit is called, we buy the farm, therefore we still must be alive. */ diff --git a/src/netfs.c b/src/netfs.c index 083ebe534..4815027e4 100644 --- a/src/netfs.c +++ b/src/netfs.c @@ -314,7 +314,34 @@ netfs_attempt_statfs (struct iouser *cred, struct node *node, else if(FUSE_OP_HAVE(statfs)) { refresh_context_struct(cred); - err = -FUSE_OP_CALL(statfs, node->nn->path, st); + + if(fuse_ops25) + { + struct statvfs stvfs; + err = -fuse_ops25->statfs(node->nn->path, &stvfs); + + st->f_type = stvfs.__f_type; + st->f_bsize = stvfs.f_bsize; + st->f_blocks = stvfs.f_blocks; + st->f_bfree = stvfs.f_bfree; + st->f_bavail = stvfs.f_bavail; + st->f_files = stvfs.f_files; + st->f_ffree = stvfs.f_ffree; + st->f_fsid = stvfs.f_fsid; + st->f_namelen = stvfs.f_namemax; + st->f_favail = stvfs.f_favail; + st->f_frsize = stvfs.f_frsize; + st->f_flag = stvfs.f_flag; + } + + else if(fuse_ops_compat22) + err = -fuse_ops_compat22->statfs(node->nn->path, st); + + else if(fuse_ops_compat2) + err = -fuse_ops_compat2->statfs(node->nn->path, st); + + else + assert(0); } else @@ -417,8 +444,8 @@ netfs_check_open_permissions (struct iouser *user, struct node *node, * into memory. */ if(! err) { - node->nn->info.compat22.flags = flags; - if(flags & O_EXEC) node->nn->info.compat22.flags |= O_RDONLY; + NN_INFO_APPLY(node, flags = flags); + if(flags & O_EXEC) NN_INFO_APPLY(node, flags |= O_RDONLY); } out: @@ -560,12 +587,15 @@ netfs_attempt_sync (struct iouser *cred, struct node *node, int wait) err = EOPNOTSUPP; goto out; } + + if(FUSE_OP_HAVE22(fsync)) + err = -FUSE_OP_CALL22(fsync, node->nn->path, 0, NN_INFO(node)); - if(fuse_ops_compat22) - err = -fuse_ops_compat22->fsync(node->nn->path, 0, - &node->nn->info.compat22); - else + else if(fuse_ops_compat2) err = -fuse_ops_compat2->fsync(node->nn->path, 0); + + else + assert(0); if(! err) node->nn->may_need_sync = 0; @@ -1061,21 +1091,33 @@ error_t netfs_attempt_write (struct iouser *cred, struct node *node, goto out; } - node->nn->info.compat22.writepage = 0; /* cannot distinct on the Hurd :( */ + NN_INFO_APPLY(node, writepage = 0); /* cannot distinct on the Hurd :( */ - if(fuse_ops_compat2 && fuse_ops_compat2->open - && (err = fuse_ops_compat2->open(node->nn->path, - node->nn->info.compat22.flags))) - goto out; - else if(fuse_ops_compat22 && fuse_ops_compat22->open - && (err = fuse_ops_compat22->open(node->nn->path, - &node->nn->info.compat22))) - goto out; + if(FUSE_OP_HAVE(open)) + { + if(FUSE_OP_HAVE22(open)) + err = FUSE_OP_CALL22(open, node->nn->path, NN_INFO(node)); + + else if(fuse_ops_compat2) + err = fuse_ops_compat2->open(node->nn->path, + node->nn->info.compat22.flags); + + else + assert(0); + + if(err) goto out; + } + + int sz; + if(FUSE_OP_HAVE22(write)) + sz = FUSE_OP_CALL22(write, node->nn->path, data, *len, offset, + NN_INFO(node)); + + else if(fuse_ops_compat2) + sz = fuse_ops_compat2->write(node->nn->path, data, *len, offset); - int sz = fuse_ops_compat22 ? - (fuse_ops_compat22->write(node->nn->path, data, *len, - offset, &node->nn->info.compat22)) : - (fuse_ops_compat2->write(node->nn->path, data, *len, offset)); + else + assert(0); /* FIXME: open, flush and release handling probably should be changed * completely, I mean, we probably should do fuse_ops->open in @@ -1084,15 +1126,21 @@ error_t netfs_attempt_write (struct iouser *cred, struct node *node, * * This way we wouldn't be able to report any errors back. */ - if(sz >= 0 && fuse_ops_compat22 && fuse_ops_compat22->flush) - err = fuse_ops_compat22->flush(node->nn->path, &node->nn->info.compat22); + if(sz >= 0 && FUSE_OP_HAVE22(flush)) + err = FUSE_OP_CALL22(flush, node->nn->path, NN_INFO(node)); - if(fuse_ops_compat2 && fuse_ops_compat2->open && fuse_ops_compat2->release) - fuse_ops_compat2->release(node->nn->path, node->nn->info.compat22.flags); + if(FUSE_OP_HAVE(open) && FUSE_OP_HAVE(release)) + { + if(FUSE_OP_HAVE22(release)) + FUSE_OP_CALL22(release, node->nn->path, NN_INFO(node)); + + else if(fuse_ops_compat2) + fuse_ops_compat2->release(node->nn->path, + node->nn->info.compat22.flags); - else if(fuse_ops_compat22 && fuse_ops_compat22->open - && fuse_ops_compat22->release) - fuse_ops_compat22->release(node->nn->path, &node->nn->info.compat22); + else + assert(0); + } if(sz < 0) err = -sz; @@ -1170,19 +1218,31 @@ error_t netfs_attempt_read (struct iouser *cred, struct node *node, goto out; } - if(fuse_ops_compat2 && fuse_ops_compat2->open - && (err = fuse_ops_compat2->open(node->nn->path, - node->nn->info.compat22.flags))) - goto out; - else if(fuse_ops_compat22 && fuse_ops_compat22->open - && (err = fuse_ops_compat22->open(node->nn->path, - &node->nn->info.compat22))) - goto out; + if(FUSE_OP_HAVE(open)) + { + if(FUSE_OP_HAVE22(open)) + err = FUSE_OP_CALL22(open, node->nn->path, NN_INFO(node)); + + else if(fuse_ops_compat2) + err = fuse_ops_compat2->open(node->nn->path, + node->nn->info.compat22.flags); + + else + assert(0); + + if(err) goto out; + } - int sz = fuse_ops_compat22 ? - (fuse_ops_compat22->read(node->nn->path, data, *len, - offset, &node->nn->info.compat22)) : - (fuse_ops_compat2->read(node->nn->path, data, *len, offset)); + int sz; + if(FUSE_OP_HAVE22(read)) + sz = FUSE_OP_CALL22(read, node->nn->path, data, *len, offset, + NN_INFO(node)); + + else if(fuse_ops_compat2) + sz = fuse_ops_compat2->read(node->nn->path, data, *len, offset); + + else + assert(0); /* FIXME: open, flush and release handling probably should be changed * completely, I mean, we probably should do fuse_ops->open in @@ -1191,15 +1251,21 @@ error_t netfs_attempt_read (struct iouser *cred, struct node *node, * * This way we wouldn't be able to report any errors back. */ - if(sz >= 0 && fuse_ops_compat22 && fuse_ops_compat22->flush) - err = fuse_ops_compat22->flush(node->nn->path, &node->nn->info.compat22); + if(sz >= 0 && FUSE_OP_HAVE22(flush)) + err = FUSE_OP_CALL22(flush, node->nn->path, NN_INFO(node)); - if(fuse_ops_compat2 && fuse_ops_compat2->open && fuse_ops_compat2->release) - fuse_ops_compat2->release(node->nn->path, node->nn->info.compat22.flags); + if(FUSE_OP_HAVE(open) && FUSE_OP_HAVE(release)) + { + if(FUSE_OP_HAVE22(release)) + FUSE_OP_CALL22(release, node->nn->path, NN_INFO(node)); + + else if(fuse_ops_compat2) + fuse_ops_compat2->release(node->nn->path, + node->nn->info.compat22.flags); - else if(fuse_ops_compat22 && fuse_ops_compat22->open - && fuse_ops_compat22->release) - fuse_ops_compat22->release(node->nn->path, &node->nn->info.compat22); + else + assert(0); + } if(sz < 0) err = -sz; @@ -1236,10 +1302,9 @@ fuse_get_inode(const char *name) { struct stat stat; - assert(fuse_ops_compat22); - assert(fuse_ops_compat22->getattr); - - fuse_ops_compat22->getattr(name, &stat); + assert(FUSE_OP_HAVE22(getattr)); + FUSE_OP_CALL22(getattr, name, &stat); + return stat.st_ino; } @@ -1388,13 +1453,15 @@ get_dirents_getdir(struct node *dir, int first_entry, int num_entries, handle->parent = dir->nn; handle->hdrpos = (struct dirent*) *data; - if(fuse_ops_compat22) - fuse_ops_compat22->getdir(dir->nn->path, handle, - get_dirents_getdir_helper); - else + if(FUSE_OP_HAVE22(getdir)) + FUSE_OP_CALL22(getdir, dir->nn->path, handle, get_dirents_getdir_helper); + + else if(fuse_ops_compat2) fuse_ops_compat2->getdir(dir->nn->path, handle, - get_dirents_getdir_helper_compat); - + get_dirents_getdir_helper_compat); + + else + assert(0); *data_len -= handle->size; /* subtract number of bytes left in the * buffer from the length of the buffer we @@ -1522,8 +1589,7 @@ get_dirents_readdir(struct node *dir, int first_entry, int num_entries, error_t err; FUNC_PROLOGUE_NODE("get_dirents_readdir", dir); - if(! (fuse_ops_compat22 && fuse_ops_compat22->readdir)) - FUNC_RETURN(EOPNOTSUPP); + assert(FUSE_OP_HAVE22(readdir)); fuse_dirh_t handle; if(! (handle = malloc(sizeof(struct fuse_dirhandle)))) @@ -1552,22 +1618,21 @@ get_dirents_readdir(struct node *dir, int first_entry, int num_entries, handle->parent = dir->nn; handle->hdrpos = (struct dirent*) *data; - if(fuse_ops_compat22->opendir - && (err = fuse_ops_compat22->opendir(dir->nn->path, - &dir->nn->info.compat22))) + if(FUSE_OP_HAVE22(opendir) + && (err = FUSE_OP_CALL22(opendir, dir->nn->path, NN_INFO(dir)))) goto out; - if((err = fuse_ops_compat22->readdir(dir->nn->path, handle, - get_dirents_readdir_helper, - first_entry, &dir->nn->info.compat22))) + if((err = FUSE_OP_CALL22(readdir, dir->nn->path, handle, + get_dirents_readdir_helper, + first_entry, NN_INFO(dir)))) { - fuse_ops_compat22->releasedir(dir->nn->path, &dir->nn->info.compat22); + if(FUSE_OP_HAVE22(releasedir)) + FUSE_OP_CALL22(releasedir, dir->nn->path, NN_INFO(dir)); goto out; } - if(fuse_ops_compat22->releasedir - && (err = fuse_ops_compat22->releasedir(dir->nn->path, - &dir->nn->info.compat22))) + if(FUSE_OP_HAVE22(releasedir) + && (err = FUSE_OP_CALL22(releasedir, dir->nn->path, NN_INFO(dir)))) goto out; *data_len -= handle->size; /* subtract number of bytes left in the @@ -1601,7 +1666,7 @@ netfs_get_dirents (struct iouser *cred, struct node *dir, goto out; - if(fuse_ops_compat22 && fuse_ops_compat22->readdir) + if(FUSE_OP_HAVE22(readdir)) err = get_dirents_readdir(dir, first_entry, num_entries, data, data_len, data_entries); |