diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-11-07 13:55:10 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-11-07 13:55:10 -0500 |
commit | 6919db714e750f48cbb15d4fe9053de9ff553e44 (patch) | |
tree | 62cc842bc2a071061226ab10cffbffb189017155 | |
parent | e0488a297b33e16c5557af17e4bebcad13dc6398 (diff) | |
download | dbfs-6919db714e750f48cbb15d4fe9053de9ff553e44.tar.gz |
Convert all code to use DB transaction handles.
-rw-r--r-- | dbfs-backend.c | 157 | ||||
-rw-r--r-- | dbfs.c | 492 | ||||
-rw-r--r-- | dbfs.h | 42 | ||||
-rw-r--r-- | libdbfs.c | 13 | ||||
-rw-r--r-- | mkdbfs.c | 39 | ||||
-rw-r--r-- | xattr.c | 55 |
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; @@ -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 = { @@ -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) @@ -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; } @@ -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; } @@ -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, ¤t, ¤t_len); + rc = dbfs_xattr_get(txn, ino_n, name, ¤t, ¤t_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); } |