terom@28: terom@31: #include "dbfs.h" terom@29: #include "../lib/log.h" terom@29: #include "../lib/misc.h" terom@29: terom@28: /* terom@28: * Core fs functionality like lookup, getattr terom@28: */ terom@28: terom@28: void _dbfs_lookup_result (const struct evsql_result_info *res, void *arg) { terom@28: struct fuse_req *req = arg; terom@28: struct fuse_entry_param e; ZINIT(e); terom@28: int err = 0; terom@28: terom@28: uint32_t ino; terom@28: terom@28: // check the results terom@28: if ((err = _dbfs_check_res(res, 1, 5))) terom@28: SERROR(err = (err == 1 ? ENOENT : EIO)); terom@28: terom@28: // get the data terom@28: if (0 terom@28: || evsql_result_uint32(res, 0, 0, &ino, 0 ) // inodes.ino terom@28: ) terom@28: EERROR(err = EIO, "invalid db data"); terom@28: terom@28: INFO("[dbfs.lookup] -> ino=%u", ino); terom@28: terom@28: // stat attrs terom@31: if ((err = _dbfs_stat_info(&e.attr, res, 0, 1))) terom@28: goto error; terom@28: terom@28: // other attrs terom@28: e.ino = e.attr.st_ino = ino; terom@28: e.attr_timeout = CACHE_TIMEOUT; terom@28: e.entry_timeout = CACHE_TIMEOUT; terom@28: terom@28: // reply terom@28: if ((err = fuse_reply_entry(req, &e))) terom@28: EERROR(err, "fuse_reply_entry"); terom@28: terom@28: error: terom@28: if (err && (err = fuse_reply_err(req, err))) terom@28: EWARNING(err, "fuse_reply_err"); terom@28: terom@28: // free terom@28: evsql_result_free(res); terom@28: } terom@28: terom@28: void dbfs_lookup (struct fuse_req *req, fuse_ino_t parent, const char *name) { terom@28: struct dbfs *ctx = fuse_req_userdata(req); terom@28: int err; terom@28: terom@28: INFO("[dbfs.lookup] parent=%lu name=%s", parent, name); terom@28: terom@28: // query and params terom@28: const char *sql = terom@28: "SELECT" terom@31: " inodes.ino, " DBFS_STAT_COLS terom@33: " FROM file_tree INNER JOIN inodes ON (file_tree.ino = inodes.ino)" terom@33: " WHERE file_tree.parent = $1::int4 AND file_tree.name = $2::varchar"; terom@28: terom@28: static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) { terom@28: EVSQL_PARAM ( UINT32 ), terom@28: EVSQL_PARAM ( STRING ), terom@28: terom@28: EVSQL_PARAMS_END terom@28: }; terom@28: terom@28: // build params terom@28: if (0 terom@28: || evsql_param_uint32(¶ms, 0, parent) terom@28: || evsql_param_string(¶ms, 1, name) terom@28: ) terom@28: EERROR(err = EIO, "evsql_param_*"); terom@28: terom@28: // query terom@28: if (evsql_query_params(ctx->db, NULL, sql, ¶ms, _dbfs_lookup_result, req) == NULL) terom@28: EERROR(err = EIO, "evsql_query_params"); terom@28: terom@28: // XXX: handle interrupts terom@28: terom@28: // wait terom@28: return; terom@28: terom@28: error: terom@28: if ((err = fuse_reply_err(req, err))) terom@28: EWARNING(err, "fuse_reply_err"); terom@28: } terom@28: