author | Tero Marttila <terom@fixme.fi> |
Sat, 29 Nov 2008 01:30:43 +0200 | |
branch | new-evsql |
changeset 49 | bb2ff0d2d343 |
parent 48 | 8b019d191353 |
permissions | -rw-r--r-- |
31 | 1 |
|
2 |
#include "dbfs.h" |
|
3 |
#include "../lib/log.h" |
|
4 |
#include "../lib/misc.h" |
|
5 |
||
6 |
// max. size for a setattr UPDATE query |
|
7 |
#define DBFS_SETATTR_SQL_MAX 512 |
|
8 |
||
9 |
// for building the setattr UPDATE |
|
10 |
#define FIELD(to_set, flag, field, value) ((to_set) & (flag)) ? (field " = " value ", ") : "" |
|
11 |
||
48
8b019d191353
update dbfs code to work with new evsql
Tero Marttila <terom@fixme.fi>
parents:
41
diff
changeset
|
12 |
void _dbfs_attr_res (struct evsql_result *res, void *arg) { |
31 | 13 |
struct fuse_req *req = arg; |
14 |
struct stat st; ZINIT(st); |
|
15 |
int err = 0; |
|
16 |
||
17 |
uint32_t ino; |
|
49
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
18 |
struct dbfs_stat_values stat_values; |
31 | 19 |
|
49
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
20 |
// result info |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
21 |
static struct evsql_result_info result_info = { |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
22 |
0, { |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
23 |
{ EVSQL_FMT_BINARY, EVSQL_TYPE_UINT32 }, // inodes.ino |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
24 |
DBFS_STAT_RESULT_INFO, |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
25 |
{ 0, 0 } |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
26 |
} |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
27 |
}; |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
28 |
|
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
29 |
// begin |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
30 |
if ((err = evsql_result_begin(&result_info, res))) |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
31 |
EERROR(err, "query failed"); |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
32 |
|
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
33 |
// get the one row of data |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
34 |
if ((err = evsql_result_next(res, &ino, DBFS_STAT_RESULT_VALUES(&stat_values))) <= 0) |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
35 |
EERROR(err = (err ? err : ENOENT), "evsql_result_next"); |
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
36 |
|
36
56427f22e969
tweak debug/info output, implement dbfs_unlink with slightly improved error macros handling
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
37 |
INFO("\t[dbfs.getattr %p] -> ino=%lu, stat follows", req, (unsigned long int) ino); |
49
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
38 |
|
32 | 39 |
// inode |
40 |
st.st_ino = ino; |
|
41 |
||
31 | 42 |
// stat attrs |
49
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
43 |
if ((err = _dbfs_stat_info(&st, &stat_values))) |
31 | 44 |
goto error; |
49
bb2ff0d2d343
modify stat-returning dbfs result functions to use new evsql
Tero Marttila <terom@fixme.fi>
parents:
48
diff
changeset
|
45 |
|
31 | 46 |
// reply |
47 |
if ((err = fuse_reply_attr(req, &st, st.st_nlink ? CACHE_TIMEOUT : 0))) |
|
48 |
EERROR(err, "fuse_reply_entry"); |
|
49 |
||
50 |
error: |
|
51 |
if (err && (err = fuse_reply_err(req, err))) |
|
52 |
EWARNING(err, "fuse_reply_err"); |
|
53 |
||
54 |
// free |
|
55 |
evsql_result_free(res); |
|
56 |
} |
|
57 |
||
58 |
void dbfs_getattr (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi) { |
|
59 |
struct dbfs *ctx = fuse_req_userdata(req); |
|
41
6abda2fa4579
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
Tero Marttila <terom@fixme.fi>
parents:
36
diff
changeset
|
60 |
struct evsql_query *query; |
31 | 61 |
int err; |
62 |
||
63 |
(void) fi; |
|
64 |
||
65 |
INFO("[dbfs.getattr %p] ino=%lu", req, ino); |
|
66 |
||
67 |
const char *sql = |
|
68 |
"SELECT" |
|
69 |
" inodes.ino, " DBFS_STAT_COLS |
|
70 |
" FROM inodes" |
|
33 | 71 |
" WHERE inodes.ino = $1::int4"; |
31 | 72 |
|
73 |
static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) { |
|
74 |
EVSQL_PARAM ( UINT32 ), |
|
75 |
||
76 |
EVSQL_PARAMS_END |
|
77 |
}; |
|
78 |
||
79 |
// build params |
|
80 |
if (0 |
|
81 |
|| evsql_param_uint32(¶ms, 0, ino) |
|
82 |
) |
|
83 |
SERROR(err = EIO); |
|
84 |
||
85 |
// query |
|
41
6abda2fa4579
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
Tero Marttila <terom@fixme.fi>
parents:
36
diff
changeset
|
86 |
if ((query = evsql_query_params(ctx->db, NULL, sql, ¶ms, _dbfs_attr_res, req)) == NULL) |
31 | 87 |
SERROR(err = EIO); |
88 |
||
41
6abda2fa4579
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
Tero Marttila <terom@fixme.fi>
parents:
36
diff
changeset
|
89 |
// handle interrupts |
6abda2fa4579
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
Tero Marttila <terom@fixme.fi>
parents:
36
diff
changeset
|
90 |
fuse_req_interrupt_func(req, dbfs_interrupt_query, query); |
31 | 91 |
|
92 |
// wait |
|
93 |
return; |
|
94 |
||
95 |
error: |
|
96 |
if ((err = fuse_reply_err(req, err))) |
|
97 |
EWARNING(err, "fuse_reply_err"); |
|
98 |
} |
|
99 |
||
100 |
||
101 |
void dbfs_setattr (struct fuse_req *req, fuse_ino_t ino, struct stat *attr, int to_set, struct fuse_file_info *fi) { |
|
102 |
struct dbfs *ctx = fuse_req_userdata(req); |
|
41
6abda2fa4579
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
Tero Marttila <terom@fixme.fi>
parents:
36
diff
changeset
|
103 |
struct evsql_query *query; |
31 | 104 |
int err; |
105 |
int ret; |
|
106 |
||
107 |
char sql_buf[DBFS_SETATTR_SQL_MAX]; |
|
108 |
||
109 |
static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) { |
|
110 |
EVSQL_PARAM ( UINT16 ), // inodes.mode |
|
111 |
EVSQL_PARAM ( UINT32 ), // inodes.uid |
|
112 |
EVSQL_PARAM ( UINT32 ), // inodes.gid |
|
113 |
EVSQL_PARAM ( UINT32 ), // data size |
|
114 |
EVSQL_PARAM ( UINT32 ), // ino |
|
115 |
||
116 |
EVSQL_PARAMS_END |
|
117 |
}; |
|
118 |
||
119 |
// log |
|
120 |
INFO("[dbfs.setattr %p] ino=%lu, fileop=%p: ", req, ino, fi && fi->fh ? (void*) fi->fh : NULL); |
|
121 |
||
122 |
if (to_set & FUSE_SET_ATTR_MODE) { |
|
123 |
// ignore the S_IFMT |
|
124 |
attr->st_mode &= 07777; |
|
125 |
||
126 |
INFO("\tmode = %08o", attr->st_mode); |
|
127 |
} |
|
128 |
||
129 |
if (to_set & FUSE_SET_ATTR_UID) |
|
130 |
INFO("\tuid = %u", attr->st_uid); |
|
131 |
||
132 |
if (to_set & FUSE_SET_ATTR_GID) |
|
133 |
INFO("\tgid = %u", attr->st_gid); |
|
134 |
||
135 |
if (to_set & FUSE_SET_ATTR_SIZE) |
|
136 |
INFO("\tsize = %lu", attr->st_size); |
|
137 |
||
138 |
if (to_set & FUSE_SET_ATTR_ATIME) |
|
139 |
INFO("\tatime = %lu", attr->st_atime); |
|
140 |
||
141 |
if (to_set & FUSE_SET_ATTR_MTIME) |
|
142 |
INFO("\tmtime = %lu", attr->st_mtime); |
|
143 |
||
144 |
// the SQL |
|
145 |
if ((ret = snprintf(sql_buf, DBFS_SETATTR_SQL_MAX, |
|
146 |
"UPDATE inodes SET" |
|
147 |
" %s%s%s%s ino = ino" |
|
148 |
" WHERE inodes.ino = $5::int4" |
|
33 | 149 |
" RETURNING inodes.ino, " DBFS_STAT_COLS, |
31 | 150 |
|
151 |
FIELD(to_set, FUSE_SET_ATTR_MODE, "mode", "$1::int2"), |
|
152 |
FIELD(to_set, FUSE_SET_ATTR_UID, "uid", "$2::int4"), |
|
153 |
FIELD(to_set, FUSE_SET_ATTR_GID, "gid", "$3::int4"), |
|
154 |
FIELD(to_set, FUSE_SET_ATTR_SIZE, "data", "lo_otruncate(data, $4::int4)") |
|
155 |
)) >= DBFS_SETATTR_SQL_MAX && (err = EIO)) |
|
156 |
ERROR("sql_buf is too small: %i", ret); |
|
157 |
||
158 |
// the params... |
|
159 |
if (0 |
|
160 |
|| ( evsql_params_clear(¶ms) ) |
|
161 |
|| ((to_set & FUSE_SET_ATTR_MODE ) && evsql_param_uint16(¶ms, 0, attr->st_mode) ) |
|
162 |
|| ((to_set & FUSE_SET_ATTR_UID ) && evsql_param_uint32(¶ms, 1, attr->st_uid) ) |
|
163 |
|| ((to_set & FUSE_SET_ATTR_GID ) && evsql_param_uint32(¶ms, 2, attr->st_gid) ) |
|
164 |
|| ((to_set & FUSE_SET_ATTR_SIZE ) && evsql_param_uint32(¶ms, 3, attr->st_size) ) |
|
165 |
|| ( evsql_param_uint32(¶ms, 4, ino) ) |
|
166 |
) |
|
167 |
SERROR(err = EIO); |
|
168 |
||
169 |
// trace the query |
|
170 |
evsql_query_debug(sql_buf, ¶ms); |
|
171 |
||
172 |
// query... we can pretend it's a getattr :) |
|
41
6abda2fa4579
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
Tero Marttila <terom@fixme.fi>
parents:
36
diff
changeset
|
173 |
if ((query = evsql_query_params(ctx->db, NULL, sql_buf, ¶ms, _dbfs_attr_res, req)) == NULL) |
31 | 174 |
SERROR(err = EIO); |
175 |
||
41
6abda2fa4579
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
Tero Marttila <terom@fixme.fi>
parents:
36
diff
changeset
|
176 |
// handle interrupts |
6abda2fa4579
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
Tero Marttila <terom@fixme.fi>
parents:
36
diff
changeset
|
177 |
fuse_req_interrupt_func(req, dbfs_interrupt_query, query); |
31 | 178 |
|
179 |
// wait |
|
180 |
return; |
|
181 |
||
182 |
error: |
|
183 |
if ((err = fuse_reply_err(req, err))) |
|
184 |
EWARNING(err, "fuse_reply_err"); |
|
185 |
} |