1 #ifndef DBFS_DBFS_H |
|
2 #define DBFS_DBFS_H |
|
3 |
|
4 #include <sys/stat.h> |
|
5 #include <errno.h> |
|
6 |
|
7 #include <event2/event.h> |
|
8 |
|
9 #include "ops.h" |
|
10 #include "../evfuse.h" |
|
11 #include "../evsql.h" |
|
12 #include "../lib/error.h" |
|
13 |
|
14 /* |
|
15 * Structs and functions shared between all dbfs components |
|
16 */ |
|
17 |
|
18 struct dbfs { |
|
19 struct event_base *ev_base; |
|
20 |
|
21 const char *db_conninfo; |
|
22 struct evsql *db; |
|
23 |
|
24 struct evfuse *ev_fuse; |
|
25 }; |
|
26 |
|
27 // XXX: not sure how this should work |
|
28 #define CACHE_TIMEOUT 1.0 |
|
29 |
|
30 // columns used for stat_info |
|
31 #define DBFS_STAT_COLS " inodes.type, inodes.mode, dbfs_size(inodes.type, inodes.data, inodes.link_path), (SELECT COUNT(*) FROM inodes i LEFT JOIN file_tree ft ON (i.ino = ft.ino) WHERE i.ino = inodes.ino) AS nlink" |
|
32 |
|
33 /* |
|
34 * Convert the CHAR(4) inodes.type from SQL into a mode_t. |
|
35 * |
|
36 * Returns zero for unknown types. |
|
37 */ |
|
38 mode_t _dbfs_mode (const char *type); |
|
39 |
|
40 /* |
|
41 * Check that the number of rows and columns in the result set matches what we expect. |
|
42 * |
|
43 * If rows is nonzero, there must be exactly that many rows (mostly useful for rows=1). |
|
44 * The number of columns must always be given, and match. |
|
45 * |
|
46 * Returns; |
|
47 * -1 if the query failed, the columns/rows do not match |
|
48 * 0 the results match |
|
49 * 1 there were no results (zero rows) |
|
50 */ |
|
51 int _dbfs_check_res (const struct evsql_result_info *res, size_t rows, size_t cols); |
|
52 |
|
53 /* |
|
54 * Same as _dbfs_check_res, but returns ENOENT/EIO directly |
|
55 */ |
|
56 err_t dbfs_check_result (const struct evsql_result_info *res, size_t rows, size_t cols); |
|
57 |
|
58 /* |
|
59 * Fill a `struct state` with info retrieved from a SQL query. |
|
60 * |
|
61 * The result must contain four columns, starting at the given offset: |
|
62 * inodes.type, inodes.mode, inodes.size, count(*) AS nlink |
|
63 * |
|
64 * Note that this does not fill the st_ino field |
|
65 */ |
|
66 int _dbfs_stat_info (struct stat *st, const struct evsql_result_info *res, size_t row, size_t col_offset); |
|
67 |
|
68 /** interrupt.c |
|
69 * |
|
70 * Fuse interrupts are handled using fuse_req_interrupt_func. Calling this registers a callback function with the req, |
|
71 * which may or may not be called either by fuse_req_interrupt_func, or later on via evfuse's event handler. It is |
|
72 * assumed that this will never be called after a call to fuse_reply_*. |
|
73 * |
|
74 * Hence, to handle an interrupt, we must first ensure that fuse_reply_* will not be called afterwards (it'll return |
|
75 * an error), and then we must call fuse_reply_err(req, EINTR). |
|
76 * |
|
77 * In the simplest case, we can simply submit a query, and then abort it once the req is interrupted (now or later). |
|
78 * In the more complicated case, we can check if the request was interrupted, if not, do the query and handle |
|
79 * interrupts. |
|
80 */ |
|
81 |
|
82 /* |
|
83 * Useable as a callback to fuse_req_interrupt_func, will abort the given query and err the req. |
|
84 * |
|
85 * Due to a locking bug in libfuse 2.7.4, this will actually delay the fuse_req_err until the next event-loop iteration. |
|
86 */ |
|
87 void dbfs_interrupt_query (struct fuse_req *req, void *query_ptr); |
|
88 |
|
89 /* |
|
90 * XXX: More complicated state, is this actually needed? |
|
91 */ |
|
92 struct dbfs_interrupt_ctx { |
|
93 struct fuse_req *req; |
|
94 struct evsql_query *query; |
|
95 |
|
96 int interrupted : 1; |
|
97 }; |
|
98 |
|
99 /* |
|
100 * Register as a fuse interrupt function for simple requests that only run one query without allocating any resources. |
|
101 * |
|
102 * This will abort the query if the interrupt is run, causing it's callback to not be called. |
|
103 * |
|
104 * Returns nonzero if the request was already interrupted, zero otherwise. Be careful that the interrupt does not get |
|
105 * fired between you checking for it and setting query. |
|
106 */ |
|
107 int dbfs_interrupt_register (struct fuse_req *req, struct dbfs_interrupt_ctx *ctx); |
|
108 |
|
109 #endif /* DBFS_DBFS_H */ |
|