# HG changeset patch # User Tero Marttila # Date 1224614537 -10800 # Node ID 56427f22e969a0aaa9a64c719c8eb0bae5606ca8 # Parent 4f10421681d264e4a400ca067310ef1aca03cfef tweak debug/info output, implement dbfs_unlink with slightly improved error macros handling diff -r 4f10421681d2 -r 56427f22e969 src/dbfs/attr.c --- a/src/dbfs/attr.c Fri Oct 17 20:12:20 2008 +0300 +++ b/src/dbfs/attr.c Tue Oct 21 21:42:17 2008 +0300 @@ -27,7 +27,7 @@ EERROR(err = EIO, "invalid db data"); - INFO("[dbfs.getattr %p] -> ino=%lu, stat follows", req, (unsigned long int) ino); + INFO("\t[dbfs.getattr %p] -> ino=%lu, stat follows", req, (unsigned long int) ino); // inode st.st_ino = ino; diff -r 4f10421681d2 -r 56427f22e969 src/dbfs/common.c --- a/src/dbfs/common.c Fri Oct 17 20:12:20 2008 +0300 +++ b/src/dbfs/common.c Tue Oct 21 21:42:17 2008 +0300 @@ -49,7 +49,35 @@ return err; } +err_t dbfs_check_result (const struct evsql_result_info *res, size_t rows, size_t cols) { + int err; + // number of rows returned/affected + size_t nrows = evsql_result_rows(res) ? : evsql_result_affected(res); + + // did the query fail outright? + if (res->error) + // dump error message + NXERROR(err = EIO, evsql_result_error(res)); + + // SELECT/DELETE/UPDATE WHERE didn't match any rows -> ENOENT + if (nrows == 0) + XERROR(err = ENOENT, "no rows returned/affected"); + + // duplicate rows where one expected? + if (rows && nrows != rows) + XERROR(err = EIO, "wrong number of rows: %zu -> %zu", rows, nrows); + + // correct number of columns + if (evsql_result_cols(res) != cols) + XERROR(err = EIO, "wrong number of columns: %zu -> %zu", cols, evsql_result_cols(res)); + + // good + return 0; + +error: + return err; +} int _dbfs_stat_info (struct stat *st, const struct evsql_result_info *res, size_t row, size_t col_offset) { int err = 0; diff -r 4f10421681d2 -r 56427f22e969 src/dbfs/core.c --- a/src/dbfs/core.c Fri Oct 17 20:12:20 2008 +0300 +++ b/src/dbfs/core.c Tue Oct 21 21:42:17 2008 +0300 @@ -24,7 +24,7 @@ ) EERROR(err = EIO, "invalid db data"); - INFO("[dbfs.lookup] -> ino=%u", ino); + INFO("\t[dbfs.lookup] -> ino=%u", ino); // stat attrs if ((err = _dbfs_stat_info(&e.attr, res, 0, 1))) diff -r 4f10421681d2 -r 56427f22e969 src/dbfs/dbfs.c --- a/src/dbfs/dbfs.c Fri Oct 17 20:12:20 2008 +0300 +++ b/src/dbfs/dbfs.c Tue Oct 21 21:42:17 2008 +0300 @@ -17,6 +17,7 @@ .readlink = dbfs_readlink, .mknod = dbfs_mknod, .mkdir = dbfs_mkdir, + .unlink = dbfs_unlink, .symlink = dbfs_symlink, .rename = dbfs_rename, diff -r 4f10421681d2 -r 56427f22e969 src/dbfs/dbfs.h --- a/src/dbfs/dbfs.h Fri Oct 17 20:12:20 2008 +0300 +++ b/src/dbfs/dbfs.h Tue Oct 21 21:42:17 2008 +0300 @@ -23,6 +23,9 @@ struct evfuse *ev_fuse; }; +// used for error returns +typedef int err_t; + // XXX: not sure how this should work #define CACHE_TIMEOUT 1.0 @@ -50,6 +53,11 @@ int _dbfs_check_res (const struct evsql_result_info *res, size_t rows, size_t cols); /* + * Same as _dbfs_check_res, but returns ENOENT/EIO directly + */ +err_t dbfs_check_result (const struct evsql_result_info *res, size_t rows, size_t cols); + +/* * Fill a `struct state` with info retrieved from a SQL query. * * The result must contain four columns, starting at the given offset: diff -r 4f10421681d2 -r 56427f22e969 src/dbfs/dirop.c --- a/src/dbfs/dirop.c Fri Oct 17 20:12:20 2008 +0300 +++ b/src/dbfs/dirop.c Tue Oct 21 21:42:17 2008 +0300 @@ -58,7 +58,7 @@ if (_dbfs_mode(type) != S_IFDIR) EERROR(err = ENOTDIR, "wrong type: %s", type); - INFO("[dbfs.opendir %p:%p] -> ino=%lu, parent=%lu, type=%s", dirop, dirop->base.req, (unsigned long int) dirop->base.ino, (unsigned long int) dirop->parent, type); + INFO("\t[dbfs.opendir %p:%p] -> ino=%lu, parent=%lu, type=%s", dirop, dirop->base.req, (unsigned long int) dirop->base.ino, (unsigned long int) dirop->parent, type); // open_fn done, do the open_reply if ((err = dbfs_op_open_reply(&dirop->base))) @@ -88,7 +88,7 @@ assert(dirop->base.req); assert(!dirop->base.open); - INFO("[dbfs.opendir %p:%p] -> trans=%p", dirop, dirop->base.req, dirop->base.trans); + INFO("\t[dbfs.opendir %p:%p] -> trans=%p", dirop, dirop->base.req, dirop->base.trans); // first fetch info about the dir itself const char *sql = @@ -173,7 +173,7 @@ if ((err = _dbfs_check_res(res, 0, 4)) < 0) SERROR(err = EIO); - INFO("[dbfs.readdir %p:%p] -> files: res_rows=%zu", dirop, dirop->base.req, evsql_result_rows(res)); + INFO("\t[dbfs.readdir %p:%p] -> files: res_rows=%zu", dirop, dirop->base.req, evsql_result_rows(res)); // iterate over the rows for (row = 0; row < evsql_result_rows(res); row++) { diff -r 4f10421681d2 -r 56427f22e969 src/dbfs/fileop.c --- a/src/dbfs/fileop.c Fri Oct 17 20:12:20 2008 +0300 +++ b/src/dbfs/fileop.c Tue Oct 21 21:42:17 2008 +0300 @@ -41,7 +41,7 @@ if (_dbfs_mode(type) != S_IFREG) EERROR(err = EINVAL, "wrong type: %s", type); - INFO("[dbfs.open %p:%p] -> ino=%lu, type=%s", fop, fop->base.req, (unsigned long int) fop->base.ino, type); + INFO("\t[dbfs.open %p:%p] -> ino=%lu, type=%s", fop, fop->base.req, (unsigned long int) fop->base.ino, type); // open_fn done, do the open_reply if ((err = dbfs_op_open_reply(&fop->base))) @@ -142,7 +142,7 @@ if (evsql_result_binary(res, 0, 0, &buf, &size, 0)) SERROR(err = EIO); - INFO("[dbfs.read %p:%p] -> size=%zu", fop, fop->base.req, size); + INFO("\t[dbfs.read %p:%p] -> size=%zu", fop, fop->base.req, size); // send it if ((err = fuse_reply_buf(fop->base.req, buf, size))) @@ -221,7 +221,7 @@ if (evsql_result_uint32(res, 0, 0, &size, 0)) SERROR(err = EIO); - INFO("[dbfs.write %p:%p] -> size=%lu", fop, fop->base.req, (long unsigned int) size); + INFO("\t[dbfs.write %p:%p] -> size=%lu", fop, fop->base.req, (long unsigned int) size); // send it if ((err = fuse_reply_write(fop->base.req, size))) diff -r 4f10421681d2 -r 56427f22e969 src/dbfs/link.c --- a/src/dbfs/link.c Fri Oct 17 20:12:20 2008 +0300 +++ b/src/dbfs/link.c Tue Oct 21 21:42:17 2008 +0300 @@ -25,7 +25,7 @@ if (_dbfs_mode(type) != S_IFLNK) EERROR(err = EINVAL, "wrong type: %s", type); - INFO("[dbfs.readlink %p] -> ino=%lu, type=%s, link=%s", req, (unsigned long int) ino, type, link); + INFO("\t[dbfs.readlink %p] -> ino=%lu, type=%s, link=%s", req, (unsigned long int) ino, type, link); // reply if ((err = fuse_reply_readlink(req, link))) @@ -78,3 +78,65 @@ } +#define SETERR(err_var, err_val, bool_val) ((err_var) = bool_val ? (err_val) : 0) + +void dbfs_unlink_res (const struct evsql_result_info *res, void *arg) { + struct fuse_req *req = arg; + int err = 0; + + // check the results + if ((err = dbfs_check_result(res, 1, 0))) + goto error; + + INFO("\t[dbfs.unlink %p] -> OK", req); + + // reply + if ((err = fuse_reply_err(req, 0))) + EERROR(err, "fuse_reply_readlink"); + +error: + if (err && (err = fuse_reply_err(req, err))) + EWARNING(err, "fuse_reply_err"); + + // free + evsql_result_free(res); +} + +void dbfs_unlink (struct fuse_req *req, fuse_ino_t parent, const char *name) { + struct dbfs *ctx = fuse_req_userdata(req); + int err; + + INFO("[dbfs.unlink %p] parent=%lu, name=%s", req, parent, name); + + const char *sql = + "DELETE" + " FROM file_tree" + " WHERE parent = $1::int4 AND name = $2::varchar"; + + static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) { + EVSQL_PARAM ( UINT32 ), + EVSQL_PARAM ( STRING ), + + EVSQL_PARAMS_END + }; + + // build params + if (SETERR(err, (0 + || evsql_param_uint32(¶ms, 0, parent) + || evsql_param_string(¶ms, 1, name) + ), EIO)) + goto error; + + // query + if (SETERR(err, evsql_query_params(ctx->db, NULL, sql, ¶ms, dbfs_unlink_res, req) == NULL, EIO)) + goto error; + + // XXX: handle interrupts + + // wait + return; + +error: + if ((err = fuse_reply_err(req, err))) + EWARNING(err, "fuse_reply_err"); +} diff -r 4f10421681d2 -r 56427f22e969 src/dbfs/ops.h --- a/src/dbfs/ops.h Fri Oct 17 20:12:20 2008 +0300 +++ b/src/dbfs/ops.h Tue Oct 21 21:42:17 2008 +0300 @@ -16,6 +16,7 @@ /* link.c */ void dbfs_readlink (struct fuse_req *req, fuse_ino_t ino); +void dbfs_unlink (struct fuse_req *req, fuse_ino_t parent, const char *name); /* dirop.c */ void dbfs_opendir (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi); diff -r 4f10421681d2 -r 56427f22e969 src/evsql/evsql.c --- a/src/evsql/evsql.c Fri Oct 17 20:12:20 2008 +0300 +++ b/src/evsql/evsql.c Tue Oct 21 21:42:17 2008 +0300 @@ -23,6 +23,8 @@ static int _evsql_query_exec (struct evsql_conn *conn, struct evsql_query *query, const char *command) { int err; + DEBUG("evsql.%p: exec query=%p on trans=%p on conn=%p:", conn->evsql, query, conn->trans, conn); + switch (conn->evsql->type) { case EVSQL_EVPQ: // got params? @@ -890,6 +892,12 @@ if (_evsql_query_enqueue(evsql, trans, query, command)) goto error; +#ifdef DEBUG_ENABLED + // debug it? + DEBUG("evsql.%p: enqueued query=%p on trans=%p", evsql, query, trans); + evsql_query_debug(command, params); +#endif /* DEBUG_ENABLED */ + // ok return query; diff -r 4f10421681d2 -r 56427f22e969 src/lib/error.h --- a/src/lib/error.h Fri Oct 17 20:12:20 2008 +0300 +++ b/src/lib/error.h Tue Oct 21 21:42:17 2008 +0300 @@ -8,6 +8,8 @@ #define EERROR(_err, ...) do { eerr_func(__func__, (_err), __VA_ARGS__); goto error; } while (0) #define NERROR(...) do { err_func_nonl(__func__, __VA_ARGS__); goto error; } while (0) #define SERROR(_err) do { (_err); goto error; } while (0) +#define XERROR(_err, ...) do { (_err); err_func(__func__, __VA_ARGS__); goto error; } while (0) +#define NXERROR(_err, ...) do { (_err); err_func_nonl(__func__, __VA_ARGS__); goto error; } while (0) // XXX: replace with *err_func(...) + exit(EXIT_FAILURE) #define FATAL(...) err_func_exit(__func__, __VA_ARGS__)