--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/error.h Fri Sep 26 21:13:35 2008 +0300
@@ -0,0 +1,8 @@
+#ifndef LIB_ERROR_H
+#define LIB_ERROR_H
+
+#define ERROR(...) do { err_func(__func__, __VA_ARGS__); goto error; } while (0)
+#define PERROR(...) do { perr_func(__func__, __VA_ARGS__); goto error; } while (0)
+#define EERROR(_err, ...) do { eerr_func(__func__, (_err), __VA_ARGS__); goto error; } while (0)
+
+#endif /* LIB_ERROR_H */
--- a/src/lib/log.h Fri Sep 26 20:39:51 2008 +0300
+++ b/src/lib/log.h Fri Sep 26 21:13:35 2008 +0300
@@ -1,3 +1,5 @@
+#ifndef LIB_LOG_H
+#define LIB_LOG_H
/*
* error handling
@@ -35,12 +37,10 @@
#define eerr_func(func, err, ...) _generic_err( 1, func, err,__VA_ARGS__ )
/*
- * error(func + colon + msg, ...) + goto error
- * err = negative error code
+ * Legacy...
*/
-#define ERROR(...) do { err_func(__func__, __VA_ARGS__); goto error; } while (0)
-#define PERROR(...) do { perr_func(__func__, __VA_ARGS__); goto error; } while (0)
-#define EERROR(err, ...) do { eerr_func(__func__, (err), __VA_ARGS__); goto error; } while (0)
+#include "error.h"
+
#define FATAL(...) err_func_exit(__func__, __VA_ARGS__)
#define PFATAL(...) perr_func_exit(__func__, __VA_ARGS__)
#define WARNING(...) err_func(__func__, __VA_ARGS__)
@@ -68,3 +68,4 @@
#define INFO(...) (void) (0)
#endif
+#endif /* LIB_LOG_H */
--- a/src/simple.c Fri Sep 26 20:39:51 2008 +0300
+++ b/src/simple.c Fri Sep 26 21:13:35 2008 +0300
@@ -4,6 +4,7 @@
#include <assert.h>
#include "simple.h"
+#include "dirbuf.h"
#include "lib/log.h"
#include "lib/misc.h"
@@ -25,8 +26,20 @@
stat->st_size = node->data ? strlen(node->data) : 0;
}
-static int _simple_check_ino (struct simple_fs *fs, fuse_ino_t ino) {
- return (ino < 1 || ino > fs->inode_count) ? EIO : 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) {
@@ -79,13 +92,10 @@
INFO("[simple.getattr %p] ino=%lu", fs, ino);
- // make sure ino is valid
- if ((err = _simple_check_ino(fs, ino)))
- ERROR("invalid inode");
-
- // look up the node
- node = fs->inode_table + (ino - 1);
-
+ // 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);
@@ -101,6 +111,60 @@
EWARNING(err, "fuse_reply_err");
}
+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))
+ 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, off, &buf, 0, 1, ".", dir_node->inode, S_IFDIR )
+ || dirbuf_add(req, off, &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, off, &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");
+}
/*
* Define our fuse_lowlevel_ops struct.
@@ -109,6 +173,8 @@
.lookup = simple_lookup,
.getattr = simple_getattr,
+
+ .readdir = simple_readdir,
};
struct fuse_lowlevel_ops *simple_init () {
--- a/src/simple.h Fri Sep 26 20:39:51 2008 +0300
+++ b/src/simple.h Fri Sep 26 21:13:35 2008 +0300
@@ -5,7 +5,7 @@
* A simple static in-memory filesystem structure.
*/
-#include <fuse/fuse_lowlevel.h>
+#include "evfuse.h"
/*
* A simple file/dir.