diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-04-25 02:22:04 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-25 02:22:04 -0400 |
commit | 912a0c8b977e584cb2b8c46526d036cc3ca103a2 (patch) | |
tree | 9c93e812094be379cff5591648e78ab984f57073 | |
parent | 4cbee76eb49cbdd68367fd9ef2ce31eb8ca61efd (diff) | |
download | dbfs-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.c | 21 | ||||
-rw-r--r-- | dbfs.c | 101 | ||||
-rw-r--r-- | dbfs.h | 2 | ||||
-rw-r--r-- | libdbfs.c | 2 |
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; @@ -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, @@ -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); @@ -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; |