aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-04-25 02:56:24 -0400
committerJeff Garzik <jeff@garzik.org>2006-04-25 02:56:24 -0400
commit4158bad935569acb91d0eb68923bb155ee9e16f5 (patch)
tree1faf675f69d3798db04ce81d9037b49f8f8ad1db
parent912a0c8b977e584cb2b8c46526d036cc3ca103a2 (diff)
downloaddbfs-4158bad935569acb91d0eb68923bb155ee9e16f5.tar.gz
mkdbfs: write root directory. Also, make libdbfs a proper lib.
Move some functions over to libdbfs from dbfs-backend.c.
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am10
-rw-r--r--dbfs-backend.c115
-rw-r--r--dbfs.h7
-rw-r--r--libdbfs.c110
-rw-r--r--mkdbfs.c86
6 files changed, 182 insertions, 147 deletions
diff --git a/.gitignore b/.gitignore
index d9aea70..11fed36 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,5 +23,6 @@ stamp-h1
mkdbfs
dbfs
dbfs-config.h*
+libdbfs.a
fuse-db-*.tar.gz
diff --git a/Makefile.am b/Makefile.am
index 2045d80..cf1db27 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,13 +4,17 @@
INCLUDES = @GLIB_CFLAGS@ @FUSE_CFLAGS@
+noinst_LIBRARIES = libdbfs.a
+
sbin_PROGRAMS = dbfs mkdbfs
-dbfs_SOURCES = dbfs.c dbfs.h dbfs-backend.c libdbfs.c
-dbfs_LDADD = @GLIB_LIBS@ @FUSE_LIBS@ @DB_LIBS@
+libdbfs_a_SOURCES = libdbfs.c
+
+dbfs_SOURCES = dbfs.c dbfs.h dbfs-backend.c
+dbfs_LDADD = @GLIB_LIBS@ @FUSE_LIBS@ @DB_LIBS@ libdbfs.a
mkdbfs_SOURCES = mkdbfs.c
-mkdbfs_LDADD = @DB_LIBS@
+mkdbfs_LDADD = @GLIB_LIBS@ @DB_LIBS@ libdbfs.a
EXTRA_DIST = autogen.sh
diff --git a/dbfs-backend.c b/dbfs-backend.c
index 19ba273..bee74f1 100644
--- a/dbfs-backend.c
+++ b/dbfs-backend.c
@@ -60,12 +60,6 @@ static int dbfs_mode_type(guint32 mode, enum dbfs_inode_type *itype)
return 0;
}
-void dbfs_inode_free(struct dbfs_inode *ino)
-{
- free(ino->raw_inode);
- g_free(ino);
-}
-
int dbfs_inode_del(struct dbfs_inode *ino)
{
guint64 ino_n = GUINT64_FROM_LE(ino->raw_inode->ino);
@@ -105,30 +99,6 @@ int dbfs_inode_del(struct dbfs_inode *ino)
return rrc;
}
-static int dbfs_inode_write(struct dbfs_inode *ino)
-{
- 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;
-
- raw_ino->version = GUINT64_TO_LE(
- GUINT64_FROM_LE(raw_ino->version) + 1);
-
- return gfs->meta->get(gfs->meta, NULL, &key, &val, 0) ? -EIO : 0;
-}
-
int dbfs_inode_read(guint64 ino_n, struct dbfs_inode **ino_out)
{
int rc;
@@ -243,21 +213,6 @@ int dbfs_dir_read(guint64 ino, DBT *val)
return rc ? -EIO : 0;
}
-static int dbfs_dir_write(guint64 ino, DBT *val)
-{
- DBT key;
- char key_str[32];
-
- memset(&key, 0, sizeof(key));
-
- sprintf(key_str, "/dir/%Lu", (unsigned long long) ino);
-
- key.data = key_str;
- key.size = strlen(key_str);
-
- return gfs->meta->put(gfs->meta, NULL, &key, val, 0) ? -EIO : 0;
-}
-
int dbfs_dir_foreach(void *dir, dbfs_dir_actor_t func, void *userdata)
{
struct dbfs_dirent *de;
@@ -376,76 +331,6 @@ static int dbfs_dirent_del(guint64 parent, const char *name)
return rc;
}
-static int dbfs_dir_new(guint64 parent, guint64 ino_n, struct dbfs_inode *ino)
-{
- void *mem, *p, *q;
- struct dbfs_dirent *de;
- size_t namelen;
- DBT val;
- int rc;
-
- p = mem = malloc(128);
- memset(mem, 0, 128);
-
- /*
- * add entry for "."
- */
- de = p;
- de->magic = GUINT32_TO_LE(DBFS_DE_MAGIC);
- de->namelen = GUINT16_TO_LE(1);
- de->ino = GUINT64_TO_LE(ino_n);
-
- q = p + sizeof(struct dbfs_dirent);
- memcpy(q, ".", 1);
-
- namelen = GUINT16_FROM_LE(de->namelen);
- p += sizeof(struct dbfs_dirent) + namelen +
- (4 - (namelen & 0x3));
-
- /*
- * add entry for ".."
- */
- de = p;
- de->magic = GUINT32_TO_LE(DBFS_DE_MAGIC);
- de->namelen = GUINT16_TO_LE(2);
- de->ino = GUINT64_TO_LE(parent);
-
- q = p + sizeof(struct dbfs_dirent);
- memcpy(q, "..", 2);
-
- namelen = GUINT16_FROM_LE(de->namelen);
- p += sizeof(struct dbfs_dirent) + namelen +
- (4 - (namelen & 0x3));
-
- /*
- * add terminating entry
- */
- de = p;
- de->magic = GUINT32_TO_LE(DBFS_DE_MAGIC);
-
- namelen = GUINT16_FROM_LE(de->namelen);
- p += sizeof(struct dbfs_dirent) + namelen +
- (4 - (namelen & 0x3));
-
- /*
- * store dir in database
- */
- memset(&val, 0, sizeof(val));
- val.data = mem;
- val.size = p - mem;
-
- rc = dbfs_dir_write(ino_n, &val);
- if (rc) {
- dbfs_inode_del(ino);
- dbfs_inode_free(ino);
- return rc;
- }
-
- free(mem);
-
- return 0;
-}
-
static int dbfs_dir_find_last(struct dbfs_dirent *de, void *userdata)
{
struct dbfs_dirscan_info *di = userdata;
diff --git a/dbfs.h b/dbfs.h
index 773cd6e..b38ad11 100644
--- a/dbfs.h
+++ b/dbfs.h
@@ -76,13 +76,13 @@ struct dbfs {
typedef int (*dbfs_dir_actor_t) (struct dbfs_dirent *, void *);
+/* dbfs-backend.c */
extern int dbfs_inode_read(guint64 ino_n, struct dbfs_inode **ino_out);
extern int dbfs_dir_read(guint64 ino, DBT *val);
extern int dbfs_symlink_read(guint64 ino, DBT *val);
extern int dbfs_dir_foreach(void *dir, dbfs_dir_actor_t func, void *userdata);
extern int dbfs_dir_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);
extern void dbfs_init(void *userdata);
extern void dbfs_exit(void *userdata);
extern int dbfs_mknod(guint64 parent, const char *name,
@@ -91,10 +91,15 @@ extern int dbfs_mknod(guint64 parent, const char *name,
extern int dbfs_symlink_write(guint64 ino, const char *link);
extern int dbfs_inode_del(struct dbfs_inode *ino);
+/* libdbfs.c */
extern int dbfs_open(struct dbfs *fs);
extern void dbfs_close(struct dbfs *fs);
extern struct dbfs *dbfs_new(void);
extern void dbfs_free(struct dbfs *fs);
extern struct dbfs *gfs;
+extern int dbfs_inode_write(struct dbfs_inode *ino);
+extern int dbfs_dir_new(guint64 parent, guint64 ino_n, const struct dbfs_inode *ino);
+extern int dbfs_dir_write(guint64 ino, DBT *val);
+extern void dbfs_inode_free(struct dbfs_inode *ino);
#endif /* __DBFS_H__ */
diff --git a/libdbfs.c b/libdbfs.c
index 7397ca7..d0eb239 100644
--- a/libdbfs.c
+++ b/libdbfs.c
@@ -147,3 +147,113 @@ void dbfs_free(struct dbfs *fs)
g_free(fs);
}
+void dbfs_inode_free(struct dbfs_inode *ino)
+{
+ free(ino->raw_inode);
+ g_free(ino);
+}
+
+int dbfs_inode_write(struct dbfs_inode *ino)
+{
+ 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;
+
+ raw_ino->version = GUINT64_TO_LE(
+ GUINT64_FROM_LE(raw_ino->version) + 1);
+
+ return gfs->meta->put(gfs->meta, NULL, &key, &val, 0) ? -EIO : 0;
+}
+
+int dbfs_dir_new(guint64 parent, guint64 ino_n, const struct dbfs_inode *ino)
+{
+ void *mem, *p, *q;
+ struct dbfs_dirent *de;
+ size_t namelen;
+ DBT val;
+ int rc;
+
+ p = mem = malloc(128);
+ memset(mem, 0, 128);
+
+ /*
+ * add entry for "."
+ */
+ de = p;
+ de->magic = GUINT32_TO_LE(DBFS_DE_MAGIC);
+ de->namelen = GUINT16_TO_LE(1);
+ de->ino = GUINT64_TO_LE(ino_n);
+
+ q = p + sizeof(struct dbfs_dirent);
+ memcpy(q, ".", 1);
+
+ namelen = GUINT16_FROM_LE(de->namelen);
+ p += sizeof(struct dbfs_dirent) + namelen +
+ (4 - (namelen & 0x3));
+
+ /*
+ * add entry for ".."
+ */
+ de = p;
+ de->magic = GUINT32_TO_LE(DBFS_DE_MAGIC);
+ de->namelen = GUINT16_TO_LE(2);
+ de->ino = GUINT64_TO_LE(parent);
+
+ q = p + sizeof(struct dbfs_dirent);
+ memcpy(q, "..", 2);
+
+ namelen = GUINT16_FROM_LE(de->namelen);
+ p += sizeof(struct dbfs_dirent) + namelen +
+ (4 - (namelen & 0x3));
+
+ /*
+ * add terminating entry
+ */
+ de = p;
+ de->magic = GUINT32_TO_LE(DBFS_DE_MAGIC);
+
+ namelen = GUINT16_FROM_LE(de->namelen);
+ p += sizeof(struct dbfs_dirent) + namelen +
+ (4 - (namelen & 0x3));
+
+ /*
+ * store dir in database
+ */
+ memset(&val, 0, sizeof(val));
+ val.data = mem;
+ val.size = p - mem;
+
+ rc = dbfs_dir_write(ino_n, &val);
+
+ free(mem);
+
+ return rc;
+}
+
+int dbfs_dir_write(guint64 ino, DBT *val)
+{
+ DBT key;
+ char key_str[32];
+
+ memset(&key, 0, sizeof(key));
+
+ sprintf(key_str, "/dir/%Lu", (unsigned long long) ino);
+
+ key.data = key_str;
+ key.size = strlen(key_str);
+
+ return gfs->meta->put(gfs->meta, NULL, &key, val, 0) ? -EIO : 0;
+}
+
diff --git a/mkdbfs.c b/mkdbfs.c
index 2269e0b..524fb1d 100644
--- a/mkdbfs.c
+++ b/mkdbfs.c
@@ -5,14 +5,14 @@
#include <string.h>
#include <errno.h>
#include <unistd.h>
+#include <time.h>
#include <glib.h>
#include <db.h>
#include "dbfs.h"
-static DB_ENV *db_env;
-static DB *db_meta;
+struct dbfs *gfs;
-void dbfs_init(void *userdata)
+void create_db(void)
{
const char *db_home, *db_password;
int rc;
@@ -31,20 +31,20 @@ void dbfs_init(void *userdata)
/* this isn't a very secure way to handle passwords */
db_password = getenv("DB_PASSWORD");
- rc = db_env_create(&db_env, 0);
+ rc = db_env_create(&gfs->env, 0);
if (rc) {
- fprintf(stderr, "db_env_create failed: %d\n", rc);
+ fprintf(stderr, "gfs->env_create failed: %d\n", rc);
exit(1);
}
- db_env->set_errfile(db_env, stderr);
- db_env->set_errpfx(db_env, "dbfs");
+ gfs->env->set_errfile(gfs->env, stderr);
+ gfs->env->set_errpfx(gfs->env, "mkdbfs");
if (db_password) {
flags |= DB_ENCRYPT;
- rc = db_env->set_encrypt(db_env, db_password, DB_ENCRYPT_AES);
+ rc = gfs->env->set_encrypt(gfs->env, db_password, DB_ENCRYPT_AES);
if (rc) {
- db_env->err(db_env, rc, "db_env->set_encrypt");
+ gfs->env->err(gfs->env, rc, "gfs->env->set_encrypt");
goto err_out;
}
@@ -54,11 +54,11 @@ void dbfs_init(void *userdata)
}
/* init DB transactional environment, stored in directory db_home */
- rc = db_env->open(db_env, db_home,
+ rc = gfs->env->open(gfs->env, db_home,
DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL |
DB_INIT_TXN | DB_CREATE | flags, 0666);
if (rc) {
- db_env->err(db_env, rc, "db_env->open");
+ gfs->env->err(gfs->env, rc, "gfs->env->open");
goto err_out;
}
@@ -66,18 +66,18 @@ void dbfs_init(void *userdata)
* Open metadata database
*/
- rc = db_create(&db_meta, db_env, 0);
+ rc = db_create(&gfs->meta, gfs->env, 0);
if (rc) {
- db_env->err(db_env, rc, "db_create");
+ gfs->env->err(gfs->env, rc, "db_create");
goto err_out;
}
- rc = db_meta->open(db_meta, NULL, "metadata", NULL,
+ rc = gfs->meta->open(gfs->meta, NULL, "metadata", NULL,
DB_HASH,
DB_AUTO_COMMIT | DB_CREATE | DB_TRUNCATE | flags,
0666);
if (rc) {
- db_meta->err(db_meta, rc, "db_meta->open");
+ gfs->meta->err(gfs->meta, rc, "gfs->meta->open");
goto err_out_meta;
}
@@ -85,41 +85,71 @@ void dbfs_init(void *userdata)
* size. This is a guess, and should be verified by looking at
* overflow pages and other DB statistics.
*/
- rc = db_meta->set_pagesize(db_meta, 512);
+ rc = gfs->meta->set_pagesize(gfs->meta, 512);
if (rc) {
- db_meta->err(db_meta, rc, "db_meta->set_pagesize");
+ gfs->meta->err(gfs->meta, rc, "gfs->meta->set_pagesize");
goto err_out_meta;
}
/* fix everything as little endian */
- rc = db_meta->set_lorder(db_meta, 1234);
+ rc = gfs->meta->set_lorder(gfs->meta, 1234);
if (rc) {
- db_meta->err(db_meta, rc, "db_meta->set_lorder");
+ gfs->meta->err(gfs->meta, rc, "gfs->meta->set_lorder");
goto err_out_meta;
}
return;
err_out_meta:
- db_meta->close(db_meta, 0);
+ gfs->meta->close(gfs->meta, 0);
err_out:
- db_env->close(db_env, 0);
+ gfs->env->close(gfs->env, 0);
exit(1);
}
-void dbfs_exit(void *userdata)
+static void make_root_dir(void)
{
- db_meta->close(db_meta, 0);
- db_env->close(db_env, 0);
+ struct dbfs_inode *ino;
+ guint64 curtime;
+ int rc;
+
+ /* allocate an empty inode */
+ ino = g_new0(struct dbfs_inode, 1);
+ ino->raw_ino_size = sizeof(struct dbfs_raw_inode);
+ ino->raw_inode = malloc(ino->raw_ino_size);
+ memset(ino->raw_inode, 0, ino->raw_ino_size);
+
+ ino->raw_inode->ino = GUINT64_TO_LE(1);
+ ino->raw_inode->mode = GUINT32_TO_LE(S_IFDIR | 0755);
+ ino->raw_inode->nlink = GUINT32_TO_LE(2);
+ curtime = GUINT64_TO_LE(time(NULL));
+ ino->raw_inode->ctime = curtime;
+ ino->raw_inode->atime = curtime;
+ ino->raw_inode->mtime = curtime;
+
+ rc = dbfs_inode_write(ino);
+ if (rc)
+ goto err_die;
+
+ rc = dbfs_dir_new(1, 1, ino);
+ if (rc)
+ goto err_die;
+
+ dbfs_inode_free(ino);
+ return;
- db_env = NULL;
- db_meta = NULL;
+err_die:
+ errno = -rc;
+ perror("dbfs_inode_write");
+ exit(1);
}
int main (int argc, char *argv[])
{
- dbfs_init(NULL);
- dbfs_exit(NULL);
+ gfs = dbfs_new();
+ create_db();
+ make_root_dir();
+ dbfs_close(gfs);
return 0;
}