Skip to content

Commit

Permalink
add multi forget for fuse
Browse files Browse the repository at this point in the history
  • Loading branch information
EricTheMagician committed Aug 22, 2015
1 parent 28f7c31 commit 2f9d912
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 44 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ before_install:
- npm/.bin/npm install -g node-gyp-install
- npm/.bin/npm install -g mocha
- node-gyp-install
- wget http://downloads.sourceforge.net/project/fuse/fuse-2.X/2.9.4/fuse-2.9.4.tar.gz
- tar xf fuse-2.9.4.tar.gz
- mkdir include
- cp fuse-2.9.4/include/*.h include

install:
- npm/.bin/npm install
Expand Down
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = function (grunt){
},
scripts:{
files:['src/*.cc', 'src/*.h', 'binding.gyp'],
tasks:['gyp', 'mochaTest']
tasks:['gyp','mochaTest']
},
example_test:{
files:['test/test_example.js', 'examples/example.js'],
Expand Down
6 changes: 4 additions & 2 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
"src/file_info.cc",
"src/filesystem.cc",
"src/node_fuse.cc",
"src/reply.cc",
"src/reply.cc",
'src/forget_data.cc'
],
"include_dirs": [
'./include',
'<!@(pkg-config fuse --cflags-only-I | sed s/-I//g)',
"<!(node -e \"require('nan')\")"
],
'cflags_cc': ['-Wall', '-g', '-Warray-bounds', '-fpermissive'],
"defines": [
'_FILE_OFFSET_BITS=64', 'FUSE_USE_VERSION=27', 'restrict='
'_FILE_OFFSET_BITS=64', 'FUSE_USE_VERSION=30'
],
"link_settings": {
"libraries": [
Expand Down
17 changes: 16 additions & 1 deletion fuse.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,27 @@ var FileSystem = function() {
* @param {Number} nlookup The number of lookups to forget.
*
**/
this.forget = function(context, inode, nlookup) {
this.forget = function(context, inode, nlookup,reply) {
if(warn_not_implemented){
console.log("forget not implemented");
}
reply.none();
};

/**
*
* like forget, except batched.
* here forget_data is an object with 2 fields: inode and nlookup
*
**/
this.multiforget = function(context, forget_data, reply){
if(warn_not_implemented){
console.log("forget not implemented");
}
reply.none();

}

/**
* Get file attributes
*
Expand Down
88 changes: 84 additions & 4 deletions src/filesystem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "reply.h"
#include "file_info.h"
#include "bindings.h"
#include "forget_data.h"
#include "node_buffer.h"
#include "mpsc_queue.h"

Expand Down Expand Up @@ -73,7 +74,7 @@ namespace NodeFuse {
// static struct vrt_queue *ring_buffer; // = vrt_queue_new("queue", vrt_fuse_cmd_type, __RING_SIZE__);
// static struct vrt_producer **producers;// = (struct vrt_producer *) malloc(sizeof(struct vrt_producer *) * _NUMBER_OF_FUSE_OPERATIONS_)
// static struct vrt_consumer *consumer;
static struct fuse_lowlevel_ops fuse_ops = {};
static struct fuse_lowlevel_ops fuse_ops;

static mpsc_queue_t<struct fuse_cmd> ring_buffer(__RING_SIZE__);

Expand Down Expand Up @@ -195,6 +196,14 @@ namespace NodeFuse {
break;
case _FUSE_OPS_SETLK_:
break;
case _FUSE_OPS_MULTI_FORGET_:
#if FUSE_USE_VERSION > 28
#ifndef __APPLE__
RemoteMultiForget(value->req, value->size, static_cast<struct fuse_forget_data *>(value->userdata) );
#endif
#endif
break;

case _FUSE_OPS_BMAP_:
break;
}
Expand Down Expand Up @@ -243,6 +252,9 @@ namespace NodeFuse {
fuse_ops.releasedir = FileSystem::ReleaseDir;
fuse_ops.fsyncdir = FileSystem::FSyncDir;
fuse_ops.statfs = FileSystem::StatFs;
#if FUSE_USE_VERSION > 28
fuse_ops.forget_multi = FileSystem::MultiForget;
#endif
// fuse_ops.setxattr = FileSystem::SetXAttr;
// fuse_ops.getxattr = FileSystem::GetXAttr;
// fuse_ops.listxattr = FileSystem::ListXAttr;
Expand Down Expand Up @@ -430,6 +442,68 @@ namespace NodeFuse {
//scope.Close(Undefined());

}

#if FUSE_USE_VERSION > 28
void FileSystem::MultiForget(fuse_req_t req,
size_t count,
struct fuse_forget_data *forget){
struct fuse_cmd *value;

if( ring_buffer.producer_claim_next(&value) != 0){
printf("ring buffer was full while trying to enqueue multi forget\n");
return;
}

value->op = _FUSE_OPS_MULTI_FORGET_;
value->req = req;
value->size = count;
value->userdata = (void *) forget;

ring_buffer.producer_publish();//(producers[ 0/*_FUSE_OPS_FORGET_*/]);
// uv_async_send(&uv_async_handle);

}
void FileSystem::RemoteMultiForget(fuse_req_t req,
size_t count,
struct fuse_forget_data *forget_all) {
Nan::HandleScope scope;;
Fuse* fuse = static_cast<Fuse *>(fuse_req_userdata(req));
Local<Object> fsobj = Nan::New(fuse->fsobj);
Local<Value> vforget = fsobj->Get(Nan::New<String>("multiforget").ToLocalChecked());
Local<Function> forget = Local<Function>::Cast(vforget);

Local<Object> context = RequestContextToObject(fuse_req_ctx(req))->ToObject();
Local<Array> data = Nan::New<Array>(count);

for( uint i = 0; i < count; i++){
ForgetData *forget_data = new ForgetData();
// forget_data->fd = &( forget_all[i] );
Local<Object> infoObj = Nan::NewInstance(Nan::New<Function>(forget_data->constructor)).ToLocalChecked();//->GetFunction()->NewInstance();
data->Set(i, infoObj);
}

Reply* reply = new Reply();
reply->request = req;
Local<Object> replyObj = Nan::NewInstance( Nan::New<Function>(reply->constructor)).ToLocalChecked();//->GetFunction()->NewInstance();
reply->Wrap(replyObj);

Local<Value> argv[3] = {context, data, replyObj};

Nan::TryCatch try_catch;

forget->Call(fsobj, 3, argv);

if (try_catch.HasCaught()) {
Nan::FatalException(try_catch);
}

fuse_reply_none(req);
//scope.Close(Undefined());

}
#endif //FUSE_USE_VERSION


