aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-04-25 02:22:04 -0400
committerJeff Garzik <jeff@garzik.org>2006-04-25 02:22:04 -0400
commit912a0c8b977e584cb2b8c46526d036cc3ca103a2 (patch)
tree9c93e812094be379cff5591648e78ab984f57073
parent4cbee76eb49cbdd68367fd9ef2ce31eb8ca61efd (diff)
downloaddbfs-912a0c8b977e584cb2b8c46526d036cc3ca103a2.tar.gz
Implement symlink op. Other misc changes.
- implement symlink op - update code to use new dbfs_reply_ino() helper - correct several places where fuse_reply_err() did not properly negate its error value. - trim trailing whitespace
-rw-r--r--dbfs-backend.c21
-rw-r--r--dbfs.c101
-rw-r--r--dbfs.h2
-rw-r--r--libdbfs.c2
4 files changed, 96 insertions, 30 deletions
diff --git a/dbfs-backend.c b/dbfs-backend.c
index ddf4b9b..19ba273 100644
--- a/dbfs-backend.c
+++ b/dbfs-backend.c
@@ -66,7 +66,7 @@ void dbfs_inode_free(struct dbfs_inode *ino)
g_free(ino);
}
-static int dbfs_inode_del(struct dbfs_inode *ino)
+int dbfs_inode_del(struct dbfs_inode *ino)
{
guint64 ino_n = GUINT64_FROM_LE(ino->raw_inode->ino);
char key[32];
@@ -549,6 +549,25 @@ int dbfs_symlink_read(guint64 ino, DBT *val)
return rc ? -EIO : 0;
}
+int dbfs_symlink_write(guint64 ino, const char *link)
+{
+ DBT key, val;
+ char key_str[32];
+
+ memset(&key, 0, sizeof(key));
+ memset(&val, 0, sizeof(val));
+
+ sprintf(key_str, "/symlink/%Lu", (unsigned long long) ino);
+
+ key.data = key_str;
+ key.size = strlen(key_str);
+
+ val.data = (void *) link;
+ val.size = strlen(link);
+
+ return gfs->meta->put(gfs->meta, NULL, &key, &val, 0) ? -EIO : 0;
+}
+
int dbfs_unlink(guint64 parent, const char *name, unsigned long flags)
{
struct dbfs_inode *ino;
diff --git a/dbfs.c b/dbfs.c
index d68ade9..1d4f7ab 100644
--- a/dbfs.c
+++ b/dbfs.c
@@ -10,6 +10,30 @@
#include <db.h>
#include "dbfs.h"
+static void dbfs_fill_ent(const struct dbfs_inode *ino,
+ struct fuse_entry_param *ent)
+{
+ memset(ent, 0, sizeof(*ent));
+
+ ent->ino = GUINT64_FROM_LE(ino->raw_inode->ino);
+ ent->generation = GUINT64_FROM_LE(ino->raw_inode->version);
+
+ /* these timeouts are just a guess */
+ ent->attr_timeout = 2.0;
+ ent->entry_timeout = 2.0;
+}
+
+static void dbfs_reply_ino(fuse_req_t req, struct dbfs_inode *ino)
+{
+ struct fuse_entry_param ent;
+
+ dbfs_fill_ent(ino, &ent);
+
+ fuse_reply_entry(req, &ent);
+
+ dbfs_inode_free(ino);
+}
+
static void dbfs_op_init(void *userdata)
{
struct dbfs **fs_io = userdata;
@@ -38,25 +62,25 @@ static void dbfs_op_destroy(void *userdata)
static void dbfs_op_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
{
- struct fuse_entry_param e;
- guint64 ino;
+ guint64 ino_n;
+ struct dbfs_inode *ino;
int rc;
/* lookup inode in parent directory */
- rc = dbfs_dir_lookup(parent, name, &ino);
+ rc = dbfs_dir_lookup(parent, name, &ino_n);
if (rc) {
- fuse_reply_err(req, rc);
+ fuse_reply_err(req, -rc);
return;
}
- /* send reply; timeout of 2.0 is just a guess */
-
- memset(&e, 0, sizeof(e));
- e.ino = ino;
- e.attr_timeout = 2.0;
- e.entry_timeout = 2.0;
+ rc = dbfs_inode_read(ino_n, &ino);
+ if (rc) {
+ fuse_reply_err(req, -rc);
+ return;
+ }
- fuse_reply_entry(req, &e);
+ /* send reply */
+ dbfs_reply_ino(req, ino);
}
static void dbfs_op_getattr(fuse_req_t req, fuse_ino_t ino_n,
@@ -106,7 +130,7 @@ static void dbfs_op_readlink(fuse_req_t req, fuse_ino_t ino)
/* read link from database */
rc = dbfs_symlink_read(ino, &val);
if (rc) {
- fuse_reply_err(req, rc);
+ fuse_reply_err(req, -rc);
return;
}
@@ -158,31 +182,22 @@ static int dbfs_mode_validate(mode_t mode)
static void dbfs_op_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode, dev_t rdev)
{
- struct fuse_entry_param ent;
struct dbfs_inode *ino;
int rc;
rc = dbfs_mode_validate(mode);
if (rc) {
- fuse_reply_err(req, rc);
+ fuse_reply_err(req, -rc);
return;
}
rc = dbfs_mknod(parent, name, mode, rdev, &ino);
if (rc) {
- fuse_reply_err(req, rc);
+ fuse_reply_err(req, -rc);
return;
}
- memset(&ent, 0, sizeof(ent));
- ent.ino = GUINT64_FROM_LE(ino->raw_inode->ino);
- ent.generation = GUINT64_FROM_LE(ino->raw_inode->version);
- ent.attr_timeout = 2.0;
- ent.entry_timeout = 2.0;
-
- fuse_reply_entry(req, &ent);
-
- dbfs_inode_free(ino);
+ dbfs_reply_ino(req, ino);
}
static void dbfs_op_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
@@ -198,7 +213,7 @@ static void dbfs_op_unlink(fuse_req_t req, fuse_ino_t parent, const char *name)
{
int rc = dbfs_unlink(parent, name, 0);
if (rc)
- fuse_reply_err(req, rc);
+ fuse_reply_err(req, -rc);
}
static int dbfs_chk_empty(struct dbfs_dirent *de, void *userdata)
@@ -242,7 +257,37 @@ static void dbfs_op_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
return;
err_out:
- fuse_reply_err(req, rc);
+ fuse_reply_err(req, -rc);
+}
+
+static void dbfs_op_symlink(fuse_req_t req, const char *link,
+ fuse_ino_t parent, const char *name)
+{
+ struct dbfs_inode *ino;
+ int rc;
+
+ if (!g_utf8_validate(link, -1, NULL)) {
+ rc = -EINVAL;
+ goto err_out;
+ }
+
+ rc = dbfs_mknod(parent, name,
+ S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO, 0, &ino);
+ if (rc)
+ goto err_out;
+
+ rc = dbfs_symlink_write(GUINT64_FROM_LE(ino->raw_inode->ino), link);
+ if (rc)
+ goto err_out_mknod;
+
+ dbfs_reply_ino(req, ino);
+ return;
+
+err_out_mknod:
+ dbfs_inode_del(ino);
+ dbfs_inode_free(ino);
+err_out:
+ fuse_reply_err(req, -rc);
}
static void dbfs_op_opendir(fuse_req_t req, fuse_ino_t ino,
@@ -254,7 +299,7 @@ static void dbfs_op_opendir(fuse_req_t req, fuse_ino_t ino,
/* read directory from database */
rc = dbfs_dir_read(ino, &val);
if (rc) {
- fuse_reply_err(req, rc);
+ fuse_reply_err(req, -rc);
return;
}
@@ -348,7 +393,7 @@ static struct fuse_lowlevel_ops dbfs_ops = {
.mkdir = dbfs_op_mkdir,
.unlink = dbfs_op_unlink,
.rmdir = dbfs_op_rmdir,
- .symlink = NULL,
+ .symlink = dbfs_op_symlink,
.rename = NULL,
.link = NULL,
.open = NULL,
diff --git a/dbfs.h b/dbfs.h
index fd93362..773cd6e 100644
--- a/dbfs.h
+++ b/dbfs.h
@@ -88,6 +88,8 @@ extern void dbfs_exit(void *userdata);
extern int dbfs_mknod(guint64 parent, const char *name,
guint32 mode, guint64 rdev,
struct dbfs_inode **ino);
+extern int dbfs_symlink_write(guint64 ino, const char *link);
+extern int dbfs_inode_del(struct dbfs_inode *ino);
extern int dbfs_open(struct dbfs *fs);
extern void dbfs_close(struct dbfs *fs);
diff --git a/libdbfs.c b/libdbfs.c
index f9fbab4..7397ca7 100644
--- a/libdbfs.c
+++ b/libdbfs.c
@@ -123,7 +123,7 @@ struct dbfs *dbfs_new(void)
return NULL;
fs->next_inode = 2ULL;
-
+
fs->home = getenv("DB_HOME");
if (!fs->home)
goto err_out;