# HG changeset patch # User Tero Marttila # Date 1222450791 -10800 # Node ID 3a603d755bcbdeea473223f32d59510dd519cc9f # Parent d2036d7799fdc6f3b13bb55811444fb7683fe0dc split off the dirbuf stuff into its own module diff -r d2036d7799fd -r 3a603d755bcb Makefile --- a/Makefile Fri Sep 26 20:11:22 2008 +0300 +++ b/Makefile Fri Sep 26 20:39:51 2008 +0300 @@ -12,8 +12,8 @@ BIN_NAMES = hello helloworld bin/helloworld: -bin/hello: obj/evfuse.o obj/lib/log.o obj/lib/signals.o -bin/simple_hello: obj/evfuse.o obj/lib/log.o obj/lib/signals.o obj/simple.o +bin/hello: obj/evfuse.o obj/dirbuf.o obj/lib/log.o obj/lib/signals.o +bin/simple_hello: obj/evfuse.o obj/dirbuf.o obj/lib/log.o obj/lib/signals.o obj/simple.o # computed LDFLAGS = ${LIBRARY_PATHS} ${LIBRARY_LIST} diff -r d2036d7799fd -r 3a603d755bcb src/dirbuf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dirbuf.c Fri Sep 26 20:39:51 2008 +0300 @@ -0,0 +1,68 @@ + +#include + +#include "dirbuf.h" +#include "lib/log.h" +#include "lib/math.h" + +int dirbuf_init (struct dirbuf *buf, size_t req_size) { + buf->len = req_size; + buf->off = 0; + + INFO("\tdirbuf.init: req_size=%zu", req_size); + + // allocate the mem + if ((buf->buf = malloc(buf->len)) == NULL) + ERROR("malloc"); + + // ok + return 0; + +error: + return -1; +} + +int dirbuf_add (fuse_req_t req, off_t req_off, struct dirbuf *buf, off_t ent_off, off_t next_off, const char *ent_name, fuse_ino_t ent_ino, mode_t ent_mode) { + struct stat stbuf; + size_t ent_size; + + INFO("\tdirbuf.add: req_off=%zu, buf->len=%zu, buf->off=%zu, ent_off=%zu, next_off=%zu, ent_name=`%s`, ent_ino=%lu, ent_mode=%07o", + req_off, buf->len, buf->off, ent_off, next_off, ent_name, ent_ino, ent_mode); + + // skip entries as needed + if (ent_off < req_off) + return 0; + + // set ino + stbuf.st_ino = ent_ino; + stbuf.st_mode = ent_mode; + + // try and add the dirent, and see if it fits + if ((ent_size = fuse_add_direntry(req, buf->buf + buf->off, buf->len - buf->off, ent_name, &stbuf, next_off)) > (buf->len - buf->off)) { + // 'tis full + return 1; + + } else { + // it fit + buf->off += ent_size; + } + + // success + return 0; +} + +int dirbuf_done (fuse_req_t req, struct dirbuf *buf) { + int err; + + // send the reply, return the error later + err = fuse_reply_buf(req, buf->buf, buf->off); + + INFO("\tdirbuf.done: size=%zu/%zu, err=%d", buf->off, buf->len, err); + + // free the dirbuf + free(buf->buf); + + // return the error code + return err; +} + diff -r d2036d7799fd -r 3a603d755bcb src/dirbuf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dirbuf.h Fri Sep 26 20:39:51 2008 +0300 @@ -0,0 +1,44 @@ +#ifndef DIRBUF_H +#define DIRBUF_H + +/* + * Simple dirent building + */ + +#include "evfuse.h" + +/* + * Holds the dir entries + */ +struct dirbuf { + char *buf; + size_t len; + size_t off; +}; + + +/* + * Initialize a dirbuf for a request. The dirbuf will be filled with at most req_size bytes of dir entries. + */ +int dirbuf_init (struct dirbuf *buf, size_t req_size); + +/* + * Add an dir entry to the dirbuf. The dirbuf should not be full. + * + * Offsets are followed: + * req_off - the offset of the first dirent to include + * ent_off - the offset of this dirent + * next_off - the offset of the next dirent + * + * Only the S_IFMT bits of ent_mode are relevant. + * + * Returns 0 if the ent was added or skipped, -1 on error, 1 if the dirbuf is full (no more ents should be added). + */ +int dirbuf_add (fuse_req_t req, off_t req_off, struct dirbuf *buf, off_t ent_off, off_t next_off, const char *ent_name, fuse_ino_t ent_ino, mode_t ent_mode); + +/* + * Attempt to send the readdir reply, free the buf, and return the error code from fuse_reply_buf + */ +int dirbuf_done (fuse_req_t req, struct dirbuf *buf); + +#endif /* DIRBUF_H */ diff -r d2036d7799fd -r 3a603d755bcb src/hello.c --- a/src/hello.c Fri Sep 26 20:11:22 2008 +0300 +++ b/src/hello.c Fri Sep 26 20:39:51 2008 +0300 @@ -9,6 +9,7 @@ #include "lib/math.h" #include "lib/signals.h" #include "evfuse.h" +#include "dirbuf.h" const char *file_name = "hello"; const char *file_data = "Hello World\n"; @@ -81,73 +82,6 @@ fuse_reply_attr(req, &stbuf, 1.0); } -struct dirbuf { - char *buf; - size_t len; - size_t off; -}; - -static int dirbuf_init (struct dirbuf *buf, size_t req_size) { - buf->len = req_size; - buf->off = 0; - - // allocate the mem - if ((buf->buf = malloc(buf->len)) == NULL) - ERROR("malloc"); - - // ok - return 0; - -error: - return -1; -} - -/* - * Add an ent to the dirbuf. This will assume that the dirbuf is not already full - * Returns 0 if the ent was added or skipped, -1 on error, 1 if the dirbuf is full - */ -static int dirbuf_add (fuse_req_t req, size_t req_size, off_t req_off, struct dirbuf *buf, off_t ent_off, off_t next_off, const char *ent_name, fuse_ino_t ent_ino) { - struct stat stbuf; - size_t ent_size; - - INFO("\thello.dirbuf_add: req_size=%zu, req_off=%zu, buf->len=%zu, buf->off=%zu, ent_off=%zu, next_off=%zu, ent_name=`%s`, ent_ino=%lu", - req_size, req_off, buf->len, buf->off, ent_off, next_off, ent_name, ent_ino); - - // skip entries as needed - if (ent_off < req_off) - return 0; - - // set ino - stbuf.st_ino = ent_ino; - - // add the dirent and update dirbuf until it fits - if ((ent_size = fuse_add_direntry(req, buf->buf + buf->off, buf->len - buf->off, ent_name, &stbuf, next_off)) > (buf->len - buf->off)) { - // 'tis full - return 1; - - } else { - // it fit - buf->off += ent_size; - } - - // success - return 0; -} - -static int dirbuf_done (fuse_req_t req, struct dirbuf *buf, size_t req_size) { - int err; - - // send the reply, return the error later - err = fuse_reply_buf(req, buf->buf, MIN(buf->off, req_size)); - - INFO("\thello.dirbuf_done: MIN(%zu, %zu)=%zu, err=%d", buf->off, req_size, MIN(buf->off, req_size), err); - - // free the dirbuf - free(buf->buf); - - // return the error code - return err; -} void hello_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) { int err = 0; @@ -165,15 +99,15 @@ if (dirbuf_init(&buf, size)) ERROR("failed to init dirbuf"); - err = dirbuf_add(req, size, off, &buf, 0, 1, ".", 1) - || dirbuf_add(req, size, off, &buf, 1, 2, "..", 1) - || dirbuf_add(req, size, off, &buf, 2, 3, file_name, 2); + err = dirbuf_add(req, off, &buf, 0, 1, ".", 1, S_IFDIR ) + || dirbuf_add(req, off, &buf, 1, 2, "..", 1, S_IFDIR ) + || dirbuf_add(req, off, &buf, 2, 3, file_name, 2, S_IFREG ); if (err < 0) ERROR("failed to add dirents to buf"); // send it - if ((err = -dirbuf_done(req, &buf, size))) + if ((err = -dirbuf_done(req, &buf))) EERROR(-err, "failed to send buf"); // success