diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-04-24 05:16:52 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-24 05:16:52 -0400 |
commit | e23860dea35c1c84f33e08c8c0aba6db2f0bf3a6 (patch) | |
tree | dd2f01834c1723882245613ebf631fb1a7542a4c | |
parent | 1d95e3a8359c0153a0e86d9b975caec220fb4cda (diff) | |
download | dbfs-e23860dea35c1c84f33e08c8c0aba6db2f0bf3a6.tar.gz |
dbfs: implement inode_write, several fixes and cleanups
- implement dbfs_inode_write
- leave raw inode in little endian in-core, swapping only when needed
- canonicalize several database I/O functions to return -EIO on error
- implement dbfs_inode_free() helper, since inode alloc is more complex now
- fix rmdir op
-rw-r--r-- | dbfs-backend.c | 68 | ||||
-rw-r--r-- | dbfs.c | 39 | ||||
-rw-r--r-- | dbfs.h | 4 |
3 files changed, 55 insertions, 56 deletions
diff --git a/dbfs-backend.c b/dbfs-backend.c index ec2e1ee..986324d 100644 --- a/dbfs-backend.c +++ b/dbfs-backend.c @@ -36,6 +36,12 @@ void dbfs_dummy1(void) (void) db_data; } +void dbfs_inode_free(struct dbfs_inode *ino) +{ + free(ino->raw_inode); + g_free(ino); +} + static int dbfs_inode_del(guint64 ino_n) { /* FIXME */ @@ -44,8 +50,23 @@ static int dbfs_inode_del(guint64 ino_n) static int dbfs_inode_write(struct dbfs_inode *ino) { - /* FIXME */ - return -EIO; + struct dbfs_raw_inode *raw_ino = ino->raw_inode; + guint64 ino_n = GUINT64_FROM_LE(ino->raw_inode->ino); + DBT key, val; + char key_str[32]; + + memset(&key, 0, sizeof(key)); + memset(&val, 0, sizeof(val)); + + sprintf(key_str, "/inode/%Lu", (unsigned long long) ino_n); + + key.data = key_str; + key.size = strlen(key_str); + + val.data = raw_ino; + val.size = ino->raw_ino_size; + + return db_meta->get(db_meta, NULL, &key, &val, 0) ? -EIO : 0; } int dbfs_inode_read(guint64 ino_n, struct dbfs_inode **ino_out) @@ -53,9 +74,8 @@ int dbfs_inode_read(guint64 ino_n, struct dbfs_inode **ino_out) int rc; DBT key, val; char key_str[32]; - struct dbfs_raw_inode *raw_ino; struct dbfs_inode *ino; - size_t ex_sz, i; + size_t ex_sz; memset(&key, 0, sizeof(key)); memset(&val, 0, sizeof(val)); @@ -73,30 +93,15 @@ int dbfs_inode_read(guint64 ino_n, struct dbfs_inode **ino_out) if (rc) return rc; - raw_ino = val.data; - raw_ino->ino = GUINT64_FROM_LE(raw_ino->ino); - raw_ino->generation = GUINT64_FROM_LE(raw_ino->generation); - raw_ino->mode = GUINT32_FROM_LE(raw_ino->mode); - raw_ino->nlink = GUINT32_FROM_LE(raw_ino->nlink); - raw_ino->uid = GUINT32_FROM_LE(raw_ino->uid); - raw_ino->gid = GUINT32_FROM_LE(raw_ino->gid); - raw_ino->rdev = GUINT64_FROM_LE(raw_ino->rdev); - raw_ino->size = GUINT64_FROM_LE(raw_ino->size); - raw_ino->ctime = GUINT64_FROM_LE(raw_ino->ctime); - raw_ino->atime = GUINT64_FROM_LE(raw_ino->atime); - raw_ino->mtime = GUINT64_FROM_LE(raw_ino->mtime); - ex_sz = val.size - sizeof(struct dbfs_raw_inode); - i = sizeof(struct dbfs_inode) - sizeof(struct dbfs_raw_inode); - ino = g_malloc(i + ex_sz + sizeof(struct dbfs_raw_inode)); - memcpy(&ino->raw_inode, raw_ino, val.size); + ino = g_new(struct dbfs_inode, 1); ino->n_extents = ex_sz / sizeof(struct dbfs_extent); + ino->raw_ino_size = val.size; + ino->raw_inode = val.data; *ino_out = ino; - free(val.data); - return 0; } @@ -119,7 +124,7 @@ int dbfs_read_dir(guint64 ino, DBT *val) rc = db_meta->get(db_meta, NULL, &key, val, 0); if (rc == DB_NOTFOUND) return -ENOTDIR; - return rc; + return rc ? -EIO : 0; } static int dbfs_write_dir(guint64 ino, DBT *val) @@ -134,7 +139,7 @@ static int dbfs_write_dir(guint64 ino, DBT *val) key.data = key_str; key.size = strlen(key_str); - return db_meta->put(db_meta, NULL, &key, val, 0); + return db_meta->put(db_meta, NULL, &key, val, 0) ? -EIO : 0; } int dbfs_read_link(guint64 ino, DBT *val) @@ -156,7 +161,7 @@ int dbfs_read_link(guint64 ino, DBT *val) rc = db_meta->get(db_meta, NULL, &key, val, 0); if (rc == DB_NOTFOUND) return -EINVAL; - return rc; + return rc ? -EIO : 0; } int dbfs_dir_foreach(void *dir, dbfs_dir_actor_t func, void *userdata) @@ -281,6 +286,7 @@ int dbfs_unlink(guint64 parent, const char *name, unsigned long flags) struct dbfs_inode *ino; guint64 ino_n; int rc, is_dir; + guint32 nlink; rc = dbfs_lookup(parent, name, &ino_n); if (rc) @@ -290,7 +296,7 @@ int dbfs_unlink(guint64 parent, const char *name, unsigned long flags) if (rc) goto out; - is_dir = S_ISDIR(ino->raw_inode.mode); + is_dir = S_ISDIR(GUINT32_FROM_LE(ino->raw_inode->mode)); if (is_dir && (!(flags & DBFS_UNLINK_DIR))) { rc = -EISDIR; goto out_ino; @@ -300,16 +306,18 @@ int dbfs_unlink(guint64 parent, const char *name, unsigned long flags) if (rc) goto out_ino; - ino->raw_inode.nlink--; + nlink = GUINT32_FROM_LE(ino->raw_inode->nlink); + nlink--; + ino->raw_inode->nlink = GUINT32_TO_LE(nlink); - if ((is_dir && (ino->raw_inode.nlink < 2)) || - (!is_dir && (ino->raw_inode.nlink < 1))) + if ((is_dir && (nlink < 2)) || + (!is_dir && (nlink < 1))) rc = dbfs_inode_del(ino_n); else rc = dbfs_inode_write(ino); out_ino: - g_free(ino); + dbfs_inode_free(ino); out: return rc; } @@ -29,21 +29,21 @@ static void dbfs_op_getattr(fuse_req_t req, fuse_ino_t ino_n, memset(&st, 0, sizeof(st)); st.st_dev = 1; st.st_ino = ino_n; - st.st_mode = ino->raw_inode.mode; - st.st_nlink = ino->raw_inode.nlink; - st.st_uid = ino->raw_inode.uid; - st.st_gid = ino->raw_inode.gid; - st.st_rdev = ino->raw_inode.rdev; - st.st_size = ino->raw_inode.size; + st.st_mode = GUINT32_FROM_LE(ino->raw_inode->mode); + st.st_nlink = GUINT32_FROM_LE(ino->raw_inode->nlink); + st.st_uid = GUINT32_FROM_LE(ino->raw_inode->uid); + st.st_gid = GUINT32_FROM_LE(ino->raw_inode->gid); + st.st_rdev = GUINT64_FROM_LE(ino->raw_inode->rdev); + st.st_size = GUINT64_FROM_LE(ino->raw_inode->size); st.st_blksize = 512; - st.st_blocks = ino->raw_inode.size / 512; - st.st_atime = ino->raw_inode.atime; - st.st_mtime = ino->raw_inode.mtime; - st.st_ctime = ino->raw_inode.ctime; + st.st_blocks = GUINT64_FROM_LE(ino->raw_inode->size) / 512; + st.st_atime = GUINT64_FROM_LE(ino->raw_inode->atime); + st.st_mtime = GUINT64_FROM_LE(ino->raw_inode->mtime); + st.st_ctime = GUINT64_FROM_LE(ino->raw_inode->ctime); fuse_reply_attr(req, &st, 1.0); - g_free(ino); + dbfs_inode_free(ino); } static void dbfs_op_readlink(fuse_req_t req, fuse_ino_t ino) @@ -180,7 +180,6 @@ static void dbfs_op_unlink(fuse_req_t req, fuse_ino_t parent, const char *name) static void dbfs_op_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name) { - struct dbfs_inode *ino; guint64 ino_n; int rc; DBT val; @@ -189,32 +188,22 @@ static void dbfs_op_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name) if (rc) goto err_out; - rc = dbfs_inode_read(ino_n, &ino); + rc = dbfs_read_dir(ino_n, &val); if (rc) goto err_out; - if (!S_ISDIR(ino->raw_inode.mode)) { - rc = ENOTDIR; - goto err_out_free; - } - - rc = dbfs_read_dir(parent, &val); - if (rc) - goto err_out_free; rc = dbfs_dir_foreach(val.data, dbfs_chk_empty, NULL); free(val.data); if (rc) - goto err_out_free; + goto err_out; rc = dbfs_unlink(parent, name, DBFS_UNLINK_DIR); if (rc) - goto err_out_free; + goto err_out; return; -err_out_free: - g_free(ino); err_out: fuse_reply_err(req, rc); } @@ -45,7 +45,8 @@ struct dbfs_raw_inode { struct dbfs_inode { unsigned int n_extents; - struct dbfs_raw_inode raw_inode; + unsigned int raw_ino_size; + struct dbfs_raw_inode *raw_inode; }; @@ -57,5 +58,6 @@ extern int dbfs_read_link(guint64 ino, DBT *val); extern int dbfs_dir_foreach(void *dir, dbfs_dir_actor_t func, void *userdata); extern int dbfs_lookup(guint64 parent, const char *name, guint64 *ino); extern int dbfs_unlink(guint64 parent, const char *name, unsigned long flags); +extern void dbfs_inode_free(struct dbfs_inode *ino); #endif /* __DBFS_H__ */ |