1
0
mirror of https://github.com/falk-werner/webfuse synced 2024-10-27 20:34:10 +00:00

removed fuse high level API stuff

This commit is contained in:
Falk Werner 2019-02-03 19:10:05 +01:00
parent eb0bdb1f01
commit c9ec71ccd5
17 changed files with 224 additions and 572 deletions

View File

@ -44,17 +44,12 @@ set(EXTRA_CFLAGS
add_library(fuse-wsfs add_library(fuse-wsfs
src/wsfs/status.c src/wsfs/status.c
src/wsfs/operations.c src/wsfs/operations.c
src/wsfs/operation/lookup.c
src/wsfs/operation/getattr.c src/wsfs/operation/getattr.c
src/wsfs/operation/readdir.c src/wsfs/operation/readdir.c
src/wsfs/operation/open.c src/wsfs/operation/open.c
src/wsfs/operation/close.c src/wsfs/operation/close.c
src/wsfs/operation/read.c src/wsfs/operation/read.c
src/wsfs/operation/ll_lookup.c
src/wsfs/operation/ll_getattr.c
src/wsfs/operation/ll_readdir.c
src/wsfs/operation/ll_open.c
src/wsfs/operation/ll_close.c
src/wsfs/operation/ll_read.c
src/wsfs/response_parser.c src/wsfs/response_parser.c
src/wsfs/server.c src/wsfs/server.c
src/wsfs/protocol.c src/wsfs/protocol.c

View File

@ -139,7 +139,7 @@ int main(int argc, char * argv[])
wsfs_server_start(server); wsfs_server_start(server);
struct wsfs_jsonrpc * const rpc = wsfs_server_get_jsonrpc_service(server); struct wsfs_jsonrpc * const rpc = wsfs_server_get_jsonrpc_service(server);
result = wsfs_operations_loop_ll(args.mount_point, rpc); result = wsfs_operations_loop(args.mount_point, rpc);
wsfs_server_dispose(server); wsfs_server_dispose(server);
} }
else else

View File

@ -36,29 +36,9 @@ class FileSystem {
} }
} }
_getEntry(path) {
if ("number" === typeof(path)) {
const inode = path;
return this._inodes[inode];
}
else {
let curItem = this.root;
for(let item of path.split('/')) {
if ('' !== item) {
curItem = curItem.entries && curItem.entries[item];
if (!curItem) {
return null;
}
}
}
return curItem;
}
}
lookup(parent, name) { lookup(parent, name) {
const parentEntry = this._getEntry(parent); const parentEntry = this._inodes[parent];
const entry = (parentEntry && parentEntry.entries && parentEntry.entries[name]) || null; const entry = (parentEntry && parentEntry.entries && parentEntry.entries[name]) || null;
if (entry) { if (entry) {
return { return {
@ -77,8 +57,8 @@ class FileSystem {
} }
getattr(path) { getattr(inode) {
let entry = this._getEntry(path); let entry = this._inodes[inode];
if (entry) { if (entry) {
return { return {
mode: entry.mode || parseInt("755", 8), mode: entry.mode || parseInt("755", 8),
@ -94,9 +74,9 @@ class FileSystem {
} }
} }
readdir(path) { readdir(inode) {
let result = FileSystem.BAD_NOENTRY; let result = FileSystem.BAD_NOENTRY;
let entry = this._getEntry(path); let entry = this._inodes[inode];
if ((entry) && ("dir" === entry.type)) { if ((entry) && ("dir" === entry.type)) {
result = [ result = [
@ -113,9 +93,9 @@ class FileSystem {
return result; return result;
} }
open(path, mode) { open(inode, mode) {
let result = FileSystem.BAD_NOENTRY; let result = FileSystem.BAD_NOENTRY;
let entry = this._getEntry(path); let entry = this._inodes[inode];
if (entry.type == "file") { if (entry.type == "file") {
result = ((mode & FileSystem.O_ACCMODE) == FileSystem.O_RDONLY) ? {handle: 1337} : FileSystem.BAD_NOACCESS; result = ((mode & FileSystem.O_ACCMODE) == FileSystem.O_RDONLY) ? {handle: 1337} : FileSystem.BAD_NOACCESS;
@ -124,14 +104,14 @@ class FileSystem {
return result; return result;
} }
close(path, handle, mode) { close(inode, handle, mode) {
// do nothing // do nothing
return true; return true;
} }
read(path, handle, offset, length) { read(inode, handle, offset, length) {
let result = FileSystem.BAD_NOENTRY; let result = FileSystem.BAD_NOENTRY;
let entry = this._getEntry(path); let entry = this._inodes[inode];
if (entry.type == "file") { if (entry.type == "file") {
let end = Math.min(offset + length, entry.contents.length); let end = Math.min(offset + length, entry.contents.length);

View File

@ -30,12 +30,6 @@ class FileSystemHandler {
} }
break; break;
case "getattr": case "getattr":
{
const path = request.params[0];
result = this._fs.getattr(path);
}
break;
case "getattr_ll":
{ {
const inode = request.params[0]; const inode = request.params[0];
result = this._fs.getattr(inode); result = this._fs.getattr(inode);
@ -43,32 +37,32 @@ class FileSystemHandler {
break; break;
case "readdir": case "readdir":
{ {
const path = request.params[0]; const inode = request.params[0];
result = this._fs.readdir(path); result = this._fs.readdir(inode);
} }
break; break;
case "open": case "open":
{ {
const path = request.params[0]; const inode = request.params[0];
const mode = request.params[1]; const mode = request.params[1];
result = this._fs.open(path, mode); result = this._fs.open(inode, mode);
} }
break; break;
case "close": case "close":
{ {
const path = request.params[0]; const inode = request.params[0];
const handle = request.params[1]; const handle = request.params[1];
const mode = request.params[2]; const mode = request.params[2];
result = this._fs.open(path, handle, mode); result = this._fs.open(inode, handle, mode);
} }
break; break;
case "read": case "read":
{ {
const path = request.params[0]; const inode = request.params[0];
const handle = request.params[1]; const handle = request.params[1];
const offset = request.params[2]; const offset = request.params[2];
const length = request.params[3]; const length = request.params[3];
result = this._fs.read(path, handle, offset, length); result = this._fs.read(inode, handle, offset, length);
} }
break; break;
default: default:

View File

@ -1,25 +1,30 @@
#include "wsfs/operations.h" #include "wsfs/operations.h"
#include <limits.h> #include <limits.h>
#include <errno.h>
#include <jansson.h> #include <jansson.h>
#include "wsfs/jsonrpc.h"
int wsfs_operation_close( #include "wsfs/jsonrpc.h"
char const *path, #include "wsfs/util.h"
void wsfs_operation_close(
fuse_req_t request,
fuse_ino_t inode,
struct fuse_file_info * file_info) struct fuse_file_info * file_info)
{ {
struct fuse_context * context = fuse_get_context(); struct wsfs_operations_context * user_data = fuse_req_userdata(request);
struct wsfs_jsonrpc * rpc = context->private_data; struct wsfs_jsonrpc * rpc = user_data->rpc;
json_t * result = NULL; json_t * result = NULL;
int handle = (int) (file_info->fh & INT_MAX); int handle = (int) (file_info->fh & INT_MAX);
wsfs_status const status = wsfs_jsonrpc_invoke(rpc, &result, "close", "sii", path, handle, file_info->flags); wsfs_status const status = wsfs_jsonrpc_invoke(rpc, &result, "close", "iii", inode, handle, file_info->flags);
if (NULL != result) if (NULL != result)
{ {
// unused // unused
json_decref(result); json_decref(result);
} }
return wsfs_status_to_rc(status);
fuse_reply_err(request, (WSFS_GOOD == status) ? 0 : ENOENT);
} }

View File

@ -1,25 +1,27 @@
#include "wsfs/operations.h" #include "wsfs/operations.h"
#include <errno.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <jansson.h>
#include "wsfs/util.h"
#include "wsfs/jsonrpc.h" #include "wsfs/jsonrpc.h"
#include "wsfs/util.h"
int wsfs_operation_getattr( extern void wsfs_operation_getattr (
char const * path, fuse_req_t request,
struct stat * buffer, fuse_ino_t inode,
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info)) struct fuse_file_info * WSFS_UNUSED_PARAM(file_info))
{ {
struct fuse_context * const context = fuse_get_context(); struct fuse_ctx const * context = fuse_req_ctx(request);
struct wsfs_jsonrpc * const rpc = context->private_data; struct wsfs_operations_context * user_data = fuse_req_userdata(request);
struct wsfs_jsonrpc * rpc = user_data->rpc;
struct stat buffer;
json_t * data = NULL; json_t * data = NULL;
wsfs_status status = wsfs_jsonrpc_invoke(rpc, &data, "getattr", "s", path); wsfs_status status = wsfs_jsonrpc_invoke(rpc, &data, "getattr", "i", inode);
if (NULL != data) if (NULL != data)
{ {
json_t * mode_holder = json_object_get(data, "mode"); json_t * mode_holder = json_object_get(data, "mode");
@ -27,33 +29,42 @@ int wsfs_operation_getattr(
if ((NULL != mode_holder) && (json_is_integer(mode_holder)) && if ((NULL != mode_holder) && (json_is_integer(mode_holder)) &&
(NULL != type_holder) && (json_is_string(type_holder))) (NULL != type_holder) && (json_is_string(type_holder)))
{ {
buffer->st_mode = json_integer_value(mode_holder) & 0555; memset(&buffer, 0, sizeof(struct stat));
buffer.st_mode = json_integer_value(mode_holder) & 0555;
char const * type = json_string_value(type_holder); char const * type = json_string_value(type_holder);
if (0 == strcmp("file", type)) if (0 == strcmp("file", type))
{ {
buffer->st_mode |= S_IFREG; buffer.st_mode |= S_IFREG;
} }
else if (0 == strcmp("dir", type)) else if (0 == strcmp("dir", type))
{ {
buffer->st_mode |= S_IFDIR; buffer.st_mode |= S_IFDIR;
} }
buffer->st_uid = context->uid; buffer.st_uid = context->uid;
buffer->st_gid = context->gid; buffer.st_gid = context->gid;
buffer->st_nlink = 1; buffer.st_nlink = 1;
buffer->st_size = wsfs_json_get_int(data, "size", 0); buffer.st_size = wsfs_json_get_int(data, "size", 0);
buffer->st_atime = wsfs_json_get_int(data, "atime", 0); buffer.st_atime = wsfs_json_get_int(data, "atime", 0);
buffer->st_mtime = wsfs_json_get_int(data, "mtime", 0); buffer.st_mtime = wsfs_json_get_int(data, "mtime", 0);
buffer->st_ctime = wsfs_json_get_int(data, "ctime", 0); buffer.st_ctime = wsfs_json_get_int(data, "ctime", 0);
} }
else else
{ {
status = WSFS_BAD_FORMAT; status = WSFS_BAD_FORMAT;
} }
json_decref(data); json_decref(data);
} }
return wsfs_status_to_rc(status); if (WSFS_GOOD == status)
{
fuse_reply_attr(request, &buffer, user_data->timeout);
}
else
{
fuse_reply_err(request, ENOENT);
}
} }

View File

@ -1,30 +0,0 @@
#include "wsfs/operations.h"
#include <limits.h>
#include <errno.h>
#include <jansson.h>
#include "wsfs/jsonrpc.h"
#include "wsfs/util.h"
void wsfs_operation_ll_close(
fuse_req_t request,
fuse_ino_t inode,
struct fuse_file_info * file_info)
{
struct wsfs_operations_context * user_data = fuse_req_userdata(request);
struct wsfs_jsonrpc * rpc = user_data->rpc;
json_t * result = NULL;
int handle = (int) (file_info->fh & INT_MAX);
wsfs_status const status = wsfs_jsonrpc_invoke(rpc, &result, "close", "iii", inode, handle, file_info->flags);
if (NULL != result)
{
// unused
json_decref(result);
}
fuse_reply_err(request, (WSFS_GOOD == status) ? 0 : ENOENT);
}

View File

@ -1,70 +0,0 @@
#include "wsfs/operations.h"
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "wsfs/jsonrpc.h"
#include "wsfs/util.h"
extern void wsfs_operation_ll_getattr (
fuse_req_t request,
fuse_ino_t inode,
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info))
{
struct fuse_ctx const * context = fuse_req_ctx(request);
struct wsfs_operations_context * user_data = fuse_req_userdata(request);
struct wsfs_jsonrpc * rpc = user_data->rpc;
struct stat buffer;
json_t * data = NULL;
wsfs_status status = wsfs_jsonrpc_invoke(rpc, &data, "getattr", "i", inode);
if (NULL != data)
{
json_t * mode_holder = json_object_get(data, "mode");
json_t * type_holder = json_object_get(data, "type");
if ((NULL != mode_holder) && (json_is_integer(mode_holder)) &&
(NULL != type_holder) && (json_is_string(type_holder)))
{
memset(&buffer, 0, sizeof(struct stat));
buffer.st_mode = json_integer_value(mode_holder) & 0555;
char const * type = json_string_value(type_holder);
if (0 == strcmp("file", type))
{
buffer.st_mode |= S_IFREG;
}
else if (0 == strcmp("dir", type))
{
buffer.st_mode |= S_IFDIR;
}
buffer.st_uid = context->uid;
buffer.st_gid = context->gid;
buffer.st_nlink = 1;
buffer.st_size = wsfs_json_get_int(data, "size", 0);
buffer.st_atime = wsfs_json_get_int(data, "atime", 0);
buffer.st_mtime = wsfs_json_get_int(data, "mtime", 0);
buffer.st_ctime = wsfs_json_get_int(data, "ctime", 0);
}
else
{
status = WSFS_BAD_FORMAT;
}
json_decref(data);
}
if (WSFS_GOOD == status)
{
fuse_reply_attr(request, &buffer, user_data->timeout);
}
else
{
fuse_reply_err(request, ENOENT);
}
}

View File

@ -1,42 +0,0 @@
#include "wsfs/operations.h"
#include <errno.h>
#include <jansson.h>
#include "wsfs/jsonrpc.h"
#include "wsfs/util.h"
void wsfs_operation_ll_open(
fuse_req_t request,
fuse_ino_t inode,
struct fuse_file_info * file_info)
{
struct wsfs_operations_context * user_data = fuse_req_userdata(request);
struct wsfs_jsonrpc * rpc = user_data->rpc;
json_t * result = NULL;
wsfs_status status = wsfs_jsonrpc_invoke(rpc, &result, "open", "ii", inode, file_info->flags);
if (NULL != result)
{
json_t * handle_holder = json_object_get(result, "handle");
if ((NULL != handle_holder) && (json_is_integer(handle_holder)))
{
file_info->fh = json_integer_value(handle_holder);
}
else
{
status = WSFS_BAD_FORMAT;
}
json_decref(result);
}
if (WSFS_GOOD == status)
{
fuse_reply_open(request, file_info);
}
else
{
fuse_reply_err(request, ENOENT);
}
}

View File

@ -1,87 +0,0 @@
#include "wsfs/operations.h"
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <jansson.h>
#include "wsfs/jsonrpc.h"
#define WSFS_MAX_READ_LENGTH 4096
static wsfs_status wsfs_fill_buffer(
char * buffer,
size_t buffer_size,
char const * format,
char const * data,
size_t count)
{
wsfs_status status = WSFS_GOOD;
size_t const copy_count = (buffer_size < count) ? buffer_size : count;
if (0 < copy_count)
{
if (0 == strcmp("identity", format))
{
memcpy(buffer, data, copy_count);
}
else
{
status = WSFS_BAD;
}
}
return status;
}
void wsfs_operation_ll_read(
fuse_req_t request,
fuse_ino_t inode,
size_t size,
off_t offset,
struct fuse_file_info * file_info)
{
struct wsfs_operations_context * user_data = fuse_req_userdata(request);
struct wsfs_jsonrpc * rpc = user_data->rpc;
int const length = (size <= WSFS_MAX_READ_LENGTH) ? (int) size : WSFS_MAX_READ_LENGTH;
char * buffer = malloc(length);
size_t count = 0;
json_t * data = NULL;
int handle = (file_info->fh & INT_MAX);
wsfs_status status = wsfs_jsonrpc_invoke(rpc, &data, "read", "iiii", inode, handle, (int) offset, length);
if (NULL != data)
{
json_t * data_holder = json_object_get(data, "data");
json_t * format_holder = json_object_get(data, "format");
json_t * count_holder = json_object_get(data, "count");
if ((NULL != data_holder) && (json_is_string(data_holder)) &&
(NULL != format_holder) && (json_is_string(format_holder)) &&
(NULL != count_holder) && (json_is_integer(count_holder)))
{
char const * const data = json_string_value(data_holder);
char const * const format = json_string_value(format_holder);
count = (size_t) json_integer_value(count_holder);
status = wsfs_fill_buffer(buffer, length, format, data, count);
}
else
{
status = WSFS_BAD_FORMAT;
}
json_decref(data);
}
if (WSFS_GOOD == status)
{
fuse_reply_buf(request, buffer, count);
}
else
{
fuse_reply_err(request, ENOENT);
}
free(buffer);
}

View File

@ -1,129 +0,0 @@
#include "wsfs/operations.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "wsfs/jsonrpc.h"
#include "wsfs/util.h"
#define WSFS_DIRBUFFER_INITIAL_SIZE 1024
struct wsfs_dirbuffer
{
char * data;
size_t position;
size_t capacity;
};
static void wsfs_dirbuffer_init(
struct wsfs_dirbuffer * buffer)
{
buffer->data = malloc(WSFS_DIRBUFFER_INITIAL_SIZE);
buffer->position = 0;
buffer->capacity = WSFS_DIRBUFFER_INITIAL_SIZE;
}
static void wsfs_dirbuffer_dispose(
struct wsfs_dirbuffer * buffer)
{
free(buffer->data);
}
static void wsfs_dirbuffer_add(
fuse_req_t request,
struct wsfs_dirbuffer * buffer,
char const * name,
fuse_ino_t inode)
{
size_t const size = fuse_add_direntry(request, NULL, 0, name, NULL, 0);
size_t remaining = buffer->capacity - buffer->position;
while (remaining < size)
{
buffer->capacity *= 2;
buffer->data = realloc(buffer->data, buffer->capacity);
remaining = buffer->capacity - buffer->position;
}
struct stat stat_buffer;
memset(&stat_buffer, 0, sizeof(struct stat));
stat_buffer.st_ino = inode;
fuse_add_direntry(request,
&buffer->data[buffer->position], remaining, name,
&stat_buffer, buffer->position + size);
buffer->position += size;
}
static size_t min(size_t a, size_t b)
{
return (a < b) ? a : b;
}
void wsfs_operation_ll_readdir (
fuse_req_t request,
fuse_ino_t inode,
size_t size,
off_t offset,
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info))
{
struct wsfs_operations_context * user_data = fuse_req_userdata(request);
struct wsfs_jsonrpc * rpc = user_data->rpc;
struct wsfs_dirbuffer buffer;
wsfs_dirbuffer_init(&buffer);
json_t * result = NULL;
wsfs_status const status = wsfs_jsonrpc_invoke(rpc, &result, "readdir", "i", inode);
if (NULL != result)
{
if (json_is_array(result))
{
bool buffer_full = false;
size_t const count = json_array_size(result);
for(size_t i = 0; (!buffer_full) && (i < count); i++)
{
json_t * entry =json_array_get(result, i);
if (json_is_object(entry))
{
json_t * name_holder = json_object_get(entry, "name");
json_t * inode_holder = json_object_get(entry, "inode");
if ((NULL != name_holder) && (json_is_string(name_holder)) &&
(NULL != inode_holder) && (json_is_integer(inode_holder)))
{
char const * name = json_string_value(name_holder);
fuse_ino_t entry_inode = (fuse_ino_t) json_integer_value(inode_holder);
wsfs_dirbuffer_add(request, &buffer, name, entry_inode);
}
}
}
}
json_decref(result);
}
if (WSFS_GOOD == status)
{
if (((size_t) offset) < buffer.position)
{
fuse_reply_buf(request, &buffer.data[offset],
min(buffer.position - offset, size));
}
else
{
fuse_reply_buf(request, NULL, 0);
}
}
else
{
fuse_reply_err(request, ENOENT);
}
wsfs_dirbuffer_dispose(&buffer);
}

View File

@ -10,7 +10,7 @@
#include "wsfs/jsonrpc.h" #include "wsfs/jsonrpc.h"
#include "wsfs/util.h" #include "wsfs/util.h"
void wsfs_operation_ll_lookup ( void wsfs_operation_lookup (
fuse_req_t request, fuse_req_t request,
fuse_ino_t parent, fuse_ino_t parent,
char const * name) char const * name)

View File

@ -1,17 +1,21 @@
#include "wsfs/operations.h" #include "wsfs/operations.h"
#include <errno.h>
#include <jansson.h> #include <jansson.h>
#include "wsfs/jsonrpc.h"
int wsfs_operation_open( #include "wsfs/jsonrpc.h"
char const *path, #include "wsfs/util.h"
void wsfs_operation_open(
fuse_req_t request,
fuse_ino_t inode,
struct fuse_file_info * file_info) struct fuse_file_info * file_info)
{ {
struct fuse_context * context = fuse_get_context(); struct wsfs_operations_context * user_data = fuse_req_userdata(request);
struct wsfs_jsonrpc * rpc = context->private_data; struct wsfs_jsonrpc * rpc = user_data->rpc;
json_t * result = NULL; json_t * result = NULL;
wsfs_status status = wsfs_jsonrpc_invoke(rpc, &result, "open", "si", path, file_info->flags); wsfs_status status = wsfs_jsonrpc_invoke(rpc, &result, "open", "ii", inode, file_info->flags);
if (NULL != result) if (NULL != result)
{ {
json_t * handle_holder = json_object_get(result, "handle"); json_t * handle_holder = json_object_get(result, "handle");
@ -27,5 +31,12 @@ int wsfs_operation_open(
json_decref(result); json_decref(result);
} }
return wsfs_status_to_rc(status); if (WSFS_GOOD == status)
{
fuse_reply_open(request, file_info);
}
else
{
fuse_reply_err(request, ENOENT);
}
} }

View File

@ -1,5 +1,6 @@
#include "wsfs/operations.h" #include "wsfs/operations.h"
#include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <jansson.h> #include <jansson.h>
@ -33,21 +34,22 @@ static wsfs_status wsfs_fill_buffer(
return status; return status;
} }
int wsfs_operation_read( void wsfs_operation_read(
const char * path, fuse_req_t request,
char * buffer, fuse_ino_t inode,
size_t buffer_size, size_t size,
off_t offset, off_t offset,
struct fuse_file_info * file_info) struct fuse_file_info * file_info)
{ {
struct fuse_context * context = fuse_get_context(); struct wsfs_operations_context * user_data = fuse_req_userdata(request);
struct wsfs_jsonrpc * rpc = context->private_data; struct wsfs_jsonrpc * rpc = user_data->rpc;
int const length = (buffer_size <= WSFS_MAX_READ_LENGTH) ? (int) buffer_size : WSFS_MAX_READ_LENGTH; int const length = (size <= WSFS_MAX_READ_LENGTH) ? (int) size : WSFS_MAX_READ_LENGTH;
int result = 0; char * buffer = malloc(length);
size_t count = 0;
json_t * data = NULL; json_t * data = NULL;
int handle = (file_info->fh & INT_MAX); int handle = (file_info->fh & INT_MAX);
wsfs_status status = wsfs_jsonrpc_invoke(rpc, &data, "read", "siii", path, handle, (int) offset, length); wsfs_status status = wsfs_jsonrpc_invoke(rpc, &data, "read", "iiii", inode, handle, (int) offset, length);
if (NULL != data) if (NULL != data)
{ {
json_t * data_holder = json_object_get(data, "data"); json_t * data_holder = json_object_get(data, "data");
@ -60,13 +62,9 @@ int wsfs_operation_read(
{ {
char const * const data = json_string_value(data_holder); char const * const data = json_string_value(data_holder);
char const * const format = json_string_value(format_holder); char const * const format = json_string_value(format_holder);
int const count = json_integer_value(count_holder); count = (size_t) json_integer_value(count_holder);
status = wsfs_fill_buffer(buffer, buffer_size, format, data, count); status = wsfs_fill_buffer(buffer, length, format, data, count);
if (WSFS_GOOD == status)
{
result = count;
}
} }
else else
{ {
@ -76,10 +74,14 @@ int wsfs_operation_read(
json_decref(data); json_decref(data);
} }
if (WSFS_GOOD != status) if (WSFS_GOOD == status)
{ {
result = wsfs_status_to_rc(status); fuse_reply_buf(request, buffer, count);
}
else
{
fuse_reply_err(request, ENOENT);
} }
return result; free(buffer);
} }

View File

@ -1,23 +1,84 @@
#include "wsfs/operations.h" #include "wsfs/operations.h"
#include <jansson.h> #include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "wsfs/util.h"
#include "wsfs/jsonrpc.h" #include "wsfs/jsonrpc.h"
#include "wsfs/util.h"
int wsfs_operation_readdir(
char const * path, #define WSFS_DIRBUFFER_INITIAL_SIZE 1024
void * buffer,
fuse_fill_dir_t filler, struct wsfs_dirbuffer
off_t WSFS_UNUSED_PARAM(offset),
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info),
enum fuse_readdir_flags WSFS_UNUSED_PARAM(flags))
{ {
struct fuse_context * context = fuse_get_context(); char * data;
struct wsfs_jsonrpc * rpc = context->private_data; size_t position;
size_t capacity;
};
static void wsfs_dirbuffer_init(
struct wsfs_dirbuffer * buffer)
{
buffer->data = malloc(WSFS_DIRBUFFER_INITIAL_SIZE);
buffer->position = 0;
buffer->capacity = WSFS_DIRBUFFER_INITIAL_SIZE;
}
static void wsfs_dirbuffer_dispose(
struct wsfs_dirbuffer * buffer)
{
free(buffer->data);
}
static void wsfs_dirbuffer_add(
fuse_req_t request,
struct wsfs_dirbuffer * buffer,
char const * name,
fuse_ino_t inode)
{
size_t const size = fuse_add_direntry(request, NULL, 0, name, NULL, 0);
size_t remaining = buffer->capacity - buffer->position;
while (remaining < size)
{
buffer->capacity *= 2;
buffer->data = realloc(buffer->data, buffer->capacity);
remaining = buffer->capacity - buffer->position;
}
struct stat stat_buffer;
memset(&stat_buffer, 0, sizeof(struct stat));
stat_buffer.st_ino = inode;
fuse_add_direntry(request,
&buffer->data[buffer->position], remaining, name,
&stat_buffer, buffer->position + size);
buffer->position += size;
}
static size_t min(size_t a, size_t b)
{
return (a < b) ? a : b;
}
void wsfs_operation_readdir (
fuse_req_t request,
fuse_ino_t inode,
size_t size,
off_t offset,
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info))
{
struct wsfs_operations_context * user_data = fuse_req_userdata(request);
struct wsfs_jsonrpc * rpc = user_data->rpc;
struct wsfs_dirbuffer buffer;
wsfs_dirbuffer_init(&buffer);
json_t * result = NULL; json_t * result = NULL;
wsfs_status const status = wsfs_jsonrpc_invoke(rpc, &result, "readdir", "s", path); wsfs_status const status = wsfs_jsonrpc_invoke(rpc, &result, "readdir", "i", inode);
if (NULL != result) if (NULL != result)
{ {
if (json_is_array(result)) if (json_is_array(result))
@ -30,9 +91,14 @@ int wsfs_operation_readdir(
if (json_is_object(entry)) if (json_is_object(entry))
{ {
json_t * name_holder = json_object_get(entry, "name"); json_t * name_holder = json_object_get(entry, "name");
if ((NULL != name_holder) && (json_is_string(name_holder))) json_t * inode_holder = json_object_get(entry, "inode");
if ((NULL != name_holder) && (json_is_string(name_holder)) &&
(NULL != inode_holder) && (json_is_integer(inode_holder)))
{ {
buffer_full = filler(buffer, json_string_value(name_holder), NULL, 0, 0); char const * name = json_string_value(name_holder);
fuse_ino_t entry_inode = (fuse_ino_t) json_integer_value(inode_holder);
wsfs_dirbuffer_add(request, &buffer, name, entry_inode);
} }
} }
} }
@ -41,5 +107,23 @@ int wsfs_operation_readdir(
json_decref(result); json_decref(result);
} }
return wsfs_status_to_rc(status); if (WSFS_GOOD == status)
{
if (((size_t) offset) < buffer.position)
{
fuse_reply_buf(request, &buffer.data[offset],
min(buffer.position - offset, size));
}
else
{
fuse_reply_buf(request, NULL, 0);
}
}
else
{
fuse_reply_err(request, ENOENT);
}
wsfs_dirbuffer_dispose(&buffer);
} }

View File

@ -2,56 +2,18 @@
#include <string.h> #include <string.h>
#include "wsfs/util.h"
#include "wsfs/jsonrpc.h"
static void* wsfs_operation_init(
struct fuse_conn_info * WSFS_UNUSED_PARAM(connection),
struct fuse_config * config)
{
struct fuse_context * const context = fuse_get_context();
config->kernel_cache = 1;
return context->private_data;
}
static void wsfs_operations_init(
struct fuse_operations * operations)
{
memset(operations, 0, sizeof(struct fuse_operations));
operations->init = &wsfs_operation_init;
operations->getattr = &wsfs_operation_getattr;
operations->readdir = &wsfs_operation_readdir;
operations->open = &wsfs_operation_open;
operations->release = &wsfs_operation_close;
operations->read = &wsfs_operation_read;
}
int wsfs_operations_loop( int wsfs_operations_loop(
char * mount_point, char * mount_point,
struct wsfs_jsonrpc * rpc) struct wsfs_jsonrpc * rpc)
{
struct fuse_operations operations;
wsfs_operations_init(&operations);
char * fuse_args[] = { "app", "-s", "-f", mount_point, NULL };
int const result = fuse_main(4, fuse_args, &operations, rpc);
return result;
}
int wsfs_operations_loop_ll(
char * mount_point,
struct wsfs_jsonrpc * rpc)
{ {
struct fuse_lowlevel_ops operations; struct fuse_lowlevel_ops operations;
memset(&operations, 0, sizeof(struct fuse_lowlevel_ops)); memset(&operations, 0, sizeof(struct fuse_lowlevel_ops));
operations.lookup = &wsfs_operation_ll_lookup; operations.lookup = &wsfs_operation_lookup;
operations.getattr = &wsfs_operation_ll_getattr; operations.getattr = &wsfs_operation_getattr;
operations.readdir = &wsfs_operation_ll_readdir; operations.readdir = &wsfs_operation_readdir;
operations.open = &wsfs_operation_ll_open; operations.open = &wsfs_operation_open;
operations.release = &wsfs_operation_ll_close; operations.release = &wsfs_operation_close;
operations.read = &wsfs_operation_ll_read; operations.read = &wsfs_operation_read;
int result = 1; int result = 1;
const int argc = 1; const int argc = 1;

View File

@ -19,68 +19,34 @@ extern int wsfs_operations_loop(
char * mount_point, char * mount_point,
struct wsfs_jsonrpc * rpc); struct wsfs_jsonrpc * rpc);
extern int wsfs_operation_readdir( extern void wsfs_operation_lookup (
char const * path,
void * buffer,
fuse_fill_dir_t filler,
off_t offset,
struct fuse_file_info * file_info,
enum fuse_readdir_flags flags);
extern int wsfs_operation_getattr(
char const * path,
struct stat * buffer,
struct fuse_file_info * file_info);
extern int wsfs_operation_open(
char const *path,
struct fuse_file_info * file_info);
extern int wsfs_operation_close(
char const *path,
struct fuse_file_info * file_info);
extern int wsfs_operation_read(
const char * path,
char * buffer,
size_t buffer_size,
off_t offset,
struct fuse_file_info * file_info);
// low level operations
extern int wsfs_operations_loop_ll(
char * mount_point,
struct wsfs_jsonrpc * rpc);
extern void wsfs_operation_ll_lookup (
fuse_req_t req, fuse_req_t req,
fuse_ino_t parent, fuse_ino_t parent,
char const * name); char const * name);
extern void wsfs_operation_ll_getattr ( extern void wsfs_operation_getattr (
fuse_req_t request, fuse_req_t request,
fuse_ino_t inode, fuse_ino_t inode,
struct fuse_file_info *file_info); struct fuse_file_info *file_info);
extern void wsfs_operation_ll_readdir ( extern void wsfs_operation_readdir (
fuse_req_t request, fuse_req_t request,
fuse_ino_t inode, fuse_ino_t inode,
size_t size, size_t size,
off_t offset, off_t offset,
struct fuse_file_info *file_info); struct fuse_file_info *file_info);
extern void wsfs_operation_ll_open( extern void wsfs_operation_open(
fuse_req_t request, fuse_req_t request,
fuse_ino_t inode, fuse_ino_t inode,
struct fuse_file_info * file_info); struct fuse_file_info * file_info);
extern void wsfs_operation_ll_close( extern void wsfs_operation_close(
fuse_req_t request, fuse_req_t request,
fuse_ino_t inode, fuse_ino_t inode,
struct fuse_file_info * file_info); struct fuse_file_info * file_info);
extern void wsfs_operation_ll_read( extern void wsfs_operation_read(
fuse_req_t request, fuse_req_t request,
fuse_ino_t ino, size_t size, off_t off, fuse_ino_t ino, size_t size, off_t off,
struct fuse_file_info *fi); struct fuse_file_info *fi);