#ifndef __DBFS_H__ #define __DBFS_H__ /* * Maintained by Jeff Garzik * * Copyright 2006-2007 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) enum { DBFS_BLK_ID_LEN = 20, /* block id (sha1 hash) len */ DBFS_UNLINK_DIR = (1 << 0), DBFS_ROOT_INO = 1, /* root inode number */ DBFS_DIRENT_ALIGN = 8, /* struct dbfs_dirent alignment */ DBFS_FILENAME_MAX = 256, /* max filename component size */ DBFS_XATTR_NAME_LEN = 256, /* extended attr limits */ DBFS_XATTR_MAX_LEN = (1024 * 1024), DBFS_XLIST_ALIGN = 8, /* struct dbfs_xlist alignment */ /* our data items are small, so use the smallest possible page * size. This is a guess, and should be verified by looking at * overflow pages and other DB statistics. */ DBFS_PGSZ_METADATA = 512, /* another guess. must take into account small data items * as well as large ones */ DBFS_PGSZ_DATA = 2048, DBFS_MAX_EXT_LEN = (4 * 1024 * 1024), /* max extent len */ DBFS_ZERO_CMP_BLK_SZ = 8192, }; enum { /* dirent magic number */ DBFS_DE_MAGIC = 0xd4d4d4d4U, }; enum dbfs_inode_type { IT_REG, IT_DIR, IT_DEV, IT_FIFO, IT_SYMLINK, IT_SOCKET }; typedef struct { char buf[DBFS_BLK_ID_LEN]; } dbfs_blk_id_t; struct dbfs_dirent { guint32 magic; guint16 res2; guint16 namelen; guint64 ino; char name[0]; } __attribute__ ((packed)); struct dbfs_xlist { guint32 namelen; char name[0]; } __attribute__ ((packed)); struct dbfs_extent { guint32 off; /* offset into block */ guint32 len; /* length of fragment */ dbfs_blk_id_t id; /* block id */ } __attribute__ ((packed)); struct dbfs_hashref { guint32 refs; } __attribute__ ((packed)); struct dbfs_raw_inode { guint64 ino; guint64 version; guint32 mode; guint32 nlink; guint32 uid; guint32 gid; guint64 rdev; guint64 size; guint64 ctime; guint64 atime; guint64 mtime; struct dbfs_extent blocks[0]; } __attribute__ ((packed)); struct dbfs_inode { enum dbfs_inode_type type; unsigned int n_extents; unsigned int raw_ino_size; struct dbfs_raw_inode *raw_inode; }; struct dbfs { const char *home; char *passwd; DB_ENV *env; DB *meta; DB *data; DB *hashref; guint64 next_inode; }; extern int debugging; typedef int (*dbfs_dir_actor_t) (struct dbfs_dirent *, void *); /* dbfs-backend.c */ extern int dbmeta_del(DB_TXN *txn, const char *key_str); extern int dbfs_inode_read(DB_TXN *txn, guint64 ino_n, struct dbfs_inode **ino_out); extern int dbfs_dir_read(DB_TXN *txn, guint64 ino, DBT *val); extern int dbfs_symlink_read(DB_TXN *txn, guint64 ino, DBT *val); extern int dbfs_dir_foreach(void *dir, dbfs_dir_actor_t func, void *userdata); extern int dbfs_dir_lookup(DB_TXN *txn, guint64 parent, const char *name, guint64 *ino); extern int dbfs_link(DB_TXN *txn, struct dbfs_inode *ino, guint64 ino_n, guint64 parent, const char *name); extern int dbfs_unlink(DB_TXN *txn, guint64 parent, const char *name, unsigned long flags); extern void dbfs_init(void *userdata); extern void dbfs_exit(void *userdata); extern int dbfs_mknod(DB_TXN *txn, guint64 parent, const char *name, guint32 mode, guint64 rdev, struct dbfs_inode **ino); extern int dbfs_symlink_write(DB_TXN *txn, guint64 ino, const char *link); extern int dbfs_inode_del(DB_TXN *txn, const struct dbfs_inode *ino); extern int dbfs_xattr_get(DB_TXN *TXN, guint64 ino_n, const char *name, void **buf_out, size_t *buflen_out); extern int dbfs_xattr_set(DB_TXN *TXN, guint64 ino_n, const char *name, const void *buf, size_t buflen, int flags); extern int dbfs_xattr_remove(DB_TXN *TXN, guint64, const char *, gboolean); extern int dbfs_xattr_list(DB_TXN *TXN, guint64 ino, void **buf_out, size_t *buflen_out); extern int dbfs_read(DB_TXN *, guint64, guint64, size_t, void **); extern int dbfs_write(DB_TXN *, guint64, guint64, const void *, size_t); extern int dbfs_inode_resize(DB_TXN *txn, struct dbfs_inode *ino, guint64 new_size); extern int dbfs_rename(DB_TXN *txn, guint64, const char *, guint64, const char *); /* libdbfs.c */ extern int dbfs_open(struct dbfs *, unsigned int, unsigned int, const char *, gboolean syslog); 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(DB_TXN *txn, struct dbfs_inode *ino); extern int dbfs_dir_new(DB_TXN *txn, guint64 parent, guint64 ino_n, const struct dbfs_inode *ino); extern int dbfs_dir_write(DB_TXN *txn, 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); } static inline size_t dbfs_xlist_next(guint16 namelen) { return ALIGN(sizeof(struct dbfs_xlist) + namelen, DBFS_XLIST_ALIGN); } #endif /* __DBFS_H__ */