aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-11-07 13:55:10 -0500
committerJeff Garzik <jeff@garzik.org>2006-11-07 13:55:10 -0500
commit6919db714e750f48cbb15d4fe9053de9ff553e44 (patch)
tree62cc842bc2a071061226ab10cffbffb189017155
parente0488a297b33e16c5557af17e4bebcad13dc6398 (diff)
downloaddbfs-6919db714e750f48cbb15d4fe9053de9ff553e44.tar.gz
Convert all code to use DB transaction handles.
-rw-r--r--dbfs-backend.c157
-rw-r--r--dbfs.c492
-rw-r--r--dbfs.h42
-rw-r--r--libdbfs.c13
-rw-r--r--mkdbfs.c39
-rw-r--r--xattr.c55
6 files changed, 587 insertions, 211 deletions
diff --git a/dbfs-backend.c b/dbfs-backend.c
index b794f01..fa054a9 100644
--- a/dbfs-backend.c
+++ b/dbfs-backend.c
@@ -42,7 +42,7 @@ struct dbfs_dirscan_info {
void *end_ent;
};
-int dbmeta_del(const char *key_str)
+int dbmeta_del(DB_TXN *txn, const char *key_str)
{
DBT key;
int rc;
@@ -51,7 +51,7 @@ int dbmeta_del(const char *key_str)
key.size = strlen(key_str);
/* delete key 'key_str' from metadata database */
- rc = gfs->meta->del(gfs->meta, NULL, &key, 0);
+ rc = gfs->meta->del(gfs->meta, txn, &key, 0);
if (rc == DB_NOTFOUND)
return -ENOENT;
if (rc)
@@ -79,7 +79,7 @@ static int dbfs_mode_type(guint32 mode, enum dbfs_inode_type *itype)
return 0;
}
-int dbfs_inode_del(struct dbfs_inode *ino)
+int dbfs_inode_del(DB_TXN *txn, struct dbfs_inode *ino)
{
guint64 ino_n = GUINT64_FROM_LE(ino->raw_inode->ino);
char key[32];
@@ -87,23 +87,23 @@ int dbfs_inode_del(struct dbfs_inode *ino)
sprintf(key, "/inode/%Lu", (unsigned long long) ino_n);
- rrc = dbmeta_del(key);
+ rrc = dbmeta_del(txn, key);
switch (ino->type) {
case IT_REG:
- /* FIXME */
+ /* FIXME! */
break;
case IT_DIR:
sprintf(key, "/dir/%Lu", (unsigned long long) ino_n);
- rc = dbmeta_del(key);
+ rc = dbmeta_del(txn, key);
if (rc && !rrc)
rrc = rc;
break;
case IT_SYMLINK:
sprintf(key, "/symlink/%Lu", (unsigned long long) ino_n);
- rc = dbmeta_del(key);
+ rc = dbmeta_del(txn, key);
if (rc && !rrc)
rrc = rc;
break;
@@ -118,7 +118,7 @@ int dbfs_inode_del(struct dbfs_inode *ino)
return rrc;
}
-int dbfs_inode_read(guint64 ino_n, struct dbfs_inode **ino_out)
+int dbfs_inode_read(DB_TXN *txn, guint64 ino_n, struct dbfs_inode **ino_out)
{
int rc;
DBT key, val;
@@ -136,7 +136,7 @@ int dbfs_inode_read(guint64 ino_n, struct dbfs_inode **ino_out)
memset(&val, 0, sizeof(val));
val.flags = DB_DBT_MALLOC;
- rc = gfs->meta->get(gfs->meta, NULL, &key, &val, 0);
+ rc = gfs->meta->get(gfs->meta, txn, &key, &val, 0);
if (rc == DB_NOTFOUND)
return -ENOENT;
if (rc)
@@ -161,7 +161,7 @@ int dbfs_inode_read(guint64 ino_n, struct dbfs_inode **ino_out)
return 0;
}
-static int dbfs_inode_next(struct dbfs_inode **ino_out)
+static int dbfs_inode_next(DB_TXN *txn, struct dbfs_inode **ino_out)
{
struct dbfs_inode *ino;
int rc;
@@ -175,7 +175,7 @@ static int dbfs_inode_next(struct dbfs_inode **ino_out)
* as the next free inode number.
*/
while (1) {
- rc = dbfs_inode_read(gfs->next_inode, &ino);
+ rc = dbfs_inode_read(txn, gfs->next_inode, &ino);
if (rc)
break;
@@ -209,7 +209,7 @@ static int dbfs_inode_next(struct dbfs_inode **ino_out)
return 0;
}
-int dbfs_dir_read(guint64 ino, DBT *val)
+int dbfs_dir_read(DB_TXN *txn, guint64 ino, DBT *val)
{
DBT key;
char key_str[32];
@@ -224,7 +224,7 @@ int dbfs_dir_read(guint64 ino, DBT *val)
memset(val, 0, sizeof(*val));
val->flags = DB_DBT_MALLOC;
- rc = gfs->meta->get(gfs->meta, NULL, &key, val, 0);
+ rc = gfs->meta->get(gfs->meta, txn, &key, val, 0);
if (rc == DB_NOTFOUND)
return -ENOTDIR;
return rc ? -EIO : 0;
@@ -277,7 +277,7 @@ static int dbfs_dir_scan1(struct dbfs_dirent *de, void *userdata)
return 0;
}
-int dbfs_dir_lookup(guint64 parent, const char *name, guint64 *ino)
+int dbfs_dir_lookup(DB_TXN *txn, guint64 parent, const char *name, guint64 *ino)
{
struct dbfs_dirscan_info di;
struct dbfs_dirent *de;
@@ -287,7 +287,7 @@ int dbfs_dir_lookup(guint64 parent, const char *name, guint64 *ino)
*ino = 0;
/* read directory from database */
- rc = dbfs_dir_read(parent, &val);
+ rc = dbfs_dir_read(txn, parent, &val);
if (rc)
return rc;
@@ -313,13 +313,13 @@ out:
return rc;
}
-static int dbfs_dirent_del(guint64 parent, const char *name)
+static int dbfs_dirent_del(DB_TXN *txn, guint64 parent, const char *name)
{
struct dbfs_dirscan_info ui;
DBT dir_val;
int rc, del_len, tail_len;
- rc = dbfs_dir_read(parent, &dir_val);
+ rc = dbfs_dir_read(txn, parent, &dir_val);
if (rc)
return rc;
@@ -340,7 +340,7 @@ static int dbfs_dirent_del(guint64 parent, const char *name)
memmove(ui.start_ent, ui.end_ent, tail_len);
dir_val.size -= del_len;
- rc = dbfs_dir_write(parent, &dir_val);
+ rc = dbfs_dir_write(txn, parent, &dir_val);
free(dir_val.data);
@@ -371,7 +371,7 @@ static int dbfs_name_validate(const char *name)
return 0;
}
-static int dbfs_dir_append(guint64 parent, guint64 ino_n, const char *name)
+static int dbfs_dir_append(DB_TXN *txn, guint64 parent, guint64 ino_n, const char *name)
{
struct dbfs_dirscan_info di;
struct dbfs_dirent *de;
@@ -385,7 +385,7 @@ static int dbfs_dir_append(guint64 parent, guint64 ino_n, const char *name)
return rc;
/* read parent directory from database */
- rc = dbfs_dir_read(parent, &val);
+ rc = dbfs_dir_read(txn, parent, &val);
if (rc)
return rc;
@@ -437,14 +437,14 @@ static int dbfs_dir_append(guint64 parent, guint64 ino_n, const char *name)
val.size = p - val.data;
- rc = dbfs_dir_write(parent, &val);
+ rc = dbfs_dir_write(txn, parent, &val);
out:
free(val.data);
return rc;
}
-int dbfs_symlink_read(guint64 ino, DBT *val)
+int dbfs_symlink_read(DB_TXN *txn, guint64 ino, DBT *val)
{
DBT key;
char key_str[32];
@@ -459,13 +459,13 @@ int dbfs_symlink_read(guint64 ino, DBT *val)
memset(val, 0, sizeof(*val));
val->flags = DB_DBT_MALLOC;
- rc = gfs->meta->get(gfs->meta, NULL, &key, val, 0);
+ rc = gfs->meta->get(gfs->meta, txn, &key, val, 0);
if (rc == DB_NOTFOUND)
return -EINVAL;
return rc ? -EIO : 0;
}
-int dbfs_symlink_write(guint64 ino, const char *link)
+int dbfs_symlink_write(DB_TXN *txn, guint64 ino, const char *link)
{
DBT key, val;
char key_str[32];
@@ -480,17 +480,17 @@ int dbfs_symlink_write(guint64 ino, const char *link)
val.data = (void *) link;
val.size = strlen(link);
- return gfs->meta->put(gfs->meta, NULL, &key, &val, 0) ? -EIO : 0;
+ return gfs->meta->put(gfs->meta, txn, &key, &val, 0) ? -EIO : 0;
}
-int dbfs_link(struct dbfs_inode *ino, guint64 ino_n, guint64 parent,
- const char *name)
+int dbfs_link(DB_TXN *txn, struct dbfs_inode *ino, guint64 ino_n,
+ guint64 parent, const char *name)
{
guint32 nlink;
int rc;
/* make sure it doesn't exist yet */
- rc = dbfs_dir_append(parent, ino_n, name);
+ rc = dbfs_dir_append(txn, parent, ino_n, name);
if (rc)
return rc;
@@ -499,22 +499,20 @@ int dbfs_link(struct dbfs_inode *ino, guint64 ino_n, guint64 parent,
nlink++;
ino->raw_inode->nlink = GUINT32_TO_LE(nlink);
- /* write inode; if fails, undo directory modification */
- rc = dbfs_inode_write(ino);
- if (rc)
- dbfs_dirent_del(parent, name);
+ /* write inode; if fails, DB TXN undoes directory modification */
+ rc = dbfs_inode_write(txn, ino);
return rc;
}
-int dbfs_unlink(guint64 parent, const char *name, unsigned long flags)
+int dbfs_unlink(DB_TXN *txn, guint64 parent, const char *name, unsigned long flags)
{
struct dbfs_inode *ino;
guint64 ino_n;
int rc, is_dir;
guint32 nlink;
- rc = dbfs_dir_lookup(parent, name, &ino_n);
+ rc = dbfs_dir_lookup(txn, parent, name, &ino_n);
if (rc)
goto out;
@@ -523,7 +521,7 @@ int dbfs_unlink(guint64 parent, const char *name, unsigned long flags)
goto out;
}
- rc = dbfs_inode_read(ino_n, &ino);
+ rc = dbfs_inode_read(txn, ino_n, &ino);
if (rc)
goto out;
@@ -533,7 +531,7 @@ int dbfs_unlink(guint64 parent, const char *name, unsigned long flags)
goto out_ino;
}
- rc = dbfs_dirent_del(parent, name);
+ rc = dbfs_dirent_del(txn, parent, name);
if (rc)
goto out_ino;
@@ -545,9 +543,9 @@ int dbfs_unlink(guint64 parent, const char *name, unsigned long flags)
ino->raw_inode->nlink = GUINT32_TO_LE(nlink);
if (!nlink)
- rc = dbfs_inode_del(ino);
+ rc = dbfs_inode_del(txn, ino);
else
- rc = dbfs_inode_write(ino);
+ rc = dbfs_inode_write(txn, ino);
out_ino:
dbfs_inode_free(ino);
@@ -555,8 +553,8 @@ out:
return rc;
}
-int dbfs_mknod(guint64 parent, const char *name, guint32 mode, guint64 rdev,
- struct dbfs_inode **ino_out)
+int dbfs_mknod(DB_TXN *txn, guint64 parent, const char *name, guint32 mode,
+ guint64 rdev, struct dbfs_inode **ino_out)
{
struct dbfs_inode *ino;
int rc, is_dir;
@@ -565,7 +563,7 @@ int dbfs_mknod(guint64 parent, const char *name, guint32 mode, guint64 rdev,
*ino_out = NULL;
- rc = dbfs_inode_next(&ino);
+ rc = dbfs_inode_next(txn, &ino);
if (rc)
return rc;
@@ -577,17 +575,17 @@ int dbfs_mknod(guint64 parent, const char *name, guint32 mode, guint64 rdev,
ino->raw_inode->nlink = GUINT32_TO_LE(nlink);
ino->raw_inode->rdev = GUINT64_TO_LE(rdev);
- rc = dbfs_inode_write(ino);
+ rc = dbfs_inode_write(txn, ino);
if (rc)
goto err_out;
if (is_dir) {
- rc = dbfs_dir_new(parent, ino_n, ino);
+ rc = dbfs_dir_new(txn, parent, ino_n, ino);
if (rc)
goto err_out_del;
}
- rc = dbfs_dir_append(parent, ino_n, name);
+ rc = dbfs_dir_append(txn, parent, ino_n, name);
if (rc)
goto err_out_del;
@@ -595,13 +593,13 @@ int dbfs_mknod(guint64 parent, const char *name, guint32 mode, guint64 rdev,
return 0;
err_out_del:
- dbfs_inode_del(ino);
+ /* txn abort will delete inode */
err_out:
dbfs_inode_free(ino);
return rc;
}
-int dbfs_rename(guint64 parent, const char *name,
+int dbfs_rename(DB_TXN *txn, guint64 parent, const char *name,
guint64 new_parent, const char *new_name)
{
int rc;
@@ -610,19 +608,19 @@ int dbfs_rename(guint64 parent, const char *name,
if ((parent == new_parent) && (!strcmp(name, new_name)))
return -EINVAL;
- rc = dbfs_dir_lookup(parent, name, &ino_n);
+ rc = dbfs_dir_lookup(txn, parent, name, &ino_n);
if (rc)
return rc;
- rc = dbfs_dirent_del(parent, name);
+ rc = dbfs_dirent_del(txn, parent, name);
if (rc)
return rc;
- rc = dbfs_unlink(new_parent, new_name, 0);
+ rc = dbfs_unlink(txn, new_parent, new_name, 0);
if (rc && (rc != -ENOENT))
return rc;
- return dbfs_dir_append(new_parent, ino_n, new_name);
+ return dbfs_dir_append(txn, new_parent, ino_n, new_name);
}
static void ext_list_free(GList *ext_list)
@@ -732,7 +730,7 @@ static gboolean is_null_id(dbfs_blk_id_t *id)
return is_zero_buf(id, DBFS_BLK_ID_LEN);
}
-static int dbfs_ext_read(dbfs_blk_id_t *id, void **buf, size_t *buflen)
+static int dbfs_ext_read(DB_TXN *txn, dbfs_blk_id_t *id, void **buf, size_t *buflen)
{
DBT key, val;
int rc;
@@ -744,7 +742,7 @@ static int dbfs_ext_read(dbfs_blk_id_t *id, void **buf, size_t *buflen)
memset(&val, 0, sizeof(val));
val.flags = DB_DBT_MALLOC;
- rc = gfs->data->get(gfs->data, NULL, &key, &val, 0);
+ rc = gfs->data->get(gfs->data, txn, &key, &val, 0);
if (rc == DB_NOTFOUND)
return -ENOENT;
if (rc)
@@ -755,7 +753,7 @@ static int dbfs_ext_read(dbfs_blk_id_t *id, void **buf, size_t *buflen)
return 0;
}
-int dbfs_read(guint64 ino_n, guint64 off, size_t read_req_size,
+int dbfs_read(DB_TXN *txn, guint64 ino_n, guint64 off, size_t read_req_size,
void **buf_out)
{
struct dbfs_inode *ino;
@@ -765,7 +763,7 @@ int dbfs_read(guint64 ino_n, guint64 off, size_t read_req_size,
unsigned int pos = 0;
int rc;
- rc = dbfs_inode_read(ino_n, &ino);
+ rc = dbfs_inode_read(txn, ino_n, &ino);
if (rc)
goto out;
@@ -791,7 +789,7 @@ int dbfs_read(guint64 ino_n, guint64 off, size_t read_req_size,
void *frag;
size_t fraglen;
- rc = dbfs_ext_read(&ext->id, &frag, &fraglen);
+ rc = dbfs_ext_read(txn, &ext->id, &frag, &fraglen);
if (rc) {
free(buf);
buf = NULL;
@@ -823,7 +821,8 @@ out:
return rc < 0 ? rc : buflen;
}
-static int dbfs_write_unique_buf(DBT *key, const void *buf, size_t buflen)
+static int dbfs_write_unique_buf(DB_TXN *txn, DBT *key, const void *buf,
+ size_t buflen)
{
struct dbfs_hashref ref;
DBT val;
@@ -835,7 +834,7 @@ static int dbfs_write_unique_buf(DBT *key, const void *buf, size_t buflen)
val.data = &ref;
val.size = sizeof(ref);
- rc = gfs->hashref->put(gfs->hashref, NULL, key, &val, 0);
+ rc = gfs->hashref->put(gfs->hashref, txn, key, &val, 0);
if (rc)
return -EIO;
@@ -843,20 +842,14 @@ static int dbfs_write_unique_buf(DBT *key, const void *buf, size_t buflen)
val.data = (void *) buf;
val.size = buflen;
- rc = gfs->data->put(gfs->data, NULL, key, &val, DB_NOOVERWRITE);
- if (rc) {
- memset(&val, 0, sizeof(val));
- val.data = &ref;
- val.size = sizeof(ref);
- gfs->hashref->del(gfs->hashref, NULL, key, 0);
-
+ rc = gfs->data->put(gfs->data, txn, key, &val, DB_NOOVERWRITE);
+ if (rc)
return -EIO;
- }
return 0;
}
-static int dbfs_write_buf(const void *buf, size_t buflen,
+static int dbfs_write_buf(DB_TXN *txn, const void *buf, size_t buflen,
struct dbfs_extent *ext)
{
struct dbfs_hashref *ref;
@@ -881,25 +874,25 @@ static int dbfs_write_buf(const void *buf, size_t buflen,
memset(&val, 0, sizeof(val));
val.flags = DB_DBT_MALLOC;
- rc = gfs->hashref->get(gfs->hashref, NULL, &key, &val, 0);
+ rc = gfs->hashref->get(gfs->hashref, txn, &key, &val, 0);
if (rc && (rc != DB_NOTFOUND))
return -EIO;
if (rc == DB_NOTFOUND)
- return dbfs_write_unique_buf(&key, buf, buflen);
+ return dbfs_write_unique_buf(txn, &key, buf, buflen);
ref = val.data;
g_assert(val.size == sizeof(*ref));
ref->refs = GUINT32_TO_LE(GUINT32_FROM_LE(ref->refs) + 1);
- rc = gfs->hashref->put(gfs->hashref, NULL, &key, &val, 0);
+ rc = gfs->hashref->put(gfs->hashref, txn, &key, &val, 0);
free(val.data);
return rc ? -EIO : 0;
}
-static int dbfs_data_unref(dbfs_blk_id_t *id)
+static int dbfs_data_unref(DB_TXN *txn, dbfs_blk_id_t *id)
{
struct dbfs_hashref *ref;
guint32 refs;
@@ -916,7 +909,7 @@ static int dbfs_data_unref(dbfs_blk_id_t *id)
memset(&val, 0, sizeof(val));
val.flags = DB_DBT_MALLOC;
- rc = gfs->hashref->get(gfs->hashref, NULL, &key, &val, 0);
+ rc = gfs->hashref->get(gfs->hashref, txn, &key, &val, 0);
if (rc == DB_NOTFOUND)
return -ENOENT;
if (rc)
@@ -930,7 +923,7 @@ static int dbfs_data_unref(dbfs_blk_id_t *id)
refs--;
ref->refs = GUINT32_TO_LE(refs);
- rc = gfs->hashref->put(gfs->hashref, NULL, &key, &val, 0);
+ rc = gfs->hashref->put(gfs->hashref, txn, &key, &val, 0);
free(val.data);
return rc ? -EIO : 0;
@@ -938,8 +931,8 @@ static int dbfs_data_unref(dbfs_blk_id_t *id)
free(val.data);
- rc = gfs->hashref->del(gfs->hashref, NULL, &key, 0);
- rc2 = gfs->data->del(gfs->data, NULL, &key, 0);
+ rc = gfs->hashref->del(gfs->hashref, txn, &key, 0);
+ rc2 = gfs->data->del(gfs->data, txn, &key, 0);
return (rc || rc2) ? -EIO : 0;
}
@@ -965,7 +958,7 @@ static int dbfs_inode_realloc(struct dbfs_inode *ino,
return 0;
}
-int dbfs_inode_resize(struct dbfs_inode *ino, guint64 new_size)
+int dbfs_inode_resize(DB_TXN *txn, struct dbfs_inode *ino, guint64 new_size)
{
guint64 old_size, diff, diff_ext;
unsigned int grow, i, new_n_extents, tmp;
@@ -1007,7 +1000,7 @@ int dbfs_inode_resize(struct dbfs_inode *ino, guint64 new_size)
if (ext_len > diff)
break;
- rc = dbfs_data_unref(&ext->id);
+ rc = dbfs_data_unref(txn, &ext->id);
if (rc)
return rc;
@@ -1036,25 +1029,26 @@ int dbfs_inode_resize(struct dbfs_inode *ino, guint64 new_size)
return 0;
}
-int dbfs_write(guint64 ino_n, guint64 off, const void *buf, size_t buflen)
+int dbfs_write(DB_TXN *txn, guint64 ino_n, guint64 off, const void *buf,
+ size_t buflen)
{
struct dbfs_extent ext;
struct dbfs_inode *ino;
int rc;
guint64 i_size;
- rc = dbfs_inode_read(ino_n, &ino);
+ rc = dbfs_inode_read(txn, ino_n, &ino);
if (rc)
return rc;
- rc = dbfs_write_buf(buf, buflen, &ext);
+ rc = dbfs_write_buf(txn, buf, buflen, &ext);
if (rc)
goto out;
i_size = GUINT64_FROM_LE(ino->raw_inode->size);
if ((off != i_size) && ((off + buflen) > i_size)) {
- rc = dbfs_inode_resize(ino, off + 1);
+ rc = dbfs_inode_resize(txn, ino, off + 1);
if (rc)
goto err_out;
}
@@ -1065,7 +1059,7 @@ int dbfs_write(guint64 ino_n, guint64 off, const void *buf, size_t buflen)
if (off == i_size) {
unsigned int idx;
- rc = dbfs_inode_resize(ino, i_size + buflen);
+ rc = dbfs_inode_resize(txn, ino, i_size + buflen);
if (rc)
goto err_out;
@@ -1082,7 +1076,6 @@ int dbfs_write(guint64 ino_n, guint64 off, const void *buf, size_t buflen)
goto out;
err_out:
- dbfs_data_unref(&ext.id);
out:
dbfs_inode_free(ino);
return rc;
diff --git a/dbfs.c b/dbfs.c
index ba41939..22bd5f9 100644
--- a/dbfs.c
+++ b/dbfs.c
@@ -102,22 +102,37 @@ static void dbfs_op_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
guint64 ino_n;
struct dbfs_inode *ino;
int rc;
+ DB_TXN *txn;
- /* lookup inode in parent directory */
- rc = dbfs_dir_lookup(parent, name, &ino_n);
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
if (rc) {
- fuse_reply_err(req, -rc);
+ fuse_reply_err(req, rc);
return;
}
- rc = dbfs_inode_read(ino_n, &ino);
+ /* lookup inode in parent directory */
+ rc = dbfs_dir_lookup(txn, parent, name, &ino_n);
+ if (rc)
+ goto err_out;
+
+ rc = dbfs_inode_read(txn, ino_n, &ino);
+ if (rc)
+ goto err_out;
+
+ rc = txn->commit(txn, 0);
if (rc) {
- fuse_reply_err(req, -rc);
+ dbfs_inode_free(ino);
+ fuse_reply_err(req, rc);
return;
}
/* send reply */
dbfs_reply_ino(req, ino);
+ return;
+
+err_out:
+ txn->abort(txn);
+ fuse_reply_err(req, -rc);
}
static void dbfs_op_getattr(fuse_req_t req, fuse_ino_t ino_n,
@@ -126,14 +141,27 @@ static void dbfs_op_getattr(fuse_req_t req, fuse_ino_t ino_n,
struct dbfs_inode *ino;
struct stat st;
int rc;
+ DB_TXN *txn;
- /* read inode from database */
- rc = dbfs_inode_read(ino_n, &ino);
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
if (rc) {
- fuse_reply_err(req, ENOENT);
+ fuse_reply_err(req, rc);
return;
}
+ /* read inode from database */
+ rc = dbfs_inode_read(txn, ino_n, &ino);
+ if (rc) {
+ rc = ENOENT;
+ goto err_out_txn;
+ }
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
+
/* fill in stat buf, taking care to convert from
* little endian to native endian
*/
@@ -143,6 +171,12 @@ static void dbfs_op_getattr(fuse_req_t req, fuse_ino_t ino_n,
fuse_reply_attr(req, &st, 2.0);
dbfs_inode_free(ino);
+ return;
+
+err_out_txn:
+ txn->abort(txn);
+err_out:
+ fuse_reply_err(req, rc);
}
static void dbfs_op_setattr(fuse_req_t req, fuse_ino_t ino_n,
@@ -152,11 +186,18 @@ static void dbfs_op_setattr(fuse_req_t req, fuse_ino_t ino_n,
struct dbfs_inode *ino;
struct stat st;
int rc, dirty = 0;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
/* read inode from database */
- rc = dbfs_inode_read(ino_n, &ino);
+ rc = dbfs_inode_read(txn, ino_n, &ino);
if (rc)
- goto err_out;
+ goto err_out_txn;
if (to_set & FUSE_SET_ATTR_MODE) {
ino->raw_inode->mode = GUINT32_TO_LE(attr->st_mode);
@@ -171,7 +212,7 @@ static void dbfs_op_setattr(fuse_req_t req, fuse_ino_t ino_n,
dirty = 1;
}
if (to_set & FUSE_SET_ATTR_SIZE) {
- rc = dbfs_inode_resize(ino, attr->st_size);
+ rc = dbfs_inode_resize(txn, ino, attr->st_size);
if (rc)
goto err_out_free;
ino->raw_inode->size = GUINT64_TO_LE(attr->st_size);
@@ -187,11 +228,18 @@ static void dbfs_op_setattr(fuse_req_t req, fuse_ino_t ino_n,
}
if (dirty) {
- rc = dbfs_inode_write(ino);
+ rc = dbfs_inode_write(txn, ino);
if (rc)
goto err_out_free;
}
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ rc = -rc;
+ txn = NULL;
+ goto err_out_free;
+ }
+
dbfs_fill_attr(ino, &st);
dbfs_inode_free(ino);
fuse_reply_attr(req, &st, 2.0);
@@ -199,6 +247,9 @@ static void dbfs_op_setattr(fuse_req_t req, fuse_ino_t ino_n,
err_out_free:
dbfs_inode_free(ino);
+err_out_txn:
+ if (txn)
+ txn->abort(txn);
err_out:
fuse_reply_err(req, -rc);
}
@@ -208,12 +259,24 @@ static void dbfs_op_readlink(fuse_req_t req, fuse_ino_t ino)
int rc;
DBT val;
char *s;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
/* read link from database */
- rc = dbfs_symlink_read(ino, &val);
+ rc = dbfs_symlink_read(txn, ino, &val);
+ if (rc)
+ goto err_out_txn;
+
+ rc = txn->commit(txn, 0);
if (rc) {
- fuse_reply_err(req, -rc);
- return;
+ rc = -rc;
+ free(val.data);
+ goto err_out;
}
/* send reply; use g_strndup to append a trailing null */
@@ -222,6 +285,12 @@ static void dbfs_op_readlink(fuse_req_t req, fuse_ino_t ino)
g_free(s);
free(val.data);
+ return;
+
+err_out_txn:
+ txn->abort(txn);
+err_out:
+ fuse_reply_err(req, -rc);
}
static int dbfs_mode_validate(mode_t mode)
@@ -266,26 +335,42 @@ static void dbfs_op_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
{
struct dbfs_inode *ino;
int rc;
+ DB_TXN *txn;
- rc = dbfs_mode_validate(mode);
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
if (rc) {
- fuse_reply_err(req, -rc);
- return;
+ rc = -rc;
+ goto err_out;
}
+ rc = dbfs_mode_validate(mode);
+ if (rc)
+ goto err_out_txn;
+
/* these have separate inode-creation hooks */
if (S_ISDIR(mode) || S_ISLNK(mode)) {
- fuse_reply_err(req, EINVAL);
- return;
+ rc = -EINVAL;
+ goto err_out_txn;
}
- rc = dbfs_mknod(parent, name, mode, rdev, &ino);
+ rc = dbfs_mknod(txn, parent, name, mode, rdev, &ino);
+ if (rc)
+ goto err_out_txn;
+
+ rc = txn->commit(txn, 0);
if (rc) {
- fuse_reply_err(req, -rc);
- return;
+ dbfs_inode_free(ino);
+ rc = -rc;
+ goto err_out;
}
dbfs_reply_ino(req, ino);
+ return;
+
+err_out_txn:
+ txn->abort(txn);
+err_out:
+ fuse_reply_err(req, -rc);
}
static void dbfs_op_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
@@ -293,21 +378,66 @@ static void dbfs_op_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
{
struct dbfs_inode *ino;
int rc;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
mode &= ALLPERMS;
mode |= S_IFDIR;
- rc = dbfs_mknod(parent, name, mode, 0, &ino);
+ rc = dbfs_mknod(txn, parent, name, mode, 0, &ino);
if (rc)
- fuse_reply_err(req, -rc);
- else
- dbfs_reply_ino(req, ino);
+ goto err_out_txn;
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ dbfs_inode_free(ino);
+ rc = -rc;
+ goto err_out;
+ }
+
+ dbfs_reply_ino(req, ino);
+
+ return;
+
+err_out_txn:
+ txn->abort(txn);
+err_out:
+ fuse_reply_err(req, -rc);
}
static void dbfs_op_unlink(fuse_req_t req, fuse_ino_t parent, const char *name)
{
- int rc = dbfs_unlink(parent, name, 0);
+ int rc;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto out;
+ }
+
+ rc = dbfs_unlink(txn, parent, name, 0);
+ if (rc)
+ goto err_out;
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto out;
+ }
+
+out:
fuse_reply_err(req, -rc);
+ return;
+
+err_out:
+ txn->abort(txn);
+ goto out;
}
static void dbfs_op_link(fuse_req_t req, fuse_ino_t ino_n, fuse_ino_t parent,
@@ -315,24 +445,41 @@ static void dbfs_op_link(fuse_req_t req, fuse_ino_t ino_n, fuse_ino_t parent,
{
struct dbfs_inode *ino;
int rc;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
/* read inode from database */
- rc = dbfs_inode_read(ino_n, &ino);
+ rc = dbfs_inode_read(txn, ino_n, &ino);
if (rc) {
- fuse_reply_err(req, ENOENT);
- return;
+ rc = -ENOENT;
+ goto err_out_txn;
}
/* attempt to create hard link */
- rc = dbfs_link(ino, ino_n, parent, newname);
+ rc = dbfs_link(txn, ino, ino_n, parent, newname);
if (rc)
+ goto err_out_ino;
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ dbfs_inode_free(ino);
+ rc = -rc;
goto err_out;
+ }
dbfs_reply_ino(req, ino);
return;
-err_out:
+err_out_ino:
dbfs_inode_free(ino);
+err_out_txn:
+ txn->abort(txn);
+err_out:
fuse_reply_err(req, -rc);
}
@@ -348,26 +495,64 @@ static void dbfs_op_read(fuse_req_t req, fuse_ino_t ino, size_t size,
off_t off, struct fuse_file_info *fi)
{
void *buf = NULL;
- int rc;
+ int rc, rc2;
+ DB_TXN *txn;
- rc = dbfs_read(ino, off, size, &buf);
- if (rc < 0) {
- fuse_reply_err(req, -rc);
- return;
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
+
+ rc = dbfs_read(txn, ino, off, size, &buf);
+ if (rc < 0)
+ goto err_out_txn;
+
+ rc2 = txn->commit(txn, 0);
+ if (rc2) {
+ rc = -rc2;
+ goto err_out;
}
fuse_reply_buf(req, buf, rc);
free(buf);
+ return;
+
+err_out_txn:
+ txn->abort(txn);
+err_out:
+ fuse_reply_err(req, -rc);
}
static void dbfs_op_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
size_t size, off_t off, struct fuse_file_info *fi)
{
- int rc = dbfs_write(ino, off, buf, size);
+ int rc, rc2;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
+
+ rc = dbfs_write(txn, ino, off, buf, size);
if (rc < 0)
- fuse_reply_err(req, -rc);
- else
- fuse_reply_write(req, rc);
+ goto err_out_txn;
+
+ rc2 = txn->commit(txn, 0);
+ if (rc2) {
+ rc = -rc2;
+ goto err_out;
+ }
+
+ fuse_reply_write(req, rc);
+ return;
+
+err_out_txn:
+ txn->abort(txn);
+err_out:
+ fuse_reply_err(req, -rc);
}
static int dbfs_chk_empty(struct dbfs_dirent *de, void *userdata)
@@ -384,16 +569,23 @@ static void dbfs_op_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
guint64 ino_n;
int rc;
DBT val;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto out;
+ }
/* get inode number associated with name */
- rc = dbfs_dir_lookup(parent, name, &ino_n);
+ rc = dbfs_dir_lookup(txn, parent, name, &ino_n);
if (rc)
- goto out;
+ goto out_txn;
/* read dir associated with name */
- rc = dbfs_dir_read(ino_n, &val);
+ rc = dbfs_dir_read(txn, ino_n, &val);
if (rc)
- goto out;
+ goto out_txn;
/* make sure dir only contains "." and ".." */
rc = dbfs_dir_foreach(val.data, dbfs_chk_empty, NULL);
@@ -401,11 +593,24 @@ static void dbfs_op_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
/* if dbfs_chk_empty() returns non-zero, dir is not empty */
if (rc)
- goto out;
+ goto out_txn;
/* dir is empty, go ahead and unlink */
- rc = dbfs_unlink(parent, name, DBFS_UNLINK_DIR);
+ rc = dbfs_unlink(txn, parent, name, DBFS_UNLINK_DIR);
+ if (rc)
+ goto out_txn;
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto out;
+ }
+
+ fuse_reply_err(req, 0);
+ return;
+
+out_txn:
+ txn->abort(txn);
out:
fuse_reply_err(req, -rc);
}
@@ -415,27 +620,42 @@ static void dbfs_op_symlink(fuse_req_t req, const char *link,
{
struct dbfs_inode *ino;
int rc;
+ DB_TXN *txn;
if (!g_utf8_validate(link, -1, NULL)) {
rc = -EINVAL;
goto err_out;
}
- rc = dbfs_mknod(parent, name,
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
+
+ rc = dbfs_mknod(txn, parent, name,
S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO, 0, &ino);
if (rc)
- goto err_out;
+ goto err_out_txn;
- rc = dbfs_symlink_write(GUINT64_FROM_LE(ino->raw_inode->ino), link);
+ rc = dbfs_symlink_write(txn, GUINT64_FROM_LE(ino->raw_inode->ino), link);
if (rc)
- goto err_out_mknod;
+ goto err_out_ino;
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ dbfs_inode_free(ino);
+ rc = -rc;
+ goto err_out;
+ }
dbfs_reply_ino(req, ino);
return;
-err_out_mknod:
- dbfs_inode_del(ino);
+err_out_ino:
dbfs_inode_free(ino);
+err_out_txn:
+ txn->abort(txn);
err_out:
fuse_reply_err(req, -rc);
}
@@ -444,7 +664,31 @@ static void dbfs_op_rename(fuse_req_t req, fuse_ino_t parent,
const char *name, fuse_ino_t newparent,
const char *newname)
{
- int rc = dbfs_rename(parent, name, newparent, newname);
+ int rc;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto out;
+ }
+
+ rc = dbfs_rename(txn, parent, name, newparent, newname);
+ if (rc)
+ goto out_txn;
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto out;
+ }
+
+ fuse_reply_err(req, 0);
+ return;
+
+out_txn:
+ txn->abort(txn);
+out:
fuse_reply_err(req, -rc);
}
@@ -460,12 +704,23 @@ static void dbfs_op_opendir(fuse_req_t req, fuse_ino_t ino,
{
DBT val;
int rc;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
/* read directory from database */
- rc = dbfs_dir_read(ino, &val);
+ rc = dbfs_dir_read(txn, ino, &val);
+ if (rc)
+ goto err_out_txn;
+
+ rc = txn->commit(txn, 0);
if (rc) {
- fuse_reply_err(req, -rc);
- return;
+ rc = -rc;
+ goto err_out;
}
/* save for later use */
@@ -473,6 +728,12 @@ static void dbfs_op_opendir(fuse_req_t req, fuse_ino_t ino,
/* send reply */
fuse_reply_open(req, fi);
+ return;
+
+err_out_txn:
+ txn->abort(txn);
+err_out:
+ fuse_reply_err(req, -rc);
}
struct dirbuf {
@@ -585,7 +846,31 @@ static void dbfs_op_setxattr(fuse_req_t req, fuse_ino_t ino,
const char *name, const char *value,
size_t size, int flags)
{
- int rc = dbfs_xattr_set(ino, name, value, size, flags);
+ int rc;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
+
+ rc = dbfs_xattr_set(txn, ino, name, value, size, flags);
+ if (rc)
+ goto err_out_txn;
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
+
+ fuse_reply_err(req, 0);
+ return;
+
+err_out_txn:
+ txn->abort(txn);
+err_out:
fuse_reply_err(req, -rc);
}
@@ -595,10 +880,23 @@ static void dbfs_op_getxattr(fuse_req_t req, fuse_ino_t ino,
void *buf = NULL;
size_t buflen = 0;
int rc;
+ DB_TXN *txn;
- rc = dbfs_xattr_get(ino, name, &buf, &buflen);
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
+
+ rc = dbfs_xattr_get(txn, ino, name, &buf, &buflen);
if (rc)
+ goto err_out_txn;
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ rc = -rc;
goto err_out;
+ }
if (size == 0)
fuse_reply_xattr(req, buflen);
@@ -612,6 +910,8 @@ static void dbfs_op_getxattr(fuse_req_t req, fuse_ino_t ino,
free(buf);
return;
+err_out_txn:
+ txn->abort(txn);
err_out:
fuse_reply_err(req, -rc);
}
@@ -621,11 +921,22 @@ static void dbfs_op_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
int rc;
void *buf;
size_t buflen;
+ DB_TXN *txn;
- rc = dbfs_xattr_list(ino, &buf, &buflen);
- if (rc < 0) {
- fuse_reply_err(req, -rc);
- return;
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
+
+ rc = dbfs_xattr_list(txn, ino, &buf, &buflen);
+ if (rc < 0)
+ goto err_out_txn;
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
}
if (size == 0)
@@ -636,12 +947,42 @@ static void dbfs_op_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
fuse_reply_buf(req, buf, buflen);
free(buf);
+ return;
+
+err_out_txn:
+ txn->abort(txn);
+err_out:
+ fuse_reply_err(req, -rc);
}
static void dbfs_op_removexattr(fuse_req_t req, fuse_ino_t ino,
const char *name)
{
- int rc = dbfs_xattr_remove(ino, name, TRUE);
+ int rc;
+ DB_TXN *txn;
+
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
+
+ rc = dbfs_xattr_remove(txn, ino, name, TRUE);
+ if (rc)
+ goto err_out_txn;
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto err_out;
+ }
+
+ fuse_reply_err(req, 0);
+ return;
+
+err_out_txn:
+ txn->abort(txn);
+err_out:
fuse_reply_err(req, -rc);
}
@@ -651,13 +992,27 @@ static void dbfs_op_access(fuse_req_t req, fuse_ino_t ino_n, int mask)
const struct fuse_ctx *ctx;
int rc;
guint32 mode, uid, gid;
+ DB_TXN *txn;
ctx = fuse_req_ctx(req);
g_assert(ctx != NULL);
- rc = dbfs_inode_read(ino_n, &ino);
+ rc = gfs->env->txn_begin(gfs->env, NULL, &txn, 0);
+ if (rc) {
+ rc = -rc;
+ goto out;
+ }
+
+ rc = dbfs_inode_read(txn, ino_n, &ino);
if (rc)
+ goto out_txn;
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ dbfs_inode_free(ino);
+ rc = -rc;
goto out;
+ }
mode = GUINT32_FROM_LE(ino->raw_inode->mode);
uid = GUINT32_FROM_LE(ino->raw_inode->uid);
@@ -680,6 +1035,11 @@ static void dbfs_op_access(fuse_req_t req, fuse_ino_t ino_n, int mask)
out:
fuse_reply_err(req, -rc);
+ return;
+
+out_txn:
+ txn->abort(txn);
+ goto out;
}
static struct fuse_lowlevel_ops dbfs_ops = {
diff --git a/dbfs.h b/dbfs.h
index 1cb8179..3db430e 100644
--- a/dbfs.h
+++ b/dbfs.h
@@ -134,32 +134,32 @@ struct dbfs {
typedef int (*dbfs_dir_actor_t) (struct dbfs_dirent *, void *);
/* dbfs-backend.c */
-extern int dbmeta_del(const char *key_str);
-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 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(guint64 parent, const char *name, guint64 *ino);
-extern int dbfs_link(struct dbfs_inode *ino, guint64 ino_n, guint64 parent, const char *name);
-extern int dbfs_unlink(guint64 parent, const char *name, unsigned long flags);
+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(guint64 parent, const char *name,
+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(guint64 ino, const char *link);
-extern int dbfs_inode_del(struct dbfs_inode *ino);
-extern int dbfs_xattr_get(guint64 ino_n, const char *name,
+extern int dbfs_symlink_write(DB_TXN *txn, guint64 ino, const char *link);
+extern int dbfs_inode_del(DB_TXN *txn, 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(guint64 ino_n, const char *name,
+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(guint64, const char *, gboolean);
-extern int dbfs_xattr_list(guint64 ino, void **buf_out, size_t *buflen_out);
-extern int dbfs_read(guint64, guint64, size_t, void **);
-extern int dbfs_write(guint64, guint64, const void *, size_t);
-extern int dbfs_inode_resize(struct dbfs_inode *ino, guint64 new_size);
-extern int dbfs_rename(guint64, const char *, guint64, const char *);
+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 *);
@@ -167,9 +167,9 @@ 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 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)
diff --git a/libdbfs.c b/libdbfs.c
index 234ed8e..59e5129 100644
--- a/libdbfs.c
+++ b/libdbfs.c
@@ -195,7 +195,7 @@ void dbfs_inode_free(struct dbfs_inode *ino)
g_free(ino);
}
-int dbfs_inode_write(struct dbfs_inode *ino)
+int dbfs_inode_write(DB_TXN *txn, struct dbfs_inode *ino)
{
struct dbfs_raw_inode *raw_ino = ino->raw_inode;
guint64 ino_n = GUINT64_FROM_LE(ino->raw_inode->ino);
@@ -216,10 +216,11 @@ int dbfs_inode_write(struct dbfs_inode *ino)
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;
+ return gfs->meta->put(gfs->meta, txn, &key, &val, 0) ? -EIO : 0;
}
-int dbfs_dir_new(guint64 parent, guint64 ino_n, const struct dbfs_inode *ino)
+int dbfs_dir_new(DB_TXN *txn, guint64 parent, guint64 ino_n,
+ const struct dbfs_inode *ino)
{
void *mem, *p, *q;
struct dbfs_dirent *de;
@@ -274,14 +275,14 @@ int dbfs_dir_new(guint64 parent, guint64 ino_n, const struct dbfs_inode *ino)
val.data = mem;
val.size = p - mem;
- rc = dbfs_dir_write(ino_n, &val);
+ rc = dbfs_dir_write(txn, ino_n, &val);
free(mem);
return rc;
}
-int dbfs_dir_write(guint64 ino, DBT *val)
+int dbfs_dir_write(DB_TXN *txn, guint64 ino, DBT *val)
{
DBT key;
char key_str[32];
@@ -293,6 +294,6 @@ int dbfs_dir_write(guint64 ino, DBT *val)
key.data = key_str;
key.size = strlen(key_str);
- return gfs->meta->put(gfs->meta, NULL, &key, val, 0) ? -EIO : 0;
+ return gfs->meta->put(gfs->meta, txn, &key, val, 0) ? -EIO : 0;
}
diff --git a/mkdbfs.c b/mkdbfs.c
index 01ea171..051c783 100644
--- a/mkdbfs.c
+++ b/mkdbfs.c
@@ -28,7 +28,7 @@
#include <db.h>
#include "dbfs.h"
-static void make_root_dir(void)
+static int make_root_dir(DB_TXN *txn)
{
struct dbfs_inode *ino;
guint64 curtime;
@@ -48,26 +48,28 @@ static void make_root_dir(void)
ino->raw_inode->atime = curtime;
ino->raw_inode->mtime = curtime;
- rc = dbfs_inode_write(ino);
+ rc = dbfs_inode_write(txn, ino);
if (rc)
goto err_die;
- rc = dbfs_dir_new(1, 1, ino);
+ rc = dbfs_dir_new(txn, 1, 1, ino);
if (rc)
goto err_die;
dbfs_inode_free(ino);
- return;
+ return 0;
err_die:
errno = -rc;
perror("dbfs_inode_write");
- exit(1);
+ return 1;
}
int main (int argc, char *argv[])
{
struct dbfs *fs = dbfs_new();
+ DB_TXN *txn;
+ int pgm_rc = 0;
gfs = fs;
@@ -76,12 +78,33 @@ int main (int argc, char *argv[])
int rc = dbfs_open(fs, DB_CREATE, DB_CREATE, "mkdbfs");
if (rc) {
- perror("mkdbfs");
+ perror("mkdbfs open");
return 1;
}
- make_root_dir();
+ rc = fs->env->txn_begin(fs->env, NULL, &txn, 0);
+ if (rc) {
+ perror("mkdbfs txn_begin");
+ pgm_rc = 1;
+ goto out;
+ }
+
+ rc = make_root_dir(txn);
+ if (rc) {
+ txn->abort(txn);
+ pgm_rc = 1;
+ goto out;
+ }
+
+ rc = txn->commit(txn, 0);
+ if (rc) {
+ perror("mkdbfs txn_commit");
+ pgm_rc = 1;
+ goto out;
+ }
+
+out:
dbfs_close(fs);
- return 0;
+ return pgm_rc;
}
diff --git a/xattr.c b/xattr.c
index bc7401e..ef9823b 100644
--- a/xattr.c
+++ b/xattr.c
@@ -24,7 +24,7 @@
#include <db.h>
#include "dbfs.h"
-static int dbfs_xattr_list_read(DBT *key, DBT *val, char *keystr, guint64 ino)
+static int dbfs_xattr_list_read(DB_TXN *txn, DBT *key, DBT *val, char *keystr, guint64 ino)
{
snprintf(keystr, 32, "/xattr/%Lu", (unsigned long long) ino);
@@ -35,10 +35,10 @@ static int dbfs_xattr_list_read(DBT *key, DBT *val, char *keystr, guint64 ino)
memset(val, 0, sizeof(*val));
val->flags = DB_DBT_MALLOC;
- return gfs->meta->get(gfs->meta, NULL, key, val, 0);
+ return gfs->meta->get(gfs->meta, txn, key, val, 0);
}
-static int dbfs_xattr_list_add(guint64 ino, const char *name)
+static int dbfs_xattr_list_add(DB_TXN *txn, guint64 ino, const char *name)
{
struct dbfs_xlist *ent;
char keystr[32];
@@ -48,7 +48,7 @@ static int dbfs_xattr_list_add(guint64 ino, const char *name)
int rc;
/* get list from db */
- rc = dbfs_xattr_list_read(&key, &val, keystr, ino);
+ rc = dbfs_xattr_list_read(txn, &key, &val, keystr, ino);
if (rc && (rc != DB_NOTFOUND))
return -EIO;
@@ -89,14 +89,14 @@ static int dbfs_xattr_list_add(guint64 ino, const char *name)
memcpy(ent->name, name, name_len);
/* store new list in db */
- rc = gfs->meta->put(gfs->meta, NULL, &key, &val, 0) ? -EIO : 0;
+ rc = gfs->meta->put(gfs->meta, txn, &key, &val, 0) ? -EIO : 0;
out:
free(val.data);
return rc;
}
-static int dbfs_xattr_list_del(guint64 ino, const char *name)
+static int dbfs_xattr_list_del(DB_TXN *txn, guint64 ino, const char *name)
{
size_t name_len = strlen(name);
struct dbfs_xlist *ent;
@@ -109,7 +109,7 @@ static int dbfs_xattr_list_del(guint64 ino, const char *name)
unsigned int entries = 0;
/* get list from db */
- rc = dbfs_xattr_list_read(&key, &val, keystr, ino);
+ rc = dbfs_xattr_list_read(txn, &key, &val, keystr, ino);
if (rc == DB_NOTFOUND)
return -ENOENT;
if (rc)
@@ -146,19 +146,19 @@ static int dbfs_xattr_list_del(guint64 ino, const char *name)
val.size -= ssize;
/* store new list in db */
- rc = gfs->meta->put(gfs->meta, NULL, &key, &val, 0) ? -EIO : 0;
+ rc = gfs->meta->put(gfs->meta, txn, &key, &val, 0) ? -EIO : 0;
}
/* otherwise, delete db entry */
else
- rc = dbmeta_del(keystr);
+ rc = dbmeta_del(txn, keystr);
out:
free(val.data);
return rc;
}
-int dbfs_xattr_list(guint64 ino, void **buf_out, size_t *buflen_out)
+int dbfs_xattr_list(DB_TXN *txn, guint64 ino, void **buf_out, size_t *buflen_out)
{
struct dbfs_xlist *ent;
char keystr[32];
@@ -173,7 +173,7 @@ int dbfs_xattr_list(guint64 ino, void **buf_out, size_t *buflen_out)
*buflen_out = 0;
/* get list from db */
- rc = dbfs_xattr_list_read(&key, &val, keystr, ino);
+ rc = dbfs_xattr_list_read(txn, &key, &val, keystr, ino);
if (rc == DB_NOTFOUND)
return 0;
if (rc)
@@ -219,7 +219,7 @@ out:
return rc;
}
-static int dbfs_xattr_read(guint64 ino, const char *name, DBT *val)
+static int dbfs_xattr_read(DB_TXN *txn, guint64 ino, const char *name, DBT *val)
{
char key_str[DBFS_XATTR_NAME_LEN + 32];
DBT key;
@@ -235,13 +235,13 @@ static int dbfs_xattr_read(guint64 ino, const char *name, DBT *val)
memset(val, 0, sizeof(*val));
val->flags = DB_DBT_MALLOC;
- rc = gfs->meta->get(gfs->meta, NULL, &key, val, 0);
+ rc = gfs->meta->get(gfs->meta, txn, &key, val, 0);
if (rc == DB_NOTFOUND)
return -EINVAL;
return rc ? -EIO : 0;
}
-static int dbfs_xattr_write(guint64 ino, const char *name,
+static int dbfs_xattr_write(DB_TXN *txn, guint64 ino, const char *name,
const void *buf, size_t buflen)
{
char key_str[DBFS_XATTR_NAME_LEN + 32];
@@ -258,16 +258,16 @@ static int dbfs_xattr_write(guint64 ino, const char *name,
val.data = (void *) buf;
val.size = buflen;
- return gfs->meta->put(gfs->meta, NULL, &key, &val, 0) ? -EIO : 0;
+ return gfs->meta->put(gfs->meta, txn, &key, &val, 0) ? -EIO : 0;
}
-int dbfs_xattr_get(guint64 ino_n, const char *name,
+int dbfs_xattr_get(DB_TXN *txn, guint64 ino_n, const char *name,
void **buf_out, size_t *buflen_out)
{
int rc;
DBT val;
- rc = dbfs_xattr_read(ino_n, name, &val);
+ rc = dbfs_xattr_read(txn, ino_n, name, &val);
if (rc)
return rc;
@@ -277,8 +277,8 @@ int dbfs_xattr_get(guint64 ino_n, const char *name,
return 0;
}
-int dbfs_xattr_set(guint64 ino_n, const char *name, const void *buf,
- size_t buflen, int flags)
+int dbfs_xattr_set(DB_TXN *txn, guint64 ino_n, const char *name,
+ const void *buf, size_t buflen, int flags)
{
void *current = NULL;
size_t current_len = 0;
@@ -290,7 +290,7 @@ int dbfs_xattr_set(guint64 ino_n, const char *name, const void *buf,
(buflen > DBFS_XATTR_MAX_LEN))
return -EINVAL;
- rc = dbfs_xattr_get(ino_n, name, &current, &current_len);
+ rc = dbfs_xattr_get(txn, ino_n, name, &current, &current_len);
if (rc && (rc != -EINVAL))
return rc;
@@ -302,20 +302,19 @@ int dbfs_xattr_set(guint64 ino_n, const char *name, const void *buf,
if (!exists && (flags & XATTR_REPLACE))
return -ENOATTR;
- rc = dbfs_xattr_write(ino_n, name, buf, buflen);
+ rc = dbfs_xattr_write(txn, ino_n, name, buf, buflen);
if (rc)
return rc;
- rc = dbfs_xattr_list_add(ino_n, name);
- if (rc) {
- dbfs_xattr_remove(ino_n, name, FALSE);
+ rc = dbfs_xattr_list_add(txn, ino_n, name);
+ if (rc)
return rc;
- }
return 0;
}
-int dbfs_xattr_remove(guint64 ino_n, const char *name, gboolean update_list)
+int dbfs_xattr_remove(DB_TXN *txn, guint64 ino_n, const char *name,
+ gboolean update_list)
{
char key_str[DBFS_XATTR_NAME_LEN + 32];
@@ -323,11 +322,11 @@ int dbfs_xattr_remove(guint64 ino_n, const char *name, gboolean update_list)
"/xattr/%Lu/%s", (unsigned long long) ino_n, name);
if (update_list) {
- int rc = dbfs_xattr_list_del(ino_n, name);
+ int rc = dbfs_xattr_list_del(txn, ino_n, name);
if (rc)
return rc;
}
- return dbmeta_del(key_str);
+ return dbmeta_del(txn, key_str);
}