aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-07-16 16:00:31 -0400
committerJeff Garzik <jeff@garzik.org>2006-07-16 16:00:31 -0400
commit07198510282ae91bbe7e3b477669c69b921d43c5 (patch)
tree681c245603592e2ebaa50bf7a4e69debcef0cb56
parentff073e02a9839f6a6cfdbde60e10e11df9cd187c (diff)
downloaddbfs-07198510282ae91bbe7e3b477669c69b921d43c5.tar.gz
Fix alignment bug. Add security FIXME. Add SCHEMA describing db layout.
-rw-r--r--Makefile.am2
-rw-r--r--SCHEMA67
-rw-r--r--dbfs-backend.c12
-rw-r--r--dbfs.h9
-rw-r--r--libdbfs.c11
-rw-r--r--mkdbfs.c2
6 files changed, 86 insertions, 17 deletions
diff --git a/Makefile.am b/Makefile.am
index cf1db27..cbc139d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,5 +16,5 @@ dbfs_LDADD = @GLIB_LIBS@ @FUSE_LIBS@ @DB_LIBS@ libdbfs.a
mkdbfs_SOURCES = mkdbfs.c
mkdbfs_LDADD = @GLIB_LIBS@ @DB_LIBS@ libdbfs.a
-EXTRA_DIST = autogen.sh
+EXTRA_DIST = autogen.sh SCHEMA
diff --git a/SCHEMA b/SCHEMA
new file mode 100644
index 0000000..aa8ca0e
--- /dev/null
+++ b/SCHEMA
@@ -0,0 +1,67 @@
+
+ Berkeley DB database schema for filesystem
+ ------------------------------------------
+
+
+
+system environment variables:
+DB_HOME: database home dir, for transaction database + logs
+DB_PASSWORD: if present, AES-encrypt database with this password
+
+db4 environment
+---------------
+ "metadata": metadata database
+ page size 512
+ little endian byte order
+ optionally encrypted w/ DB4 AES encryption
+
+inode
+-----
+key: /inode/%Lu (%Lu == inode number)
+
+value record's fields (all little endian):
+
+struct dbfs_raw_inode:
+guint64 ino: inode number (identity)
+guint64 version: linear sequence number, starts @ 1
+guint32 mode: unix mode_t
+guint32 nlink: number of hard links
+guint32 uid: unix user id
+guint32 gid: unix group id
+guint64 rdev: unix dev_t
+guint64 size: inode data size, in bytes
+guint64 ctime: file creation time
+guint64 atime: file last-accessed time
+guint64 mtime: file last-modified time
+struct dbfs_extent blocks[0]: array of extents, describing inode data
+
+struct dbfs_extent:
+dbfs_blk_id_t id: 20-byte sha1 hash of data
+guint64 size: size of data block
+
+
+directories
+-----------
+An array of struct dbfs_dirent, aligned on DBFS_DIRENT_ALIGN bounds.
+
+key: /dir/%Lu inode number associated with this dir
+
+struct dbfs_dirent:
+guint32 magic: magic number (0xd4d4d4d4U)
+guint16 res2: reserved for future use
+guint16 namelen: length of final filename component
+guint64 ino: inode number of referenced inode
+char name[0]: UTF8 final filename component (namelen bytes)
+0-7 bytes alignment padding
+
+The array of struct dbfs_direct is terminated by a final dbfs_dirent
+containing a zero-length name (namelen==0).
+
+
+symbolic links
+--------------
+key: /symlink/%Lu inode number associated with this symlink
+
+value: UTF8 string, containing link text (variable length)
+
+
diff --git a/dbfs-backend.c b/dbfs-backend.c
index bee74f1..b4d7c44 100644
--- a/dbfs-backend.c
+++ b/dbfs-backend.c
@@ -237,8 +237,7 @@ int dbfs_dir_foreach(void *dir, dbfs_dir_actor_t func, void *userdata)
* do not wind up misaligned.
*/
namelen = GUINT16_FROM_LE(de->namelen);
- p += sizeof(struct dbfs_dirent) + namelen +
- (4 - (namelen & 0x3));
+ p += dbfs_dirent_next(namelen);
}
return rc;
@@ -374,8 +373,7 @@ static int dbfs_dir_append(guint64 parent, guint64 ino_n, const char *name)
/* adjust pointer 'p' to point to terminator entry */
de = p = di.end_ent;
namelen = GUINT16_FROM_LE(de->namelen);
- p += sizeof(struct dbfs_dirent) + namelen +
- (4 - (namelen & 0x3));
+ p += dbfs_dirent_next(namelen);
/* increase directory data area size */
dir_size = p - val.data;
@@ -391,8 +389,7 @@ static int dbfs_dir_append(guint64 parent, guint64 ino_n, const char *name)
memcpy(de->name, name, di.namelen);
namelen = di.namelen;
- p += sizeof(struct dbfs_dirent) + namelen +
- (4 - (namelen & 0x3));
+ p += dbfs_dirent_next(namelen);
/* append terminator entry */
de = p;
@@ -400,8 +397,7 @@ static int dbfs_dir_append(guint64 parent, guint64 ino_n, const char *name)
de->magic = GUINT32_TO_LE(DBFS_DE_MAGIC);
namelen = 0;
- p += sizeof(struct dbfs_dirent) + namelen +
- (4 - (namelen & 0x3));
+ p += dbfs_dirent_next(namelen);
val.size = p - val.data;
diff --git a/dbfs.h b/dbfs.h
index 02f7342..0803156 100644
--- a/dbfs.h
+++ b/dbfs.h
@@ -3,12 +3,16 @@
#include <glib.h>
+#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
+
enum {
DBFS_BLK_ID_LEN = 20,
DBFS_UNLINK_DIR = (1 << 0),
DBFS_ROOT_INO = 1,
+
+ DBFS_DIRENT_ALIGN = 8,
};
enum {
@@ -102,4 +106,9 @@ extern int dbfs_dir_new(guint64 parent, guint64 ino_n, const struct dbfs_inode *
extern int dbfs_dir_write(guint64 ino, DBT *val);
extern void dbfs_inode_free(struct dbfs_inode *ino);
+static inline size_t dbfs_dirent_next(guint16 namelen)
+{
+ return ALIGN(sizeof(struct dbfs_dirent) + namelen, DBFS_DIRENT_ALIGN);
+}
+
#endif /* __DBFS_H__ */
diff --git a/libdbfs.c b/libdbfs.c
index 1c28f03..9b4d878 100644
--- a/libdbfs.c
+++ b/libdbfs.c
@@ -132,7 +132,7 @@ struct dbfs *dbfs_new(void)
if (passwd) {
fs->passwd = strdup(passwd);
- /* this isn't a very good way to shroud the password */
+ /* FIXME: this isn't a very good way to shroud the password */
if (putenv("DB_PASSWORD=X"))
perror("putenv DB_PASSWORD (SECURITY WARNING)");
}
@@ -202,8 +202,7 @@ int dbfs_dir_new(guint64 parent, guint64 ino_n, const struct dbfs_inode *ino)
memcpy(q, ".", 1);
namelen = GUINT16_FROM_LE(de->namelen);
- p += sizeof(struct dbfs_dirent) + namelen +
- (4 - (namelen & 0x3));
+ p += dbfs_dirent_next(namelen);
/*
* add entry for ".."
@@ -217,8 +216,7 @@ int dbfs_dir_new(guint64 parent, guint64 ino_n, const struct dbfs_inode *ino)
memcpy(q, "..", 2);
namelen = GUINT16_FROM_LE(de->namelen);
- p += sizeof(struct dbfs_dirent) + namelen +
- (4 - (namelen & 0x3));
+ p += dbfs_dirent_next(namelen);
/*
* add terminating entry
@@ -227,8 +225,7 @@ int dbfs_dir_new(guint64 parent, guint64 ino_n, const struct dbfs_inode *ino)
de->magic = GUINT32_TO_LE(DBFS_DE_MAGIC);
namelen = GUINT16_FROM_LE(de->namelen);
- p += sizeof(struct dbfs_dirent) + namelen +
- (4 - (namelen & 0x3));
+ p += dbfs_dirent_next(namelen);
/*
* store dir in database
diff --git a/mkdbfs.c b/mkdbfs.c
index 524fb1d..8670c2a 100644
--- a/mkdbfs.c
+++ b/mkdbfs.c
@@ -48,7 +48,7 @@ void create_db(void)
goto err_out;
}
- /* this isn't a very good way to shroud the password */
+ /* FIXME: this isn't a very good way to shroud the password */
if (putenv("DB_PASSWORD=X"))
perror("putenv (SECURITY WARNING)");
}