# HG changeset patch # User Tero Marttila # Date 1226966113 -7200 # Node ID 6abda2fa457918e65d165f3e84c8597f015fab95 # Parent 03017f5f0087318aa91d9194cc2aba70424313a2 touch up the Makefile, define err_t as unsigned int in error.h, and add some preliminary interrupt support, although it will always deadlock due to a bug in libfuse diff -r 03017f5f0087 -r 6abda2fa4579 Makefile --- a/Makefile Wed Oct 22 21:07:17 2008 +0300 +++ b/Makefile Tue Nov 18 01:55:13 2008 +0200 @@ -5,31 +5,34 @@ INCLUDE_PATHS = -I${LIBEVENT_PATH}/include -I${LIBFUSE_PATH}/include LDLIBS = -levent -lfuse -lpq -# default is TEST +# default is test ifndef MODE -MODE = TEST +MODE = test endif -ifeq ($(MODE), DEBUG) +ifeq ($(MODE), debug) MODE_CFLAGS = -g -DDEBUG_ENABLED -else ifeq ($(MODE), DEV) +else ifeq ($(MODE), dev) MODE_CFLAGS = -g -else ifeq ($(MODE), TEST) +else ifeq ($(MODE), test) MODE_CFLAGS = -g -DINFO_DISABLED -else ifeq ($(MODE), RELEASE) +else ifeq ($(MODE), release) MODE_CFLAGS = -DINFO_DISABLED -O2 endif # XXX: ugh... use `pkg-config fuse` DEFINES = -D_FILE_OFFSET_BITS=64 -MY_CFLAGS = -Wall -std=gnu99 $(MODE_CFLAGS) +FIXED_CFLAGS = -Wall -std=gnu99 BIN_NAMES = helloworld hello simple_hello evpq_test url_test dbfs BIN_PATHS = $(addprefix bin/,$(BIN_NAMES)) +# modules +module_objs = $(patsubst src/%.c,obj/%.o,$(wildcard src/$(1)/*.c)) + # complex modules -EVSQL_OBJS = obj/evsql/evsql.o obj/evsql/util.o obj/evpq.o -DBFS_OBJS = obj/dbfs/dbfs.o obj/dbfs/common.o obj/dbfs/op_base.o obj/dbfs/trans.o obj/dbfs/dirop.o obj/dirbuf.o obj/dbfs/fileop.o obj/dbfs/attr.o obj/dbfs/link.o obj/dbfs/tree.o obj/dbfs/mk.o +EVSQL_OBJS = $(call module_objs,evsql) obj/evpq.o +DBFS_OBJS = $(call module_objs,dbfs) obj/dirbuf.o # first target all: ${BIN_PATHS} @@ -43,9 +46,10 @@ bin/dbfs: ${DBFS_OBJS} ${EVSQL_OBJS} obj/evfuse.o obj/lib/log.o obj/lib/signals.o # computed -LDFLAGS = ${LIBRARY_PATHS} ${LIBRARY_LIST} -CFLAGSX = ${DEFINES} ${MY_CFLAGS} -CFLAGS = ${INCLUDE_PATHS} ${CFLAGSX} +LDFLAGS = ${LIBRARY_PATHS} + +CPPFLAGS = ${INCLUDE_PATHS} ${DEFINES} +CFLAGS = ${MODE_CFLAGS} ${FIXED_CFLAGS} SRC_PATHS = $(wildcard src/*.c) $(wildcard src/*/*.c) SRC_NAMES = $(patsubst src/%,%,$(SRC_PATHS)) diff -r 03017f5f0087 -r 6abda2fa4579 src/dbfs/attr.c --- a/src/dbfs/attr.c Wed Oct 22 21:07:17 2008 +0300 +++ b/src/dbfs/attr.c Tue Nov 18 01:55:13 2008 +0200 @@ -50,6 +50,7 @@ void dbfs_getattr (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi) { struct dbfs *ctx = fuse_req_userdata(req); + struct evsql_query *query; int err; (void) fi; @@ -75,10 +76,11 @@ SERROR(err = EIO); // query - if (evsql_query_params(ctx->db, NULL, sql, ¶ms, _dbfs_attr_res, req) == NULL) + if ((query = evsql_query_params(ctx->db, NULL, sql, ¶ms, _dbfs_attr_res, req)) == NULL) SERROR(err = EIO); - // XXX: handle interrupts + // handle interrupts + fuse_req_interrupt_func(req, dbfs_interrupt_query, query); // wait return; @@ -91,6 +93,7 @@ void dbfs_setattr (struct fuse_req *req, fuse_ino_t ino, struct stat *attr, int to_set, struct fuse_file_info *fi) { struct dbfs *ctx = fuse_req_userdata(req); + struct evsql_query *query; int err; int ret; @@ -160,10 +163,11 @@ evsql_query_debug(sql_buf, ¶ms); // query... we can pretend it's a getattr :) - if (evsql_query_params(ctx->db, NULL, sql_buf, ¶ms, _dbfs_attr_res, req) == NULL) + if ((query = evsql_query_params(ctx->db, NULL, sql_buf, ¶ms, _dbfs_attr_res, req)) == NULL) SERROR(err = EIO); - // XXX: handle interrupts + // handle interrupts + fuse_req_interrupt_func(req, dbfs_interrupt_query, query); // wait return; diff -r 03017f5f0087 -r 6abda2fa4579 src/dbfs/common.c --- a/src/dbfs/common.c Wed Oct 22 21:07:17 2008 +0300 +++ b/src/dbfs/common.c Tue Nov 18 01:55:13 2008 +0200 @@ -50,7 +50,7 @@ } err_t dbfs_check_result (const struct evsql_result_info *res, size_t rows, size_t cols) { - int err; + err_t err; // number of rows returned/affected size_t nrows = evsql_result_rows(res) ? : evsql_result_affected(res); diff -r 03017f5f0087 -r 6abda2fa4579 src/dbfs/dbfs.h --- a/src/dbfs/dbfs.h Wed Oct 22 21:07:17 2008 +0300 +++ b/src/dbfs/dbfs.h Tue Nov 18 01:55:13 2008 +0200 @@ -9,6 +9,7 @@ #include "ops.h" #include "../evfuse.h" #include "../evsql.h" +#include "../lib/error.h" /* * Structs and functions shared between all dbfs components @@ -23,9 +24,6 @@ struct evfuse *ev_fuse; }; -// used for error returns -typedef int err_t; - // XXX: not sure how this should work #define CACHE_TIMEOUT 1.0 @@ -67,4 +65,43 @@ */ int _dbfs_stat_info (struct stat *st, const struct evsql_result_info *res, size_t row, size_t col_offset); +/** interrupt.c + * + * Fuse interrupts are handled using fuse_req_interrupt_func. Calling this registers a callback function with the req, + * which may or may not be called either by fuse_req_interrupt_func, or later on via evfuse's event handler. It is + * assumed that this will never be called after a call to fuse_reply_*. + * + * Hence, to handle an interrupt, we must first ensure that fuse_reply_* will not be called afterwards (it'll return + * an error), and then we must call fuse_reply_err(req, EINTR). + * + * In the simplest case, we can simply submit a query, and then abort it once the req is interrupted (now or later). + * In the more complicated case, we can check if the request was interrupted, if not, do the query and handle + * interrupts. + */ + +/* + * Useable as a callback to fuse_req_interrupt_func, will abort the given query and err the req. + */ +void dbfs_interrupt_query (struct fuse_req *req, void *query_ptr); + +/* + * XXX: More complicated state, is this actually needed? + */ +struct dbfs_interrupt_ctx { + struct fuse_req *req; + struct evsql_query *query; + + int interrupted : 1; +}; + +/* + * Register as a fuse interrupt function for simple requests that only run one query without allocating any resources. + * + * This will abort the query if the interrupt is run, causing it's callback to not be called. + * + * Returns nonzero if the request was already interrupted, zero otherwise. Be careful that the interrupt does not get + * fired between you checking for it and setting query. + */ +int dbfs_interrupt_register (struct fuse_req *req, struct dbfs_interrupt_ctx *ctx); + #endif /* DBFS_DBFS_H */ diff -r 03017f5f0087 -r 6abda2fa4579 src/dbfs/interrupt.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dbfs/interrupt.c Tue Nov 18 01:55:13 2008 +0200 @@ -0,0 +1,37 @@ + +#include "dbfs.h" + +void dbfs_interrupt_query (struct fuse_req *req, void *query_ptr) { + struct evsql_query *query = query_ptr; + err_t err; + + // abort + evsql_query_abort(NULL, query); + + // error the req + if ((err = -fuse_reply_err(req, EINTR))) + PWARNING("fuse_reply_err", err); +} + +void _dbfs_interrupt_ctx (struct fuse_req *req, void *ctx_ptr) { + // dereference ctx + struct dbfs_interrupt_ctx *ctx = ctx_ptr; + + // just cancel query if pending + if (ctx->query) { + evsql_query_abort(NULL, ctx->query); + ctx->query = NULL; + } + + // mark as interrupted + ctx->interrupted = 1; +} + +int dbfs_interrupt_register (struct fuse_req *req, struct dbfs_interrupt_ctx *ctx) { + // initialize + ctx->query = NULL; + ctx->interrupted = 0; + + // just pass over to fuse_req_interrupt_func + fuse_req_interrupt_func(req, _dbfs_interrupt_ctx, ctx); +} diff -r 03017f5f0087 -r 6abda2fa4579 src/dbfs/link.c --- a/src/dbfs/link.c Wed Oct 22 21:07:17 2008 +0300 +++ b/src/dbfs/link.c Tue Nov 18 01:55:13 2008 +0200 @@ -52,6 +52,7 @@ void dbfs_lookup (struct fuse_req *req, fuse_ino_t parent, const char *name) { struct dbfs *ctx = fuse_req_userdata(req); + struct evsql_query *query; int err; INFO("[dbfs.lookup] parent=%lu name=%s", parent, name); @@ -78,10 +79,11 @@ EERROR(err = EIO, "evsql_param_*"); // query - if (evsql_query_params(ctx->db, NULL, sql, ¶ms, dbfs_entry_res, req) == NULL) + if ((query = evsql_query_params(ctx->db, NULL, sql, ¶ms, dbfs_entry_res, req)) == NULL) EERROR(err = EIO, "evsql_query_params"); - // XXX: handle interrupts + // handle interrupts + fuse_req_interrupt_func(req, dbfs_interrupt_query, query); // wait return; @@ -130,6 +132,7 @@ void dbfs_readlink (struct fuse_req *req, fuse_ino_t ino) { struct dbfs *ctx = fuse_req_userdata(req); + struct evsql_query *query; int err; INFO("[dbfs.readlink %p] ino=%lu", req, ino); @@ -153,10 +156,11 @@ SERROR(err = EIO); // query - if (evsql_query_params(ctx->db, NULL, sql, ¶ms, _dbfs_readlink_res, req) == NULL) + if ((query = evsql_query_params(ctx->db, NULL, sql, ¶ms, _dbfs_readlink_res, req)) == NULL) SERROR(err = EIO); - // XXX: handle interrupts + // handle interrupts + fuse_req_interrupt_func(req, dbfs_interrupt_query, query); // wait return; @@ -194,6 +198,7 @@ void dbfs_unlink (struct fuse_req *req, fuse_ino_t parent, const char *name) { struct dbfs *ctx = fuse_req_userdata(req); + struct evsql_query *query; int err; INFO("[dbfs.unlink %p] parent=%lu, name=%s", req, parent, name); @@ -211,17 +216,18 @@ }; // build params - if (SETERR(err, (0 + if (0 || evsql_param_uint32(¶ms, 0, parent) || evsql_param_string(¶ms, 1, name) - ), EIO)) - goto error; + ) + SERROR(err = EIO); // query - if (SETERR(err, evsql_query_params(ctx->db, NULL, sql, ¶ms, dbfs_unlink_res, req) == NULL, EIO)) - goto error; + if ((query = evsql_query_params(ctx->db, NULL, sql, ¶ms, dbfs_unlink_res, req)) == NULL) + SERROR(err = EIO); - // XXX: handle interrupts + // handle interrupts + fuse_req_interrupt_func(req, dbfs_interrupt_query, query); // wait return; @@ -233,6 +239,7 @@ void dbfs_link (struct fuse_req *req, fuse_ino_t ino, fuse_ino_t newparent, const char *newname) { struct dbfs *ctx = fuse_req_userdata(req); + struct evsql_query *query; int err; INFO("[dbfs.link %p] ino=%lu, newparent=%lu, newname=%s", req, ino, newparent, newname); @@ -257,10 +264,11 @@ SERROR(err = EIO); // query - if (evsql_query_params(ctx->db, NULL, sql, ¶ms, dbfs_entry_res, req) == NULL) + if ((query = evsql_query_params(ctx->db, NULL, sql, ¶ms, dbfs_entry_res, req)) == NULL) SERROR(err = EIO); - // XXX: handle interrupts + // handle interrupts + fuse_req_interrupt_func(req, dbfs_interrupt_query, query); // wait return; diff -r 03017f5f0087 -r 6abda2fa4579 src/lib/error.h --- a/src/lib/error.h Wed Oct 22 21:07:17 2008 +0300 +++ b/src/lib/error.h Tue Nov 18 01:55:13 2008 +0200 @@ -3,6 +3,11 @@ #include "log.h" +/* + * err_t is always positive + */ +typedef unsigned int err_t; + #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)