void FileSystem::Forget(fuse_req_t req,
fuse_ino_t ino,
unsigned long nlookup) {
Expand All @@ -453,7 +527,7 @@ namespace NodeFuse {
void FileSystem::RemoteForget(fuse_req_t req,
fuse_ino_t ino,
unsigned long nlookup) {
Nan::HandleScope scope;;
// Nan::HandleScope scope;;
Fuse* fuse = static_cast<Fuse *>(fuse_req_userdata(req));
Local<Object> fsobj = Nan::New(fuse->fsobj);
Local<Value> vforget = fsobj->Get(Nan::New<String>("forget").ToLocalChecked());
Expand All @@ -463,7 +537,13 @@ namespace NodeFuse {
Local<Number> inode = Nan::New<Number>(ino);
Local<Integer> nlookup_ = Nan::New<Integer>( (int) nlookup);

Local<Value> argv[3] = {context, inode, nlookup_};
Reply* reply = new Reply();
reply->request = req;
Local<Object> replyObj = Nan::NewInstance( Nan::New<Function>(reply->constructor)).ToLocalChecked();//->GetFunction()->NewInstance();
reply->Wrap(replyObj);


Local<Value> argv[4] = {context, inode, nlookup_, replyObj};

Nan::TryCatch try_catch;

Expand All @@ -473,7 +553,7 @@ namespace NodeFuse {
Nan::FatalException(try_catch);
}

fuse_reply_none(req);
// fuse_reply_none(req);
//scope.Close(Undefined());

}
Expand Down
85 changes: 49 additions & 36 deletions src/filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,45 @@
#include "node_fuse.h"
#include <stdlib.h>
#include <stdint.h>
#define _FUSE_OPS_LOOKUP_ 0
#define _FUSE_OPS_GETATTR_ 1
#define _FUSE_OPS_OPEN_ 2
#define _FUSE_OPS_READ_ 3
#define _FUSE_OPS_READDIR_ 4
#define _FUSE_OPS_INIT_ 5
#define _FUSE_OPS_DESTROY_ 6
#define _FUSE_OPS_FORGET_ 7
#define _FUSE_OPS_SETATTR_ 8
#define _FUSE_OPS_READLINK_ 9
#define _FUSE_OPS_MKNOD_ 10
#define _FUSE_OPS_MKDIR_ 11
#define _FUSE_OPS_UNLINK_ 12
#define _FUSE_OPS_RMDIR_ 13
#define _FUSE_OPS_SYMLINK_ 14
#define _FUSE_OPS_RENAME_ 15
#define _FUSE_OPS_LINK_ 16
#define _FUSE_OPS_WRITE_ 17
#define _FUSE_OPS_FLUSH_ 18
#define _FUSE_OPS_RELEASE_ 19
#define _FUSE_OPS_FSYNC_ 20
#define _FUSE_OPS_OPENDIR_ 21
#define _FUSE_OPS_RELEASEDIR_ 22
#define _FUSE_OPS_FSYNCDIR_ 23
#define _FUSE_OPS_STATFS_ 24
#define _FUSE_OPS_SETXATTR_ 25
#define _FUSE_OPS_GETXATTR_ 26
#define _FUSE_OPS_LISTXATTR_ 27
#define _FUSE_OPS_REMOVEXATTR_ 28
#define _FUSE_OPS_ACCESS_ 29
#define _FUSE_OPS_CREATE_ 30
#define _FUSE_OPS_GETLK_ 31
#define _FUSE_OPS_SETLK_ 32
#define _FUSE_OPS_BMAP_ 33
#define _NUMBER_OF_FUSE_OPERATIONS_ 33
#define _FUSE_OPS_LOOKUP_ 0
#define _FUSE_OPS_GETATTR_ 1
#define _FUSE_OPS_OPEN_ 2
#define _FUSE_OPS_READ_ 3
#define _FUSE_OPS_READDIR_ 4
#define _FUSE_OPS_INIT_ 5
#define _FUSE_OPS_DESTROY_ 6
#define _FUSE_OPS_FORGET_ 7
#define _FUSE_OPS_SETATTR_ 8
#define _FUSE_OPS_READLINK_ 9
#define _FUSE_OPS_MKNOD_ 10
#define _FUSE_OPS_MKDIR_ 11
#define _FUSE_OPS_UNLINK_ 12
#define _FUSE_OPS_RMDIR_ 13
#define _FUSE_OPS_SYMLINK_ 14
#define _FUSE_OPS_RENAME_ 15
#define _FUSE_OPS_LINK_ 16
#define _FUSE_OPS_WRITE_ 17
#define _FUSE_OPS_FLUSH_ 18
#define _FUSE_OPS_RELEASE_ 19
#define _FUSE_OPS_FSYNC_ 20
#define _FUSE_OPS_OPENDIR_ 21
#define _FUSE_OPS_RELEASEDIR_ 22
#define _FUSE_OPS_FSYNCDIR_ 23
#define _FUSE_OPS_STATFS_ 24
#define _FUSE_OPS_SETXATTR_ 25
#define _FUSE_OPS_GETXATTR_ 26
#define _FUSE_OPS_LISTXATTR_ 27
#define _FUSE_OPS_REMOVEXATTR_ 28
#define _FUSE_OPS_ACCESS_ 29
#define _FUSE_OPS_CREATE_ 30
#define _FUSE_OPS_GETLK_ 31
#define _FUSE_OPS_SETLK_ 32
#define _FUSE_OPS_BMAP_ 33
#define _FUSE_OPS_BMAP_ 33
#define _FUSE_OPS_MULTI_FORGET_ 34

#define _NUMBER_OF_FUSE_OPERATIONS_ 34

#define _FUSE_UNMOUNT_ 34
#define __RING_SIZE__ 256
extern uv_async_t uv_async_handle;

Expand Down Expand Up @@ -94,6 +96,11 @@ namespace NodeFuse {
static void Forget(fuse_req_t req,
fuse_ino_t ino,
unsigned long nlookup);
#if FUSE_USE_VERSION > 28
static void MultiForget(fuse_req_t req,
size_t count,
struct fuse_forget_data *forget_all);
#endif
static void GetAttr(fuse_req_t req,
fuse_ino_t ino,
struct fuse_file_info* fi);
Expand Down Expand Up @@ -243,6 +250,12 @@ namespace NodeFuse {
static void RemoteForget(fuse_req_t req,
fuse_ino_t ino,
unsigned long nlookup);
#if FUSE_USE_VERSION > 28
static void RemoteMultiForget(fuse_req_t req,
size_t count,
struct fuse_forget_data *forget_all);
#endif

static void RemoteGetAttr(fuse_req_t req,
fuse_ino_t ino,
struct fuse_file_info fi);
Expand Down
51 changes: 51 additions & 0 deletions src/forget_data.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "forget_data.h"
#if FUSE_USE_VERSION > 28

namespace NodeFuse {

Nan::Persistent<Function> ForgetData::constructor;

NAN_METHOD(ForgetData::New){
if (info.IsConstructCall()) {
ForgetData *fi = new ForgetData();
Local<Object> obj = info.This();
fi->Wrap(obj);
info.GetReturnValue().Set( obj );
} else {
Local<Function> cons = Nan::New<Function>(constructor);
info.GetReturnValue().Set(cons->NewInstance());
}

}
void ForgetData::Initialize(Handle<Object> target){
Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(Nan::New<v8::String>("ForgetData").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);

Local<ObjectTemplate> object_tmpl = tpl->InstanceTemplate();

object_tmpl->SetInternalFieldCount(1);

Nan::SetAccessor(object_tmpl, Nan::New("inode").ToLocalChecked(), ForgetData::GetIno);
Nan::SetAccessor(object_tmpl, Nan::New("nlookup").ToLocalChecked(), ForgetData::GetNLookup);
constructor.Reset(tpl->GetFunction());

}
ForgetData::ForgetData() : ObjectWrap() {}
ForgetData::~ForgetData() {}
void ForgetData::GetIno(v8::Local<v8::String> property,
const Nan::PropertyCallbackInfo<v8::Value>& info)
{
ForgetData *forget_data = ObjectWrap::Unwrap<ForgetData>(info.This());
info.GetReturnValue().Set( Nan::New<Integer>(static_cast<uint32_t>(forget_data->fd->ino)));
}

void ForgetData::GetNLookup(v8::Local<v8::String> property,
const Nan::PropertyCallbackInfo<v8::Value>& info)
{
ForgetData *forget_data = ObjectWrap::Unwrap<ForgetData>(info.This());
info.GetReturnValue().Set( Nan::New<Integer>( static_cast<uint32_t>(forget_data->fd->nlookup)) );
}

}
#endif
Loading

0 comments on commit 2f9d912

Please sign in to comment.