diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-04-25 02:56:24 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-25 02:56:24 -0400 |
commit | 4158bad935569acb91d0eb68923bb155ee9e16f5 (patch) | |
tree | 1faf675f69d3798db04ce81d9037b49f8f8ad1db | |
parent | 912a0c8b977e584cb2b8c46526d036cc3ca103a2 (diff) | |
download | dbfs-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-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile.am | 10 | ||||
-rw-r--r-- | dbfs-backend.c | 115 | ||||
-rw-r--r-- | dbfs.h | 7 | ||||
-rw-r--r-- | libdbfs.c | 110 | ||||
-rw-r--r-- | mkdbfs.c | 86 |
6 files changed, 182 insertions, 147 deletions
@@ -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; @@ -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__ */ @@ -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; +} + @@ -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; } |