From 4da0b8921769fecc47f055a308c79e5e9fd05b34 Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Fri, 20 Mar 2015 04:11:42 +0100 Subject: [PATCH] removed unmountSync and regular unmount stops fuse now --- README.md | 4 -- fuse-bindings.cc | 101 ++++++++++++++++++++++++++++++++++------------- index.js | 34 ++++++++++------ 3 files changed, 94 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 0b2cf02..8f3cc2d 100644 --- a/README.md +++ b/README.md @@ -89,10 +89,6 @@ Pass the FUSE operations you want to support as the `ops` argument. Unmount a filesystem -#### `fuse.unmountSync(mnt)` - -Unmount a filesystem synchroniously - ## FUSE operations Most of the [FUSE api](http://fuse.sourceforge.net/doxygen/structfuse__operations.html) is supported. diff --git a/fuse-bindings.cc b/fuse-bindings.cc index a7f2090..5185d68 100644 --- a/fuse-bindings.cc +++ b/fuse-bindings.cc @@ -3,6 +3,8 @@ #define FUSE_USE_VERSION 29 #include +#include +#include #include #include #include @@ -62,6 +64,8 @@ static struct { // fuse data char mnt[1024]; char mntopts[1024]; + struct fuse *fuse; + struct fuse_chan *fuse_channel; pthread_t thread; #ifdef __APPLE__ dispatch_semaphore_t semaphore; @@ -121,10 +125,6 @@ static struct { } bindings; #ifdef __APPLE__ -static void bindings_unmount (char *path) { - unmount(path, 0); -} - NAN_INLINE static int semaphore_init (dispatch_semaphore_t *sem) { *sem = dispatch_semaphore_create(0); return *sem == NULL ? -1 : 0; @@ -138,14 +138,6 @@ NAN_INLINE static void semaphore_signal (dispatch_semaphore_t *sem) { dispatch_semaphore_signal(*sem); } #else -static void bindings_unmount (char *path) { - // TODO: if someone knows a better way to get this working on linux let me know - char *argv[] = {"fusermount", "-q", "-u", path, NULL}; - pid_t cpid = vfork(); - if (cpid > 0) waitpid(cpid, NULL, 0); - else execvp(argv[0], argv); -} - NAN_INLINE static int semaphore_init (sem_t *sem) { return sem_init(sem, 0, 0); } @@ -159,6 +151,25 @@ NAN_INLINE static void semaphore_signal (sem_t *sem) { } #endif +static void bindings_unmount (char *path) { + if (!strcmp(bindings.mnt, path) && bindings.fuse != NULL) { + fuse_unmount(bindings.mnt, bindings.fuse_channel); + pthread_join(bindings.thread, NULL); + return; + } + +#ifdef __APPLE__ + unmount(path, 0); +#else + // TODO: if someone knows a better way to get this working on linux let me know + char *argv[] = {"fusermount", "-q", "-u", path, NULL}; + pid_t cpid = vfork(); + if (cpid > 0) waitpid(cpid, NULL, 0); + else execvp(argv[0], argv); +#endif +} + + #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION) NAN_INLINE v8::Local bindings_buffer (char *data, size_t length) { Local buf = NanNew(buffer_constructor)->NewInstance(0, NULL); @@ -472,18 +483,59 @@ static void *bindings_thread (void *) { if (bindings.ops_init != NULL) ops.init = bindings_init; if (bindings.ops_destroy != NULL) ops.destroy = bindings_destroy; + int argc = !strcmp(bindings.mntopts, "-o") ? 1 : 2; char *argv[] = { (char *) "fuse_bindings_dummy", - (char *) "-s", - (char *) "-f", - (char *) bindings.mnt, (char *) bindings.mntopts }; - if (fuse_main(!strcmp(bindings.mntopts, "-o") ? 4 : 5, argv, &ops, NULL)) { - bindings.op = OP_ERROR; - bindings_call(); - } + struct fuse_args args = FUSE_ARGS_INIT(argc, argv); + struct fuse_chan *ch = bindings.fuse_channel = fuse_mount(bindings.mnt, &args); + + int ops_size = sizeof(struct fuse_operations); + bindings.fuse = fuse_new(ch, &args, &ops, ops_size, NULL); + bindings.fuse_channel = ch; + + fuse_loop(bindings.fuse); + fuse_session_remove_chan(ch); + fuse_destroy(bindings.fuse); + + uv_close((uv_handle_t*) &bindings.async, NULL); + + if (bindings.ops_access != NULL) delete bindings.ops_access; + if (bindings.ops_truncate != NULL) delete bindings.ops_truncate; + if (bindings.ops_ftruncate != NULL) delete bindings.ops_ftruncate; + if (bindings.ops_getattr != NULL) delete bindings.ops_getattr; + if (bindings.ops_fgetattr != NULL) delete bindings.ops_fgetattr; + if (bindings.ops_flush != NULL) delete bindings.ops_flush; + if (bindings.ops_fsync != NULL) delete bindings.ops_fsync; + if (bindings.ops_fsyncdir != NULL) delete bindings.ops_fsyncdir; + if (bindings.ops_readdir != NULL) delete bindings.ops_readdir; + if (bindings.ops_readlink != NULL) delete bindings.ops_readlink; + if (bindings.ops_chown != NULL) delete bindings.ops_chown; + if (bindings.ops_chmod != NULL) delete bindings.ops_chmod; + if (bindings.ops_setxattr != NULL) delete bindings.ops_setxattr; + if (bindings.ops_getxattr != NULL) delete bindings.ops_getxattr; + if (bindings.ops_statfs != NULL) delete bindings.ops_statfs; + if (bindings.ops_open != NULL) delete bindings.ops_open; + if (bindings.ops_opendir != NULL) delete bindings.ops_opendir; + if (bindings.ops_read != NULL) delete bindings.ops_read; + if (bindings.ops_write != NULL) delete bindings.ops_write; + if (bindings.ops_release != NULL) delete bindings.ops_release; + if (bindings.ops_releasedir != NULL) delete bindings.ops_releasedir; + if (bindings.ops_create != NULL) delete bindings.ops_create; + if (bindings.ops_utimens != NULL) delete bindings.ops_utimens; + if (bindings.ops_unlink != NULL) delete bindings.ops_unlink; + if (bindings.ops_rename != NULL) delete bindings.ops_rename; + if (bindings.ops_link != NULL) delete bindings.ops_link; + if (bindings.ops_symlink != NULL) delete bindings.ops_symlink; + if (bindings.ops_mkdir != NULL) delete bindings.ops_mkdir; + if (bindings.ops_rmdir != NULL) delete bindings.ops_rmdir; + if (bindings.ops_init != NULL) delete bindings.ops_init; + if (bindings.ops_destroy != NULL) delete bindings.ops_destroy; + + bindings.fuse = NULL; + bindings_in_use = 0; return NULL; } @@ -867,7 +919,8 @@ NAN_METHOD(Mount) { if (bindings_in_use) return NanThrowError("Currently only a single filesystem can be mounted at the time"); bindings_in_use = 1; - memset(&empty_stat, 0, sizeof(empty_stat)); // zero empty stat + memset(&empty_stat, 0, sizeof(empty_stat)); + memset(&bindings, 0, sizeof(bindings)); NanUtf8String path(args[0]); Local ops = args[1].As(); @@ -928,13 +981,6 @@ NAN_METHOD(Mount) { NanReturnUndefined(); } -NAN_METHOD(UnmountSync) { - NanScope(); - NanUtf8String path(args[0]); - bindings_unmount(*path); - NanReturnUndefined(); -} - class UnmountWorker : public NanAsyncWorker { public: UnmountWorker(NanCallback *callback, char *path) @@ -979,7 +1025,6 @@ void Init(Handle exports) { exports->Set(NanNew("setBuffer"), NanNew(SetBuffer)->GetFunction()); exports->Set(NanNew("mount"), NanNew(Mount)->GetFunction()); exports->Set(NanNew("unmount"), NanNew(Unmount)->GetFunction()); - exports->Set(NanNew("unmountSync"), NanNew(UnmountSync)->GetFunction()); } NODE_MODULE(fuse_bindings, Init) \ No newline at end of file diff --git a/index.js b/index.js index 7d165aa..de77126 100644 --- a/index.js +++ b/index.js @@ -22,36 +22,44 @@ exports.mount = function (mnt, ops, cb) { if (/\*|(^,)fuse-bindings(,$)/.test(process.env.DEBUG)) ops.options = ['debug'].concat(ops.options || []) mnt = path.resolve(mnt) + var callback = function (err) { + callback = noop + ops.init = init + ops.error = error + process.nextTick(cb.bind(null, err)) + } + var init = ops.init || call ops.init = function (next) { - cb() + callback() init(next) } var error = ops.error || call ops.error = function (next) { - cb(new Error('Mount failed')) + callback(new Error('Mount failed')) error(next) } - fs.stat(mnt, function (err, stat) { - if (err) return cb(new Error('Mountpoint does not exist')) - if (!stat.isDirectory()) return cb(new Error('Mountpoint is not a directory')) - fs.stat(path.join(mnt, '..'), function (_, parent) { - if (parent && parent.dev !== stat.dev) return cb(new Error('Mountpoint in use')) - fuse.mount(mnt, ops) + var mount = function () { + fs.stat(mnt, function (err, stat) { + if (err) return cb(new Error('Mountpoint does not exist')) + if (!stat.isDirectory()) return cb(new Error('Mountpoint is not a directory')) + fs.stat(path.join(mnt, '..'), function (_, parent) { + if (parent && parent.dev !== stat.dev) return cb(new Error('Mountpoint in use')) + fuse.mount(mnt, ops) + }) }) - }) + } + + if (!ops.force) return mount() + exports.unmount(mnt, mount) } exports.unmount = function (mnt, cb) { fuse.unmount(path.resolve(mnt), cb || noop) } -exports.unmountSync = function (mnt) { - return fuse.unmountSync(path.resolve(mnt)) -} - exports.EPERM = -1 exports.ENOENT = -2 exports.ESRCH = -3