diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-07-16 16:00:31 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-07-16 16:00:31 -0400 |
commit | 07198510282ae91bbe7e3b477669c69b921d43c5 (patch) | |
tree | 681c245603592e2ebaa50bf7a4e69debcef0cb56 | |
parent | ff073e02a9839f6a6cfdbde60e10e11df9cd187c (diff) | |
download | dbfs-07198510282ae91bbe7e3b477669c69b921d43c5.tar.gz |
Fix alignment bug. Add security FIXME. Add SCHEMA describing db layout.
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | SCHEMA | 67 | ||||
-rw-r--r-- | dbfs-backend.c | 12 | ||||
-rw-r--r-- | dbfs.h | 9 | ||||
-rw-r--r-- | libdbfs.c | 11 | ||||
-rw-r--r-- | mkdbfs.c | 2 |
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 @@ -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; @@ -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__ */ @@ -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 @@ -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)"); } |