| author | Tero Marttila <terom@fixme.fi> |
| Mon, 13 Oct 2008 02:27:59 +0300 | |
| changeset 27 | 461be4cd34a3 |
| parent 26 | 61668c57f4bb |
| child 28 | e944453ca924 |
| permissions | -rw-r--r-- |
| 24 | 1 |
|
2 |
/* |
|
3 |
* A simple PostgreSQL-based filesystem. |
|
4 |
*/ |
|
5 |
||
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
6 |
#include <stdlib.h> |
| 24 | 7 |
#include <string.h> |
8 |
#include <errno.h> |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
9 |
#include <assert.h> |
| 24 | 10 |
|
11 |
#include <event2/event.h> |
|
12 |
||
13 |
#include "evfuse.h" |
|
14 |
#include "evsql.h" |
|
15 |
#include "dirbuf.h" |
|
16 |
#include "lib/log.h" |
|
17 |
#include "lib/signals.h" |
|
18 |
#include "lib/misc.h" |
|
19 |
||
20 |
#define SERROR(val) do { (val); goto error; } while(0)
|
|
21 |
||
22 |
struct dbfs {
|
|
23 |
struct event_base *ev_base; |
|
24 |
struct signals *signals; |
|
25 |
||
26 |
const char *db_conninfo; |
|
27 |
struct evsql *db; |
|
28 |
||
29 |
struct evfuse *ev_fuse; |
|
30 |
}; |
|
31 |
||
32 |
#define CONNINFO_DEFAULT "dbname=test" |
|
33 |
||
34 |
// XXX: not sure how this should work |
|
35 |
#define CACHE_TIMEOUT 1.0 |
|
36 |
||
37 |
mode_t _dbfs_mode (const char *type) {
|
|
38 |
if (!strcmp(type, "DIR")) |
|
39 |
return S_IFDIR; |
|
40 |
||
41 |
if (!strcmp(type, "REG")) |
|
42 |
return S_IFREG; |
|
43 |
||
44 |
else {
|
|
45 |
WARNING("[dbfs] weird mode-type: %s", type);
|
|
46 |
return 0; |
|
47 |
} |
|
48 |
} |
|
49 |
||
50 |
void dbfs_init (void *userdata, struct fuse_conn_info *conn) {
|
|
51 |
INFO("[dbfs.init] userdata=%p, conn=%p", userdata, conn);
|
|
52 |
||
53 |
} |
|
54 |
||
| 27 | 55 |
void dbfs_destroy (void *arg) {
|
56 |
struct dbfs *ctx = arg; |
|
57 |
INFO("[dbfs.destroy %p]", ctx);
|
|
| 24 | 58 |
|
| 27 | 59 |
// exit libevent |
60 |
event_base_loopexit(ctx->ev_base, NULL); |
|
| 24 | 61 |
} |
62 |
||
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
63 |
/* |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
64 |
* Check the result set. |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
65 |
* |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
66 |
* Returns; |
| 27 | 67 |
* -1 if the query failed, the columns do not match, or there are too many/few rows (unless rows was zero) |
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
68 |
* 0 the results match |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
69 |
* 1 there were no results |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
70 |
*/ |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
71 |
int _dbfs_check_res (const struct evsql_result_info *res, size_t rows, size_t cols) {
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
72 |
int err = 0; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
73 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
74 |
// check if it failed |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
75 |
if (res->error) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
76 |
NERROR(evsql_result_error(res)); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
77 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
78 |
// not found? |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
79 |
if (evsql_result_rows(res) == 0) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
80 |
SERROR(err = 1); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
81 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
82 |
// duplicate rows? |
| 27 | 83 |
if (rows && evsql_result_rows(res) != rows) |
84 |
ERROR("wrong number of rows returned");
|
|
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
85 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
86 |
// correct number of columns |
| 27 | 87 |
if (evsql_result_cols(res) != cols) |
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
88 |
ERROR("wrong number of columns: %zu", evsql_result_cols(res));
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
89 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
90 |
// good |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
91 |
return 0; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
92 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
93 |
error: |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
94 |
if (!err) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
95 |
err = -1; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
96 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
97 |
return err; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
98 |
} |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
99 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
100 |
int _dbfs_stat_info (struct stat *st, const struct evsql_result_info *res, size_t row, size_t col_offset) {
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
101 |
int err = 0; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
102 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
103 |
uint16_t mode; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
104 |
uint64_t size, nlink; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
105 |
const char *type; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
106 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
107 |
// extract the data |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
108 |
if (0 |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
109 |
|| evsql_result_string(res, row, col_offset + 0, &type, 0 ) // inodes.type |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
110 |
|| evsql_result_uint16(res, row, col_offset + 1, &mode, 0 ) // inodes.mode |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
111 |
|| evsql_result_uint64(res, row, col_offset + 2, &size, 0 ) // inodes.size |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
112 |
|| evsql_result_uint64(res, row, col_offset + 3, &nlink, 0 ) // count(*) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
113 |
) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
114 |
EERROR(err = EIO, "invalid db data"); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
115 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
116 |
INFO("\tst_mode=S_IF%s | %ho, st_nlink=%llu, st_size=%llu", type, mode, (long long unsigned int) nlink, (long long unsigned int) size);
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
117 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
118 |
// convert and store |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
119 |
st->st_mode = _dbfs_mode(type) | mode; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
120 |
st->st_nlink = nlink; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
121 |
st->st_size = size; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
122 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
123 |
// good |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
124 |
return 0; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
125 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
126 |
error: |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
127 |
return -1; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
128 |
} |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
129 |
|
| 24 | 130 |
void _dbfs_lookup_result (const struct evsql_result_info *res, void *arg) {
|
131 |
struct fuse_req *req = arg; |
|
132 |
struct fuse_entry_param e; ZINIT(e); |
|
133 |
int err = 0; |
|
134 |
||
135 |
uint32_t ino; |
|
136 |
||
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
137 |
// check the results |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
138 |
if ((err = _dbfs_check_res(res, 1, 5))) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
139 |
SERROR(err = (err == 1 ? ENOENT : EIO)); |
| 24 | 140 |
|
141 |
// get the data |
|
142 |
if (0 |
|
143 |
|| evsql_result_uint32(res, 0, 0, &ino, 0 ) // inodes.ino |
|
144 |
) |
|
145 |
EERROR(err = EIO, "invalid db data"); |
|
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
146 |
|
| 27 | 147 |
INFO("[dbfs.lookup] -> ino=%u", ino);
|
| 24 | 148 |
|
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
149 |
// stat attrs |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
150 |
if (_dbfs_stat_info(&e.attr, res, 0, 1)) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
151 |
goto error; |
| 24 | 152 |
|
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
153 |
// other attrs |
| 24 | 154 |
e.ino = e.attr.st_ino = ino; |
155 |
e.attr_timeout = CACHE_TIMEOUT; |
|
156 |
e.entry_timeout = CACHE_TIMEOUT; |
|
157 |
||
158 |
// reply |
|
159 |
if ((err = fuse_reply_entry(req, &e))) |
|
160 |
EERROR(err, "fuse_reply_entry"); |
|
161 |
||
162 |
error: |
|
163 |
if (err && (err = fuse_reply_err(req, err))) |
|
164 |
EWARNING(err, "fuse_reply_err"); |
|
165 |
||
166 |
// free |
|
167 |
evsql_result_free(res); |
|
168 |
} |
|
169 |
||
170 |
void dbfs_lookup (struct fuse_req *req, fuse_ino_t parent, const char *name) {
|
|
171 |
struct dbfs *ctx = fuse_req_userdata(req); |
|
172 |
int err; |
|
173 |
||
174 |
INFO("[dbfs.lookup] parent=%lu name=%s", parent, name);
|
|
175 |
||
176 |
// query and params |
|
177 |
const char *sql = |
|
178 |
"SELECT" |
|
179 |
" inodes.ino, inodes.type, inodes.mode, inodes.size, count(*)" |
|
180 |
" FROM file_tree INNER JOIN inodes ON (file_tree.inode = inodes.ino)" |
|
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
181 |
" WHERE file_tree.parent = $1::int4 AND file_tree.name = $2::varchar" |
| 24 | 182 |
" GROUP BY inodes.ino, inodes.type, inodes.mode, inodes.size"; |
183 |
||
184 |
static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
|
|
185 |
EVSQL_PARAM ( UINT32 ), |
|
186 |
EVSQL_PARAM ( STRING ), |
|
187 |
||
188 |
EVSQL_PARAMS_END |
|
189 |
}; |
|
190 |
||
191 |
// build params |
|
192 |
if (0 |
|
193 |
|| evsql_param_uint32(¶ms, 0, parent) |
|
194 |
|| evsql_param_string(¶ms, 1, name) |
|
195 |
) |
|
196 |
EERROR(err = EIO, "evsql_param_*"); |
|
197 |
||
198 |
// query |
|
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
199 |
if (evsql_query_params(ctx->db, NULL, sql, ¶ms, _dbfs_lookup_result, req) == NULL) |
| 24 | 200 |
EERROR(err = EIO, "evsql_query_params"); |
201 |
||
202 |
// XXX: handle interrupts |
|
203 |
||
204 |
// wait |
|
205 |
return; |
|
206 |
||
207 |
error: |
|
208 |
if ((err = fuse_reply_err(req, err))) |
|
209 |
EWARNING(err, "fuse_reply_err"); |
|
210 |
} |
|
211 |
||
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
212 |
void _dbfs_getattr_result (const struct evsql_result_info *res, void *arg) {
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
213 |
struct fuse_req *req = arg; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
214 |
struct stat st; ZINIT(st); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
215 |
int err = 0; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
216 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
217 |
// check the results |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
218 |
if ((err = _dbfs_check_res(res, 1, 4))) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
219 |
SERROR(err = (err == 1 ? ENOENT : EIO)); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
220 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
221 |
INFO("[dbfs.getattr %p] -> (stat follows)", req);
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
222 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
223 |
// stat attrs |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
224 |
if (_dbfs_stat_info(&st, res, 0, 0)) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
225 |
goto error; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
226 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
227 |
// XXX: we don't have the ino |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
228 |
st.st_ino = 0; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
229 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
230 |
// reply |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
231 |
if ((err = fuse_reply_attr(req, &st, CACHE_TIMEOUT))) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
232 |
EERROR(err, "fuse_reply_entry"); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
233 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
234 |
error: |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
235 |
if (err && (err = fuse_reply_err(req, err))) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
236 |
EWARNING(err, "fuse_reply_err"); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
237 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
238 |
// free |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
239 |
evsql_result_free(res); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
240 |
} |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
241 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
242 |
static void dbfs_getattr (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi) {
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
243 |
struct dbfs *ctx = fuse_req_userdata(req); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
244 |
int err; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
245 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
246 |
(void) fi; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
247 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
248 |
INFO("[dbfs.getattr %p] ino=%lu", req, ino);
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
249 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
250 |
const char *sql = |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
251 |
"SELECT" |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
252 |
" inodes.type, inodes.mode, inodes.size, count(*)" |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
253 |
" FROM inodes" |
| 27 | 254 |
" WHERE inodes.ino = $1::int4" |
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
255 |
" GROUP BY inodes.type, inodes.mode, inodes.size"; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
256 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
257 |
static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
258 |
EVSQL_PARAM ( UINT32 ), |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
259 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
260 |
EVSQL_PARAMS_END |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
261 |
}; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
262 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
263 |
// build params |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
264 |
if (0 |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
265 |
|| evsql_param_uint32(¶ms, 0, ino) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
266 |
) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
267 |
SERROR(err = EIO); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
268 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
269 |
// query |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
270 |
if (evsql_query_params(ctx->db, NULL, sql, ¶ms, _dbfs_getattr_result, req) == NULL) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
271 |
SERROR(err = EIO); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
272 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
273 |
// XXX: handle interrupts |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
274 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
275 |
// wait |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
276 |
return; |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
277 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
278 |
error: |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
279 |
if ((err = fuse_reply_err(req, err))) |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
280 |
EWARNING(err, "fuse_reply_err"); |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
281 |
} |
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
282 |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
283 |
struct dbfs_dirop {
|
| 27 | 284 |
struct fuse_file_info fi; |
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
285 |
struct fuse_req *req; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
286 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
287 |
struct evsql_trans *trans; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
288 |
|
| 27 | 289 |
// dir/parent dir inodes |
290 |
uint32_t ino, parent; |
|
291 |
||
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
292 |
// opendir has returned and releasedir hasn't been called yet |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
293 |
int open; |
| 27 | 294 |
|
295 |
// for readdir |
|
296 |
struct dirbuf dirbuf; |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
297 |
}; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
298 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
299 |
/* |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
300 |
* Free the dirop, aborting any in-progress transaction. |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
301 |
* |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
302 |
* req must be NULL. |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
303 |
*/ |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
304 |
static void dbfs_dirop_free (struct dbfs_dirop *dirop) {
|
| 27 | 305 |
assert(dirop); |
306 |
assert(!dirop->open); |
|
307 |
assert(!dirop->req); |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
308 |
|
| 27 | 309 |
if (dirop->trans) {
|
310 |
WARNING("aborting transaction");
|
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
311 |
evsql_trans_abort(dirop->trans); |
| 27 | 312 |
} |
313 |
||
314 |
dirbuf_release(&dirop->dirbuf); |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
315 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
316 |
free(dirop); |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
317 |
} |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
318 |
|
| 27 | 319 |
static void dbfs_opendir_info_res (const struct evsql_result_info *res, void *arg) {
|
320 |
struct dbfs_dirop *dirop = arg; |
|
321 |
struct fuse_req *req = dirop->req; dirop->req = NULL; |
|
322 |
int err; |
|
323 |
||
324 |
assert(req != NULL); |
|
325 |
||
326 |
// check the results |
|
327 |
if ((err = _dbfs_check_res(res, 1, 2))) |
|
328 |
SERROR(err = (err == 1 ? ENOENT : EIO)); |
|
329 |
||
330 |
const char *type; |
|
331 |
||
332 |
// extract the data |
|
333 |
if (0 |
|
334 |
|| evsql_result_uint32(res, 0, 0, &dirop->parent, 1 ) // file_tree.parent |
|
335 |
|| evsql_result_string(res, 0, 1, &type, 0 ) // inodes.type |
|
336 |
) |
|
337 |
SERROR(err = EIO); |
|
338 |
||
339 |
// is it a dir? |
|
340 |
if (_dbfs_mode(type) != S_IFDIR) |
|
341 |
EERROR(err = ENOTDIR, "wrong type: %s", type); |
|
342 |
||
343 |
INFO("[dbfs.opendir %p:%p] -> ino=%lu, parent=%lu, type=%s", dirop, req, (unsigned long int) dirop->ino, (unsigned long int) dirop->parent, type);
|
|
344 |
||
345 |
// send the openddir reply |
|
346 |
if ((err = fuse_reply_open(req, &dirop->fi))) |
|
347 |
EERROR(err, "fuse_reply_open"); |
|
348 |
||
349 |
// dirop is now open |
|
350 |
dirop->open = 1; |
|
351 |
||
352 |
// ok, wait for the opendir call |
|
353 |
return; |
|
354 |
||
355 |
error: |
|
356 |
if (err) {
|
|
357 |
// abort the trans |
|
358 |
evsql_trans_abort(dirop->trans); |
|
359 |
||
360 |
dirop->trans = NULL; |
|
361 |
||
362 |
if ((err = fuse_reply_err(req, err))) |
|
363 |
EWARNING(err, "fuse_reply_err"); |
|
364 |
} |
|
365 |
||
366 |
// free |
|
367 |
evsql_result_free(res); |
|
368 |
} |
|
369 |
||
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
370 |
/* |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
371 |
* The opendir transaction is ready |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
372 |
*/ |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
373 |
static void dbfs_dirop_ready (struct evsql_trans *trans, void *arg) {
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
374 |
struct dbfs_dirop *dirop = arg; |
| 27 | 375 |
struct fuse_req *req = dirop->req; |
376 |
struct dbfs *ctx = fuse_req_userdata(req); |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
377 |
int err; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
378 |
|
| 27 | 379 |
assert(req != NULL); |
380 |
||
381 |
INFO("[dbfs.opendir %p:%p] -> trans=%p", dirop, req, trans);
|
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
382 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
383 |
// remember the transaction |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
384 |
dirop->trans = trans; |
| 27 | 385 |
|
386 |
// first fetch info about the dir itself |
|
387 |
const char *sql = |
|
388 |
"SELECT" |
|
389 |
" file_tree.parent, inodes.type" |
|
390 |
" FROM file_tree LEFT OUTER JOIN inodes ON (file_tree.inode = inodes.ino)" |
|
391 |
" WHERE file_tree.inode = $1::int4"; |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
392 |
|
| 27 | 393 |
static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
|
394 |
EVSQL_PARAM ( UINT32 ), |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
395 |
|
| 27 | 396 |
EVSQL_PARAMS_END |
397 |
}; |
|
398 |
||
399 |
// build params |
|
400 |
if (0 |
|
401 |
|| evsql_param_uint32(¶ms, 0, dirop->ino) |
|
402 |
) |
|
403 |
SERROR(err = EIO); |
|
404 |
||
405 |
// query |
|
406 |
if (evsql_query_params(ctx->db, dirop->trans, sql, ¶ms, dbfs_opendir_info_res, dirop) == NULL) |
|
407 |
SERROR(err = EIO); |
|
408 |
||
409 |
// ok, wait for the info results |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
410 |
return; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
411 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
412 |
error: |
| 27 | 413 |
// we handle the req |
414 |
dirop->req = NULL; |
|
415 |
||
416 |
// free the dirop |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
417 |
dbfs_dirop_free(dirop); |
| 27 | 418 |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
419 |
if ((err = fuse_reply_err(req, err))) |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
420 |
EWARNING(err, "fuse_reply_err"); |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
421 |
} |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
422 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
423 |
static void dbfs_dirop_done (struct evsql_trans *trans, void *arg) {
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
424 |
struct dbfs_dirop *dirop = arg; |
| 27 | 425 |
struct fuse_req *req = dirop->req; dirop->req = NULL; |
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
426 |
int err; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
427 |
|
| 27 | 428 |
assert(req != NULL); |
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
429 |
|
| 27 | 430 |
INFO("[dbfs.releasedir %p:%p] -> OK", dirop, req);
|
431 |
||
432 |
// forget trans |
|
433 |
dirop->trans = NULL; |
|
434 |
||
435 |
// just reply |
|
436 |
if ((err = fuse_reply_err(req, 0))) |
|
437 |
EWARNING(err, "fuse_reply_err"); |
|
438 |
||
439 |
// we can free dirop |
|
440 |
dbfs_dirop_free(dirop); |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
441 |
} |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
442 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
443 |
static void dbfs_dirop_error (struct evsql_trans *trans, void *arg) {
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
444 |
struct dbfs_dirop *dirop = arg; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
445 |
int err; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
446 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
447 |
INFO("[dbfs:dirop %p:%p] evsql transaction error: %s", dirop, dirop->req, evsql_trans_error(trans));
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
448 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
449 |
// deassociate the trans |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
450 |
dirop->trans = NULL; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
451 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
452 |
// error out and pending req |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
453 |
if (dirop->req) {
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
454 |
if ((err = fuse_reply_err(dirop->req, EIO))) |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
455 |
EWARNING(err, "fuse_erply_err"); |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
456 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
457 |
dirop->req = NULL; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
458 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
459 |
// only free the dirop if it isn't open |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
460 |
if (!dirop->open) |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
461 |
dbfs_dirop_free(dirop); |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
462 |
} |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
463 |
} |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
464 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
465 |
static void dbfs_opendir (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi) {
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
466 |
struct dbfs *ctx = fuse_req_userdata(req); |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
467 |
struct dbfs_dirop *dirop = NULL; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
468 |
int err; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
469 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
470 |
// allocate it |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
471 |
if ((dirop = calloc(1, sizeof(*dirop))) == NULL && (err = EIO)) |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
472 |
ERROR("calloc");
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
473 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
474 |
INFO("[dbfs.opendir %p:%p] ino=%lu, fi=%p", dirop, req, ino, fi);
|
| 27 | 475 |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
476 |
// store the dirop |
| 27 | 477 |
// copy *fi since it's on the stack |
478 |
dirop->fi = *fi; |
|
479 |
dirop->fi.fh = (uint64_t) dirop; |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
480 |
dirop->req = req; |
| 27 | 481 |
dirop->ino = ino; |
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
482 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
483 |
// start a new transaction |
| 27 | 484 |
if ((dirop->trans = evsql_trans(ctx->db, EVSQL_TRANS_SERIALIZABLE, dbfs_dirop_error, dbfs_dirop_ready, dbfs_dirop_done, dirop)) == NULL) |
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
485 |
SERROR(err = EIO); |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
486 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
487 |
// XXX: handle interrupts |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
488 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
489 |
// wait |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
490 |
return; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
491 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
492 |
error: |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
493 |
// we handle the req |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
494 |
dirop->req = NULL; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
495 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
496 |
dbfs_dirop_free(dirop); |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
497 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
498 |
if ((err = fuse_reply_err(req, err))) |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
499 |
EWARNING(err, "fuse_reply_err"); |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
500 |
} |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
501 |
|
| 27 | 502 |
static void dbfs_readdir_files_res (const struct evsql_result_info *res, void *arg) {
|
503 |
struct dbfs_dirop *dirop = arg; |
|
504 |
struct fuse_req *req = dirop->req; dirop->req = NULL; |
|
505 |
int err; |
|
506 |
size_t row; |
|
507 |
||
508 |
assert(req != NULL); |
|
509 |
||
510 |
// check the results |
|
511 |
if ((err = _dbfs_check_res(res, 0, 4)) < 0) |
|
512 |
SERROR(err = EIO); |
|
513 |
||
514 |
INFO("[dbfs.readdir %p:%p] -> files: res_rows=%zu", dirop, req, evsql_result_rows(res));
|
|
515 |
||
516 |
// iterate over the rows |
|
517 |
for (row = 0; row < evsql_result_rows(res); row++) {
|
|
518 |
uint32_t off, ino; |
|
519 |
const char *name, *type; |
|
520 |
||
521 |
// extract the data |
|
522 |
if (0 |
|
523 |
|| evsql_result_uint32(res, row, 0, &off, 0 ) // file_tree.offset |
|
524 |
|| evsql_result_string(res, row, 1, &name, 0 ) // file_tree.name |
|
525 |
|| evsql_result_uint32(res, row, 2, &ino, 0 ) // inodes.ino |
|
526 |
|| evsql_result_string(res, row, 3, &type, 0 ) // inodes.type |
|
527 |
) |
|
528 |
SERROR(err = EIO); |
|
529 |
||
530 |
INFO("\t%zu: off=%lu+2, name=%s, ino=%lu, type=%s", row, (long unsigned int) off, name, (long unsigned int) ino, type);
|
|
531 |
||
532 |
// add to the dirbuf |
|
533 |
// offsets are just offset + 2 |
|
534 |
if ((err = dirbuf_add(req, &dirop->dirbuf, off + 2, off + 3, name, ino, _dbfs_mode(type))) < 0 && (err = EIO)) |
|
535 |
ERROR("failed to add dirent for inode=%lu", (long unsigned int) ino);
|
|
536 |
||
537 |
// stop if it's full |
|
538 |
if (err > 0) |
|
539 |
break; |
|
540 |
} |
|
541 |
||
542 |
// send it |
|
543 |
if ((err = dirbuf_done(req, &dirop->dirbuf))) |
|
544 |
EERROR(err, "failed to send buf"); |
|
545 |
||
546 |
// good, fallthrough |
|
547 |
err = 0; |
|
548 |
||
549 |
error: |
|
550 |
if (err) {
|
|
551 |
// abort the trans |
|
552 |
evsql_trans_abort(dirop->trans); |
|
553 |
||
554 |
dirop->trans = NULL; |
|
555 |
||
556 |
// we handle the req |
|
557 |
dirop->req = NULL; |
|
558 |
||
559 |
if ((err = fuse_reply_err(req, err))) |
|
560 |
EWARNING(err, "fuse_reply_err"); |
|
561 |
} |
|
562 |
||
563 |
// free |
|
564 |
evsql_result_free(res); |
|
565 |
} |
|
566 |
||
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
567 |
static void dbfs_readdir (struct fuse_req *req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) {
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
568 |
struct dbfs *ctx = fuse_req_userdata(req); |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
569 |
struct dbfs_dirop *dirop = (struct dbfs_dirop *) fi->fh; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
570 |
int err; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
571 |
|
| 27 | 572 |
assert(!dirop->req); |
573 |
assert(dirop->trans); |
|
574 |
assert(dirop->ino == ino); |
|
575 |
||
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
576 |
INFO("[dbfs.readdir %p:%p] ino=%lu, size=%zu, off=%zu, fi=%p : trans=%p", dirop, req, ino, size, off, fi, dirop->trans);
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
577 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
578 |
// update dirop |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
579 |
dirop->req = req; |
| 27 | 580 |
|
581 |
// create the dirbuf |
|
582 |
if (dirbuf_init(&dirop->dirbuf, size, off)) |
|
583 |
SERROR(err = EIO); |
|
584 |
||
585 |
// add . and .. |
|
586 |
// we set the next offset to 2, because all dirent offsets will be larger than that |
|
587 |
if ((err = (0 |
|
588 |
|| dirbuf_add(req, &dirop->dirbuf, 0, 1, ".", dirop->ino, S_IFDIR ) |
|
589 |
|| dirbuf_add(req, &dirop->dirbuf, 1, 2, "..", |
|
590 |
dirop->parent ? dirop->parent : dirop->ino, S_IFDIR ) |
|
591 |
)) && (err = EIO)) |
|
592 |
ERROR("failed to add . and .. dirents");
|
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
593 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
594 |
// select all relevant file entries |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
595 |
const char *sql = |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
596 |
"SELECT" |
| 27 | 597 |
" file_tree.\"offset\", file_tree.name, inodes.ino, inodes.type" |
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
598 |
" FROM file_tree LEFT OUTER JOIN inodes ON (file_tree.inode = inodes.ino)" |
| 27 | 599 |
" WHERE file_tree.parent = $1::int4 AND file_tree.\"offset\" >= $2::int4" |
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
600 |
" LIMIT $3::int4"; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
601 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
602 |
static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) {
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
603 |
EVSQL_PARAM ( UINT32 ), |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
604 |
EVSQL_PARAM ( UINT32 ), |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
605 |
EVSQL_PARAM ( UINT32 ), |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
606 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
607 |
EVSQL_PARAMS_END |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
608 |
}; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
609 |
|
| 27 | 610 |
// adjust offset to take . and .. into account |
611 |
if (off > 2) |
|
612 |
off -= 2; |
|
613 |
||
614 |
// build params |
|
615 |
if (0 |
|
616 |
|| evsql_param_uint32(¶ms, 0, dirop->ino) |
|
617 |
|| evsql_param_uint32(¶ms, 1, off) |
|
618 |
|| evsql_param_uint32(¶ms, 2, dirbuf_estimate(&dirop->dirbuf, 0)) |
|
619 |
) |
|
620 |
SERROR(err = EIO); |
|
621 |
||
622 |
// query |
|
623 |
if (evsql_query_params(ctx->db, dirop->trans, sql, ¶ms, dbfs_readdir_files_res, dirop) == NULL) |
|
624 |
SERROR(err = EIO); |
|
625 |
||
626 |
// good, wait |
|
627 |
return; |
|
628 |
||
629 |
error: |
|
630 |
// we handle the req |
|
631 |
dirop->req = NULL; |
|
632 |
||
633 |
// abort the trans |
|
634 |
evsql_trans_abort(dirop->trans); dirop->trans = NULL; |
|
635 |
||
636 |
if ((err = fuse_reply_err(req, err))) |
|
637 |
EWARNING(err, "fuse_reply_err"); |
|
638 |
||
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
639 |
} |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
640 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
641 |
static void dbfs_releasedir (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi) {
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
642 |
struct dbfs *ctx = fuse_req_userdata(req); |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
643 |
struct dbfs_dirop *dirop = (struct dbfs_dirop *) fi->fh; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
644 |
int err; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
645 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
646 |
(void) ctx; |
| 27 | 647 |
|
648 |
assert(!dirop->req); |
|
649 |
assert(dirop->ino == ino); |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
650 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
651 |
INFO("[dbfs.releasedir %p:%p] ino=%lu, fi=%p : trans=%p", dirop, req, ino, fi, dirop->trans);
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
652 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
653 |
// update dirop. Must keep it open so that dbfs_dirop_error won't free it |
| 27 | 654 |
// copy *fi since it's on the stack |
655 |
dirop->fi = *fi; |
|
656 |
dirop->fi.fh = (uint64_t) dirop; |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
657 |
dirop->req = req; |
| 27 | 658 |
|
659 |
if (dirop->trans) {
|
|
660 |
// we can commit the transaction, although we didn't make any changes |
|
661 |
// if this fails the transaction, then dbfs_dirop_error will take care of sending the error, and dirop->req will be |
|
662 |
// NULL |
|
663 |
if (evsql_trans_commit(dirop->trans)) |
|
664 |
SERROR(err = EIO); |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
665 |
|
| 27 | 666 |
} else {
|
667 |
// trans failed earlier, so have releasedir just succeed |
|
668 |
if ((err = fuse_reply_err(req, 0))) |
|
669 |
EERROR(err, "fuse_reply_err"); |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
670 |
|
| 27 | 671 |
// req is done |
672 |
dirop->req = NULL; |
|
673 |
} |
|
674 |
||
675 |
// fall-through to cleanup |
|
676 |
err = 0; |
|
677 |
||
678 |
error: |
|
679 |
// the dirop is not open anymore and can be freed once done with |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
680 |
dirop->open = 0; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
681 |
|
| 27 | 682 |
// if trans_commit triggered an error but didn't call dbfs_dirop_error, we need to take care of it |
683 |
if (err && dirop->req) {
|
|
684 |
int err2; |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
685 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
686 |
// we handle the req |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
687 |
dirop->req = NULL; |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
688 |
|
| 27 | 689 |
if ((err2 = fuse_reply_err(req, err))) |
690 |
EWARNING(err2, "fuse_reply_err"); |
|
691 |
} |
|
692 |
||
693 |
// same for trans, we need to abort it if trans_commit failed and fs_dirop_error didn't get called |
|
694 |
if (err && dirop->trans) {
|
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
695 |
dbfs_dirop_free(dirop); |
| 27 | 696 |
|
697 |
} else |
|
698 |
// alternatively, if the trans error'd itself away (now or earlier), we don't need to keep the dirop around |
|
699 |
// anymore now that we've checkd its state |
|
700 |
if (!dirop->trans) {
|
|
701 |
dbfs_dirop_free(dirop); |
|
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
702 |
} |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
703 |
} |
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
704 |
|
| 24 | 705 |
struct fuse_lowlevel_ops dbfs_llops = {
|
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
706 |
|
| 24 | 707 |
.init = dbfs_init, |
708 |
.destroy = dbfs_destroy, |
|
709 |
||
710 |
.lookup = dbfs_lookup, |
|
|
25
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
711 |
|
|
99a41f48e29b
evsql transactions, it compiles...
Tero Marttila <terom@fixme.fi>
parents:
24
diff
changeset
|
712 |
.getattr = dbfs_getattr, |
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
713 |
|
|
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
714 |
.opendir = dbfs_opendir, |
| 27 | 715 |
.readdir = dbfs_readdir, |
|
26
61668c57f4bb
preliminary *dir implementation
Tero Marttila <terom@fixme.fi>
parents:
25
diff
changeset
|
716 |
.releasedir = dbfs_releasedir, |
| 24 | 717 |
}; |
718 |
||
719 |
void dbfs_sql_error (struct evsql *evsql, void *arg) {
|
|
720 |
struct dbfs *ctx = arg; |
|
721 |
||
722 |
// AAAAAAAAAA.... panic |
|
723 |
WARNING("[dbfs] SQL error: BREAKING MAIN LOOP LIEK NAO");
|
|
724 |
||
725 |
event_base_loopbreak(ctx->ev_base); |
|
726 |
} |
|
727 |
||
728 |
int main (int argc, char **argv) {
|
|
729 |
struct fuse_args fuse_args = FUSE_ARGS_INIT(argc, argv); |
|
730 |
struct dbfs ctx; ZINIT(ctx); |
|
731 |
||
732 |
// parse args, XXX: fuse_args |
|
733 |
ctx.db_conninfo = CONNINFO_DEFAULT; |
|
734 |
||
735 |
// init libevent |
|
736 |
if ((ctx.ev_base = event_base_new()) == NULL) |
|
737 |
ERROR("event_base_new");
|
|
738 |
||
739 |
// setup signals |
|
740 |
if ((ctx.signals = signals_default(ctx.ev_base)) == NULL) |
|
741 |
ERROR("signals_default");
|
|
742 |
||
743 |
// open sql |
|
744 |
if ((ctx.db = evsql_new_pq(ctx.ev_base, ctx.db_conninfo, dbfs_sql_error, &ctx)) == NULL) |
|
745 |
ERROR("evsql_new_pq");
|
|
746 |
||
747 |
// open fuse |
|
748 |
if ((ctx.ev_fuse = evfuse_new(ctx.ev_base, &fuse_args, &dbfs_llops, &ctx)) == NULL) |
|
749 |
ERROR("evfuse_new");
|
|
750 |
||
751 |
// run libevent |
|
752 |
INFO("running libevent loop");
|
|
753 |
||
754 |
if (event_base_dispatch(ctx.ev_base)) |
|
755 |
PERROR("event_base_dispatch");
|
|
756 |
||
757 |
// clean shutdown |
|
758 |
||
759 |
error : |
|
760 |
// cleanup |
|
761 |
if (ctx.ev_fuse) |
|
| 27 | 762 |
evfuse_free(ctx.ev_fuse); |
| 24 | 763 |
|
764 |
// XXX: ctx.db |
|
765 |
||
766 |
if (ctx.signals) |
|
767 |
signals_free(ctx.signals); |
|
768 |
||
769 |
if (ctx.ev_base) |
|
770 |
event_base_free(ctx.ev_base); |
|
771 |
||
772 |
fuse_opt_free_args(&fuse_args); |
|
773 |
} |
|
774 |