aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-04-24 05:16:52 -0400
committerJeff Garzik <jeff@garzik.org>2006-04-24 05:16:52 -0400
commite23860dea35c1c84f33e08c8c0aba6db2f0bf3a6 (patch)
treedd2f01834c1723882245613ebf631fb1a7542a4c
parent1d95e3a8359c0153a0e86d9b975caec220fb4cda (diff)
downloaddbfs-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.c68
-rw-r--r--dbfs.c39
-rw-r--r--dbfs.h4
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;
}
diff --git a/dbfs.c b/dbfs.c
index 46ed3bf..3a2d2e4 100644
--- a/dbfs.c
+++ b/dbfs.c
@@ -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);
}
diff --git a/dbfs.h b/dbfs.h
index 60d7926..e391a75 100644
--- a/dbfs.h
+++ b/dbfs.h
@@ -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__ */