# HG changeset patch # User Tero Marttila # Date 1224248975 -10800 # Node ID 90e14e0df133e8f076b8c615c2ca9e5d1eb35cb0 # Parent 7804cd7b5cd54674c166dfb1b0519b0393b263b6 working readlink diff -r 7804cd7b5cd5 -r 90e14e0df133 Makefile --- a/Makefile Fri Oct 17 02:04:03 2008 +0300 +++ b/Makefile Fri Oct 17 16:09:35 2008 +0300 @@ -20,7 +20,7 @@ # complex modules EVSQL_OBJS = obj/evsql/evsql.o obj/evsql/util.o obj/evpq.o -DBFS_OBJS = obj/dbfs/dbfs.o obj/dbfs/common.o obj/dbfs/core.o obj/dbfs/op_base.o obj/dbfs/dirop.o obj/dirbuf.o obj/dbfs/fileop.o obj/dbfs/attr.o +DBFS_OBJS = obj/dbfs/dbfs.o obj/dbfs/common.o obj/dbfs/core.o obj/dbfs/op_base.o obj/dbfs/dirop.o obj/dirbuf.o obj/dbfs/fileop.o obj/dbfs/attr.o obj/dbfs/link.o # first target all: ${BIN_PATHS} diff -r 7804cd7b5cd5 -r 90e14e0df133 doc/fuse_db.sql --- a/doc/fuse_db.sql Fri Oct 17 02:04:03 2008 +0300 +++ b/doc/fuse_db.sql Fri Oct 17 16:09:35 2008 +0300 @@ -25,3 +25,4 @@ CREATE FUNCTION lo_pwrite (IN fd int4, IN buf bytea, IN "off" int4) RETURNS int4 LANGUAGE SQL STRICT AS 'select lo_lseek($1, $3, 0); select lowrite($1, $2);'; CREATE FUNCTION lo_otruncate (IN oid, IN len int4) RETURNS oid LANGUAGE SQL STRICT AS 'select lo_truncate(lo_open($1, 393216), $2); select $1;'; +ALTER TABLE inodes ADD COLUMN symlink varchar(512); diff -r 7804cd7b5cd5 -r 90e14e0df133 src/dbfs/attr.c --- a/src/dbfs/attr.c Fri Oct 17 02:04:03 2008 +0300 +++ b/src/dbfs/attr.c Fri Oct 17 16:09:35 2008 +0300 @@ -29,13 +29,13 @@ INFO("[dbfs.getattr %p] -> ino=%lu, stat follows", req, (unsigned long int) ino); + // inode + st.st_ino = ino; + // stat attrs if ((err = _dbfs_stat_info(&st, res, 0, 1))) goto error; - // XXX: we don't have the ino - st.st_ino = ino; - // reply if ((err = fuse_reply_attr(req, &st, st.st_nlink ? CACHE_TIMEOUT : 0))) EERROR(err, "fuse_reply_entry"); diff -r 7804cd7b5cd5 -r 90e14e0df133 src/dbfs/common.c --- a/src/dbfs/common.c Fri Oct 17 02:04:03 2008 +0300 +++ b/src/dbfs/common.c Fri Oct 17 16:09:35 2008 +0300 @@ -10,6 +10,9 @@ if (!strcmp(type, "REG")) return S_IFREG; + + if (!strcmp(type, "LNK")) + return S_IFLNK; else { WARNING("[dbfs] weird mode-type: %s", type); diff -r 7804cd7b5cd5 -r 90e14e0df133 src/dbfs/dbfs.c --- a/src/dbfs/dbfs.c Fri Oct 17 02:04:03 2008 +0300 +++ b/src/dbfs/dbfs.c Fri Oct 17 16:09:35 2008 +0300 @@ -11,9 +11,10 @@ .destroy = dbfs_destroy, .lookup = dbfs_lookup, - + // .forget .getattr = dbfs_getattr, .setattr = dbfs_setattr, + .readlink = dbfs_readlink, .open = dbfs_open, .read = dbfs_read, diff -r 7804cd7b5cd5 -r 90e14e0df133 src/dbfs/link.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dbfs/link.c Fri Oct 17 16:09:35 2008 +0300 @@ -0,0 +1,79 @@ +#include "dbfs.h" + +#include "../lib/log.h" + +void _dbfs_readlink_res (const struct evsql_result_info *res, void *arg) { + struct fuse_req *req = arg; + int err = 0; + + uint32_t ino; + const char *type, *link; + + // check the results + if ((err = _dbfs_check_res(res, 1, 3))) + SERROR(err = (err == 1 ? ENOENT : EIO)); + + // get our data + if (0 + || evsql_result_uint32(res, 0, 0, &ino, 0 ) // inodes.ino + || evsql_result_string(res, 0, 1, &type, 0 ) // inodes.type + || evsql_result_string(res, 0, 2, &link, 1 ) // inodes.symlink + ) + EERROR(err = EIO, "invalid db data"); + + // is it a symlink? + 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); + + // reply + if ((err = fuse_reply_readlink(req, link))) + 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_readlink (struct fuse_req *req, fuse_ino_t ino) { + struct dbfs *ctx = fuse_req_userdata(req); + int err; + + INFO("[dbfs.readlink %p] ino=%lu", req, ino); + + const char *sql = + "SELECT" + " inodes.ino, inodes.type, inodes.symlink" + " FROM inodes" + " WHERE inodes.ino = $1::int4"; + + static struct evsql_query_params params = EVSQL_PARAMS(EVSQL_FMT_BINARY) { + EVSQL_PARAM ( UINT32 ), + + EVSQL_PARAMS_END + }; + + // build params + if (0 + || evsql_param_uint32(¶ms, 0, ino) + ) + SERROR(err = EIO); + + // query + if (evsql_query_params(ctx->db, NULL, sql, ¶ms, _dbfs_readlink_res, req) == NULL) + SERROR(err = EIO); + + // XXX: handle interrupts + + // wait + return; + +error: + if ((err = fuse_reply_err(req, err))) + EWARNING(err, "fuse_reply_err"); + +} diff -r 7804cd7b5cd5 -r 90e14e0df133 src/dbfs/ops.h --- a/src/dbfs/ops.h Fri Oct 17 02:04:03 2008 +0300 +++ b/src/dbfs/ops.h Fri Oct 17 16:09:35 2008 +0300 @@ -9,11 +9,14 @@ /* core.c */ void dbfs_lookup (struct fuse_req *req, fuse_ino_t parent, const char *name); -void dbfs_getattr (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi); -/* setattr.c */ +/* attr.c */ +void dbfs_getattr (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi); void dbfs_setattr(struct fuse_req *req, fuse_ino_t ino, struct stat *attr, int to_set, struct fuse_file_info *fi); +/* symlink.c */ +void dbfs_readlink (struct fuse_req *req, fuse_ino_t ino); + /* dirop.c */ void dbfs_opendir (struct fuse_req *req, fuse_ino_t ino, struct fuse_file_info *fi); void dbfs_readdir (struct fuse_req *req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi);