--- a/src/simple.c Tue Nov 18 02:06:52 2008 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,283 +0,0 @@
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include "simple.h"
-#include "dirbuf.h"
-#include "lib/log.h"
-#include "lib/math.h"
-#include "lib/misc.h"
-
-struct simple_fs {
- const struct simple_node *inode_table;
-
- size_t inode_count;
-};
-
-/*
- * Used for stat/entry timeouts... not sure how this should really be set.
- */
-#define CACHE_TIMEOUT 1.0
-
-static void _simple_stat (struct stat *stat, const struct simple_node *node) {
- stat->st_ino = node->inode;
- stat->st_mode = node->mode_type | node->mode_perm;
- stat->st_nlink = 1;
- stat->st_size = node->data ? strlen(node->data) : 0;
-}
-
-/*
- * Fetch the simple_node for the given inode.
- *
- * Returns NULL for invalid inodes.
- */
-static const struct simple_node *_simple_get_ino (struct simple_fs *fs, fuse_ino_t ino) {
- // make sure it's a valid inode
- if (ino < 1 || ino > fs->inode_count) {
- WARNING("invalid inode=%zu", ino);
- return NULL;
- }
-
- // return the node
- return fs->inode_table + (ino - 1);
-}
-
-static void simple_lookup (fuse_req_t req, fuse_ino_t parent, const char *name) {
- struct simple_fs *fs = fuse_req_userdata(req);
- const struct simple_node *node;
- struct fuse_entry_param e; ZINIT(e);
- int err;
-
- INFO("[simple.lookup %p] parent=%lu, name=`%s'", fs, parent, name);
-
- // find the matching node
- for (node = fs->inode_table; node->inode > 0; node++) {
- if (node->parent == parent && strcmp(node->name, name) == 0)
- break;
-
- }
-
- // did we find it?
- if (node->inode) {
- // set up the entry
- e.ino = node->inode;
- e.generation = 0x01;
- _simple_stat(&e.attr, node);
- e.attr_timeout = CACHE_TIMEOUT;
- e.entry_timeout = CACHE_TIMEOUT;
-
- // reply
- if ((err = fuse_reply_entry(req, &e)))
- EERROR(err, "fuse_reply_entry");
-
- } else {
- // not found
- err = ENOENT;
- goto error;
- }
-
- // success
- return;
-
-error:
- if ((err = fuse_reply_err(req, err)))
- EWARNING(err, "fuse_reply_err");
-}
-
-static void simple_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) {
- struct simple_fs *fs = fuse_req_userdata(req);
- const struct simple_node *node;
- struct stat stbuf; ZINIT(stbuf);
- int err;
-
- INFO("[simple.getattr %p] ino=%lu", fs, ino);
-
- // look up the node
- if ((node = _simple_get_ino(fs, ino)) == NULL)
- EERROR(err = EINVAL, "bad inode");
-
- // set up the stbuf
- _simple_stat(&stbuf, node);
-
- // reply
- if ((err = fuse_reply_attr(req, &stbuf, CACHE_TIMEOUT)))
- EERROR(err, "fuse_reply_attr");
-
- // suceccss
- return;
-
-error:
- if ((err = fuse_reply_err(req, err)))
- EWARNING(err, "fuse_reply_err");
-}
-
-static void simple_readlink (fuse_req_t req, fuse_ino_t ino) {
- struct simple_fs *fs = fuse_req_userdata(req);
- const struct simple_node *node;
- int err;
-
- INFO("[simple.readlink %p] ino=%lu", fs, ino);
-
- // look up the node
- if ((node = _simple_get_ino(fs, ino)) == NULL)
- EERROR(err = EINVAL, "bad inode");
-
- // check that it's a symlink
- if (node->mode_type != S_IFLNK)
- EERROR(err = EINVAL, "bad mode");
-
- // return the contents
- if ((err = fuse_reply_readlink(req, node->data)))
- EERROR(err, "fuse_reply_readlink");
-
- // suceccss
- return;
-
-error:
- if ((err = fuse_reply_err(req, err)))
- EWARNING(err, "fuse_reply_err");
-
-}
-
-static void simple_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) {
- struct simple_fs *fs = fuse_req_userdata(req);
- const struct simple_node *dir_node, *node;
- struct dirbuf buf;
- int err;
-
- INFO("[simple.readdir] ino=%lu, size=%zu, off=%zu, fi=%p", ino, size, off, fi);
-
- // look up the inode
- if ((dir_node = _simple_get_ino(fs, ino)) == NULL)
- EERROR(err = EINVAL, "bad inode");
-
- // check that it's a dir
- if (dir_node->mode_type != S_IFDIR)
- EERROR(err = ENOTDIR, "bad mode");
-
- // fill in the dirbuf
- if (dirbuf_init(&buf, size, off))
- ERROR("failed to init dirbuf");
-
- // add . and ..
- // we set the next offset to 2, because all dirent offsets will be larger than that
- err = dirbuf_add(req, &buf, 0, 1, ".", dir_node->inode, S_IFDIR )
- || dirbuf_add(req, &buf, 1, 2, "..", dir_node->inode, S_IFDIR );
-
- if (err != 0)
- EERROR(err, "failed to add . and .. dirents");
-
- // look up all child nodes
- for (node = fs->inode_table; node->inode; node++) {
- // skip non-children
- if (node->parent != dir_node->inode)
- continue;
-
- // child node offsets are just inode + 2
- if ((err = dirbuf_add(req, &buf, node->inode + 2, node->inode + 3, node->name, node->inode, node->mode_type)) < 0)
- EERROR(err, "failed to add dirent for inode=%lu", node->inode);
-
- // stop if it's full
- if (err > 0)
- break;
- }
-
- // send it
- if ((err = -dirbuf_done(req, &buf)))
- EERROR(err, "failed to send buf");
-
- // success
- return;
-
-error:
- if ((err = fuse_reply_err(req, err)))
- EWARNING(err, "fuse_reply_err");
-}
-
-static void simple_read (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) {
- struct simple_fs *fs = fuse_req_userdata(req);
- const struct simple_node *node;
- int err ;
-
- // fi is unused
- (void) fi;
-
- INFO("[simple.read] ino=%lu, size=%zu, off=%zu, fi=%p", ino, size, off, fi);
-
- // look up the inode
- if ((node = _simple_get_ino(fs, ino)) == NULL)
- EERROR(err = EINVAL, "bad inode");
-
- // check that it's a dir
- if (node->mode_type != S_IFREG)
- EERROR(err = (node->mode_type == S_IFDIR ? EISDIR : EINVAL), "bad mode");
-
- // seek past EOF?
- if (off >= strlen(node->data)) {
- // offset is out-of-file, so return EOF
- if ((err = fuse_reply_buf(req, NULL, 0)))
- EERROR(err, "fuse_reply_buf size=0");
-
- } else {
- // reply with the requested file data
- if ((err = fuse_reply_buf(req, node->data + off, MIN(strlen(node->data) - off, size))))
- EERROR(err, "fuse_reply_buf buf=%p + %zu, size=MIN(%zu, %zu)", node->data, off, strlen(node->data) - off, size);
- }
-
- // success
- return;
-
-error:
- if ((err = fuse_reply_err(req, err)))
- EWARNING(err, "fuse_reply_err");
-}
-
-
-/*
- * Define our fuse_lowlevel_ops struct.
- */
-static struct fuse_lowlevel_ops simple_ops = {
- .lookup = simple_lookup,
-
- .getattr = simple_getattr,
-
- .readlink = simple_readlink,
-
- .readdir = simple_readdir,
-
- .read = simple_read,
-};
-
-struct fuse_lowlevel_ops *simple_init () {
- return &simple_ops;
-}
-
-struct simple_fs *simple_new (const struct simple_node *node_list) {
- struct simple_fs *fs = NULL;
- const struct simple_node *node;
-
- // generate
- if ((fs = calloc(1, sizeof(*fs))) == NULL)
- ERROR("calloc");
-
- // remember node_list
- fs->inode_count = 0;
- fs->inode_table = node_list;
-
- // validate it
- for (node = fs->inode_table; node->inode; node++) {
- // update inode_count
- fs->inode_count++;
-
- // check that parent is valid
- assert(node->inode == fs->inode_count);
- assert(node->parent < node->inode);
- }
-
- // success
- return fs;
-
-error:
- return NULL;
-}