summaryrefslogtreecommitdiffstats
path: root/xlators/storage
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage')
-rw-r--r--xlators/storage/bdb/src/bctx.c531
-rw-r--r--xlators/storage/bdb/src/bdb-ll.c2239
-rw-r--r--xlators/storage/bdb/src/bdb.c5722
-rw-r--r--xlators/storage/bdb/src/bdb.h483
4 files changed, 4566 insertions, 4409 deletions
diff --git a/xlators/storage/bdb/src/bctx.c b/xlators/storage/bdb/src/bctx.c
index ce7e49f2c28..7fc47cd7b72 100644
--- a/xlators/storage/bdb/src/bctx.c
+++ b/xlators/storage/bdb/src/bctx.c
@@ -24,75 +24,74 @@
static void
__destroy_bctx (bctx_t *bctx)
{
- if (bctx->directory)
- FREE (bctx->directory);
-
- if (bctx->db_path)
- FREE (bctx->db_path);
-
- FREE (bctx);
+ if (bctx->directory)
+ FREE (bctx->directory);
+
+ if (bctx->db_path)
+ FREE (bctx->db_path);
+
+ FREE (bctx);
}
static void
__unhash_bctx (bctx_t *bctx)
{
- list_del_init (&bctx->b_hash);
+ list_del_init (&bctx->b_hash);
}
static int32_t
bctx_table_prune (bctx_table_t *table)
{
- int32_t ret = 0;
- struct list_head purge = {0,};
- struct list_head *next = NULL;
- bctx_t *entry = NULL;
- bctx_t *del = NULL, *tmp = NULL;
-
- if (!table)
- return 0;
-
- INIT_LIST_HEAD (&purge);
-
- LOCK (&table->lock);
- {
- if ((table->lru_limit) &&
- (table->lru_size > table->lru_limit)) {
- while (table->lru_size > table->lru_limit) {
- next = table->b_lru.next;
- entry = list_entry (next, bctx_t, list);
-
- list_move_tail (next, &table->purge);
- __unhash_bctx (entry);
-
- table->lru_size--;
- ret++;
- }
- }
- list_move_tail (&purge, &table->purge);
- list_del_init (&table->purge);
- }
- UNLOCK (&table->lock);
-
- {
- list_for_each_entry_safe (del, tmp, &purge, list) {
- list_del_init (&del->list);
- if (del->dbp) {
- ret = del->dbp->close (del->dbp, 0);
- if (ret != 0) {
- gf_log (table->this->name, GF_LOG_ERROR,
- "failed to close db on path (%s): %s",
- del->directory, db_strerror (ret));
- } else {
- gf_log (table->this->name, GF_LOG_WARNING,
- "close db for path %s; table->lru_count = %d",
- del->directory, table->lru_size);
- }
- }
- __destroy_bctx (del);
- }
- }
-
- return ret;
+ int32_t ret = 0;
+ struct list_head purge = {0,};
+ struct list_head *next = NULL;
+ bctx_t *entry = NULL;
+ bctx_t *del = NULL, *tmp = NULL;
+
+ if (!table)
+ return 0;
+
+ INIT_LIST_HEAD (&purge);
+
+ LOCK (&table->lock);
+ {
+ if ((table->lru_limit) &&
+ (table->lru_size > table->lru_limit)) {
+ while (table->lru_size > table->lru_limit) {
+ next = table->b_lru.next;
+ entry = list_entry (next, bctx_t, list);
+
+ list_move_tail (next, &table->purge);
+ __unhash_bctx (entry);
+
+ table->lru_size--;
+ ret++;
+ }
+ }
+ list_move_tail (&purge, &table->purge);
+ list_del_init (&table->purge);
+ }
+ UNLOCK (&table->lock);
+
+ list_for_each_entry_safe (del, tmp, &purge, list) {
+ list_del_init (&del->list);
+ if (del->dbp) {
+ ret = del->dbp->close (del->dbp, 0);
+ if (ret != 0) {
+ gf_log (table->this->name, GF_LOG_ERROR,
+ "failed to close db on path (%s): %s",
+ del->directory, db_strerror (ret));
+ } else {
+ gf_log (table->this->name, GF_LOG_WARNING,
+ "close db for path %s; "
+ "table->lru_count = %d",
+ del->directory, table->lru_size);
+ }
+ }
+ __destroy_bctx (del);
+ }
+
+ return ret;
}
@@ -100,115 +99,116 @@ bctx_table_prune (bctx_table_t *table)
static inline uint32_t
bdb_key_hash (char *key, uint32_t hash_size)
{
- uint32_t hash = 0;
-
- hash = *key;
-
- if (hash) {
- for (key += 1; *key != '\0'; key++) {
- hash = (hash << 5) - hash + *key;
- }
- }
-
- return (hash + *key) % hash_size;
+ uint32_t hash = 0;
+
+ hash = *key;
+
+ if (hash) {
+ for (key += 1; *key != '\0'; key++) {
+ hash = (hash << 5) - hash + *key;
+ }
+ }
+
+ return (hash + *key) % hash_size;
}
static void
__hash_bctx (bctx_t *bctx)
{
- bctx_table_t *table = NULL;
- char *key = NULL;
+ bctx_table_t *table = NULL;
+ char *key = NULL;
- table = bctx->table;
+ table = bctx->table;
- MAKE_KEY_FROM_PATH (key, bctx->directory);
- bctx->key_hash = bdb_key_hash (key, table->hash_size);
+ MAKE_KEY_FROM_PATH (key, bctx->directory);
+ bctx->key_hash = bdb_key_hash (key, table->hash_size);
- list_del_init (&bctx->b_hash);
- list_add (&bctx->b_hash, &table->b_hash[bctx->key_hash]);
+ list_del_init (&bctx->b_hash);
+ list_add (&bctx->b_hash, &table->b_hash[bctx->key_hash]);
}
static inline bctx_t *
__bctx_passivate (bctx_t *bctx)
{
- if (bctx->dbp) {
- list_move_tail (&bctx->list, &(bctx->table->b_lru));
- bctx->table->lru_size++;
- } else {
- list_move_tail (&bctx->list, &bctx->table->purge);
- __unhash_bctx (bctx);
- }
- return bctx;
+ if (bctx->dbp) {
+ list_move_tail (&bctx->list, &(bctx->table->b_lru));
+ bctx->table->lru_size++;
+ } else {
+ list_move_tail (&bctx->list, &bctx->table->purge);
+ __unhash_bctx (bctx);
+ }
+ return bctx;
}
static inline bctx_t *
__bctx_activate (bctx_t *bctx)
{
- list_move (&bctx->list, &bctx->table->active);
- bctx->table->lru_size--;
-
- return bctx;
+ list_move (&bctx->list, &bctx->table->active);
+ bctx->table->lru_size--;
+
+ return bctx;
}
static bctx_t *
__bdb_ctx_unref (bctx_t *bctx)
{
- assert (bctx->ref);
-
- --bctx->ref;
-
- if (!bctx->ref)
- bctx = __bctx_passivate (bctx);
-
- return bctx;
+ assert (bctx->ref);
+
+ --bctx->ref;
+
+ if (!bctx->ref)
+ bctx = __bctx_passivate (bctx);
+
+ return bctx;
}
bctx_t *
bctx_unref (bctx_t *bctx)
{
- bctx_table_t *table = NULL;
-
- if (!bctx && !bctx->table)
- return NULL;
-
- table = bctx->table;
-
- LOCK (&table->lock);
- {
- bctx = __bdb_ctx_unref (bctx);
- }
- UNLOCK (&table->lock);
-
- bctx_table_prune (table);
-
- return bctx;
+ bctx_table_t *table = NULL;
+
+ if (!bctx && !bctx->table)
+ return NULL;
+
+ table = bctx->table;
+
+ LOCK (&table->lock);
+ {
+ bctx = __bdb_ctx_unref (bctx);
+ }
+ UNLOCK (&table->lock);
+
+ bctx_table_prune (table);
+
+ return bctx;
}
/*
- * NOTE: __bdb_ctx_ref() is called only after holding table->lock and bctx->lock, in that order
+ * NOTE: __bdb_ctx_ref() is called only after holding table->lock and
+ * bctx->lock, in that order
*/
static inline bctx_t *
__bctx_ref (bctx_t *bctx)
{
- if (!bctx->ref)
- __bctx_activate (bctx);
+ if (!bctx->ref)
+ __bctx_activate (bctx);
- bctx->ref++;
+ bctx->ref++;
- return bctx;
+ return bctx;
}
bctx_t *
bctx_ref (bctx_t *bctx)
{
- LOCK (&(bctx->table->lock));
- {
- __bctx_ref (bctx);
- }
- UNLOCK (&(bctx->table->lock));
+ LOCK (&(bctx->table->lock));
+ {
+ __bctx_ref (bctx);
+ }
+ UNLOCK (&(bctx->table->lock));
- return bctx;
+ return bctx;
}
@@ -216,179 +216,184 @@ bctx_ref (bctx_t *bctx)
static inline bctx_t *
__create_bctx (bctx_table_t *table,
- const char *path)
+ const char *path)
{
- bctx_t *bctx = NULL;
- char *db_path = NULL;
+ bctx_t *bctx = NULL;
+ char *db_path = NULL;
- bctx = CALLOC (1, sizeof (*bctx));
- GF_VALIDATE_OR_GOTO ("bctx", bctx, out);
+ bctx = CALLOC (1, sizeof (*bctx));
+ GF_VALIDATE_OR_GOTO ("bctx", bctx, out);
- bctx->table = table;
- bctx->directory = strdup (path);
- GF_VALIDATE_OR_GOTO ("bctx", bctx->directory, out);
+ bctx->table = table;
+ bctx->directory = strdup (path);
+ GF_VALIDATE_OR_GOTO ("bctx", bctx->directory, out);
- MAKE_REAL_PATH_TO_STORAGE_DB (db_path, BDB_THIS (table), path);
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, BDB_THIS (table), path);
- bctx->db_path = strdup (db_path);
- GF_VALIDATE_OR_GOTO ("bctx", bctx->directory, out);
+ bctx->db_path = strdup (db_path);
+ GF_VALIDATE_OR_GOTO ("bctx", bctx->directory, out);
- INIT_LIST_HEAD (&bctx->c_list);
- INIT_LIST_HEAD (&bctx->list);
- INIT_LIST_HEAD (&bctx->b_hash);
+ INIT_LIST_HEAD (&bctx->c_list);
+ INIT_LIST_HEAD (&bctx->list);
+ INIT_LIST_HEAD (&bctx->b_hash);
- LOCK_INIT (&bctx->lock);
+ LOCK_INIT (&bctx->lock);
- __hash_bctx (bctx);
+ __hash_bctx (bctx);
- list_add (&bctx->list, &table->b_lru);
- table->lru_size++;
+ list_add (&bctx->list, &table->b_lru);
+ table->lru_size++;
out:
- return bctx;
+ return bctx;
}
-/* bctx_lookup - lookup bctx_t for the directory @directory. (see description of bctx_t in bdb.h)
+/* bctx_lookup - lookup bctx_t for the directory @directory.
+ * (see description of bctx_t in bdb.h)
*
* @table: bctx_table_t for this instance of bdb.
- * @directory: directory for which bctx_t is being looked up.
+ * @directory: directory for which bctx_t is being looked up.
*/
bctx_t *
-bctx_lookup (bctx_table_t *table,
- const char *directory)
+bctx_lookup (bctx_table_t *table,
+ const char *directory)
{
- char *key = NULL;
- uint32_t key_hash = 0;
- bctx_t *trav = NULL, *bctx = NULL, *tmp = NULL;
- int32_t need_break = 0;
-
- GF_VALIDATE_OR_GOTO ("bctx", table, out);
- GF_VALIDATE_OR_GOTO ("bctx", directory, out);
-
- MAKE_KEY_FROM_PATH (key, directory);
- key_hash = bdb_key_hash (key, table->hash_size);
-
- LOCK (&table->lock);
- {
- if (!list_empty (&table->b_hash[key_hash])) {
- list_for_each_entry_safe (trav, tmp, &table->b_hash[key_hash], b_hash) {
- LOCK(&trav->lock);
- if (!strcmp(trav->directory, directory)) {
- bctx = __bctx_ref (trav);
- need_break = 1;
- }
- UNLOCK(&trav->lock);
- if (need_break)
- break;
- }
- }
-
- if (!bctx) {
- bctx = __create_bctx (table, directory);
- bctx = __bctx_ref (bctx);
- }
- }
- UNLOCK (&table->lock);
+ char *key = NULL;
+ uint32_t key_hash = 0;
+ bctx_t *trav = NULL, *bctx = NULL, *tmp = NULL;
+ int32_t need_break = 0;
+
+ GF_VALIDATE_OR_GOTO ("bctx", table, out);
+ GF_VALIDATE_OR_GOTO ("bctx", directory, out);
+
+ MAKE_KEY_FROM_PATH (key, directory);
+ key_hash = bdb_key_hash (key, table->hash_size);
+
+ LOCK (&table->lock);
+ {
+ if (list_empty (&table->b_hash[key_hash])) {
+ goto creat_bctx;
+ }
+
+ list_for_each_entry_safe (trav, tmp, &table->b_hash[key_hash],
+ b_hash) {
+ LOCK(&trav->lock);
+ {
+ if (!strcmp(trav->directory, directory)) {
+ bctx = __bctx_ref (trav);
+ need_break = 1;
+ }
+ }
+ UNLOCK(&trav->lock);
+
+ if (need_break)
+ break;
+ }
+
+ creat_bctx:
+ if (!bctx) {
+ bctx = __create_bctx (table, directory);
+ bctx = __bctx_ref (bctx);
+ }
+ }
+ UNLOCK (&table->lock);
out:
- return bctx;
+ return bctx;
}
bctx_t *
bctx_parent (bctx_table_t *table,
- const char *path)
+ const char *path)
{
- char *pathname = NULL, *directory = NULL;
- bctx_t *bctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("bctx", table, out);
- GF_VALIDATE_OR_GOTO ("bctx", path, out);
-
- pathname = strdup (path);
- GF_VALIDATE_OR_GOTO ("bctx", pathname, out);
- directory = dirname (pathname);
-
- bctx = bctx_lookup (table, directory);
- GF_VALIDATE_OR_GOTO ("bctx", bctx, out);
-
+ char *pathname = NULL, *directory = NULL;
+ bctx_t *bctx = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bctx", table, out);
+ GF_VALIDATE_OR_GOTO ("bctx", path, out);
+
+ pathname = strdup (path);
+ GF_VALIDATE_OR_GOTO ("bctx", pathname, out);
+ directory = dirname (pathname);
+
+ bctx = bctx_lookup (table, directory);
+ GF_VALIDATE_OR_GOTO ("bctx", bctx, out);
+
out:
- if (pathname)
- free (pathname);
- return bctx;
+ if (pathname)
+ free (pathname);
+ return bctx;
}
inline int32_t
-bdb_db_rename (bctx_table_t *table,
- const char *oldpath,
- const char *newpath)
+bdb_db_rename (bctx_table_t *table,
+ const char *oldpath,
+ const char *newpath)
{
- DB_ENV *dbenv = NULL;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("bctx", table, out);
- GF_VALIDATE_OR_GOTO ("bctx", oldpath, out);
- GF_VALIDATE_OR_GOTO ("bctx", newpath, out);
-
- dbenv = table->dbenv;
- GF_VALIDATE_OR_GOTO ("bctx", dbenv, out);
-
- LOCK (&table->lock);
- {
- ret = dbenv->dbrename (dbenv, NULL, oldpath, NULL, newpath, 0);
-
- if (ret != 0) {
- gf_log ("bctx",
- GF_LOG_ERROR,
- "failed to rename %s to %s: %s",
- oldpath, newpath, db_strerror (ret));
- } else {
- gf_log ("bctx",
- GF_LOG_DEBUG,
- "successfully renamed %s to %s: %s",
- oldpath, newpath, db_strerror (ret));
- }
- }
- UNLOCK (&table->lock);
+ DB_ENV *dbenv = NULL;
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("bctx", table, out);
+ GF_VALIDATE_OR_GOTO ("bctx", oldpath, out);
+ GF_VALIDATE_OR_GOTO ("bctx", newpath, out);
+
+ dbenv = table->dbenv;
+ GF_VALIDATE_OR_GOTO ("bctx", dbenv, out);
+
+ LOCK (&table->lock);
+ {
+ ret = dbenv->dbrename (dbenv, NULL, oldpath, NULL, newpath, 0);
+
+ if (ret != 0) {
+ gf_log ("bctx", GF_LOG_ERROR,
+ "failed to rename %s to %s: %s",
+ oldpath, newpath, db_strerror (ret));
+ } else {
+ gf_log ("bctx", GF_LOG_DEBUG,
+ "successfully renamed %s to %s: %s",
+ oldpath, newpath, db_strerror (ret));
+ }
+ }
+ UNLOCK (&table->lock);
out:
- return ret;
+ return ret;
}
bctx_t *
-bctx_rename (bctx_t *bctx,
- const char *db_newpath)
+bctx_rename (bctx_t *bctx,
+ const char *db_newpath)
{
- bctx_table_t *table = NULL;
- int32_t ret = -1;
-
- table = bctx->table;
-
- LOCK (&table->lock);
- {
- __unhash_bctx (bctx);
- list_del_init (&bctx->list);
- if (bctx->dbp) {
- ret = bctx->dbp->close (bctx->dbp, 0);
- if (ret != 0) {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "failed to close db for directory %s (%s)",
- bctx->directory, db_strerror (ret));
- }
- bctx->dbp = NULL;
- }
- }
- UNLOCK (&table->lock);
-
- ret = bdb_db_rename (table, bctx->db_path, db_newpath);
-
- if (ret != 0) {
- gf_log ("bctx",
- GF_LOG_ERROR,
- "bdb_db_rename failed for directory %s",
- bctx->directory);
- bctx = NULL;
- }
-
- return bctx;
+ bctx_table_t *table = NULL;
+ int32_t ret = -1;
+
+ table = bctx->table;
+
+ LOCK (&table->lock);
+ {
+ __unhash_bctx (bctx);
+ list_del_init (&bctx->list);
+ if (bctx->dbp) {
+ ret = bctx->dbp->close (bctx->dbp, 0);
+ if (ret != 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to close db for "
+ "directory %s (%s)",
+ bctx->directory, db_strerror (ret));
+ }
+ bctx->dbp = NULL;
+ }
+ }
+ UNLOCK (&table->lock);
+
+ ret = bdb_db_rename (table, bctx->db_path, db_newpath);
+
+ if (ret != 0) {
+ gf_log ("bctx", GF_LOG_ERROR,
+ "bdb_db_rename failed for directory %s",
+ bctx->directory);
+ bctx = NULL;
+ }
+
+ return bctx;
}
diff --git a/xlators/storage/bdb/src/bdb-ll.c b/xlators/storage/bdb/src/bdb-ll.c
index 5a79987ae46..cd2d1ac4916 100644
--- a/xlators/storage/bdb/src/bdb-ll.c
+++ b/xlators/storage/bdb/src/bdb-ll.c
@@ -20,7 +20,7 @@
#include <libgen.h>
#include "bdb.h"
#include <list.h>
-/*
+/*
* implement the procedures to interact with bdb */
/****************************************************************
@@ -28,26 +28,23 @@
* General wrappers and utility procedures for bdb xlator
*
****************************************************************/
-#define BDB_LL_PAGE_SIZE_DEFAULT 4096
-#define BDB_LL_PAGE_SIZE_MIN 4096
-#define BDB_LL_PAGE_SIZE_MAX 65536
ino_t
bdb_inode_transform (ino_t parent,
bctx_t *bctx)
{
- struct bdb_private *private = NULL;
- ino_t ino = -1;
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ struct bdb_private *private = NULL;
+ ino_t ino = -1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
- private = bctx->table->this->private;
+ private = bctx->table->this->private;
- LOCK (&private->ino_lock);
- ino = ++private->next_ino;
- UNLOCK (&private->ino_lock);
+ LOCK (&private->ino_lock);
+ ino = ++private->next_ino;
+ UNLOCK (&private->ino_lock);
out:
- return ino;
+ return ino;
}
@@ -71,132 +68,132 @@ out:
static DB *
bdb_db_open (bctx_t *bctx)
{
- DB *storage_dbp = NULL;
- int32_t op_ret = -1;
- bctx_table_t *table = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
-
- table = bctx->table;
- GF_VALIDATE_OR_GOTO ("bdb-ll", table, out);
-
- /* we have to do the following, we can't deny someone of db_open ;) */
- op_ret = db_create (&storage_dbp, table->dbenv, 0);
- if (op_ret != 0) {
- gf_log ("bdb-ll", GF_LOG_ERROR,
- "failed to do db_create for directory %s (%s)",
- bctx->directory, db_strerror (op_ret));
- storage_dbp = NULL;
- goto out;
- }
-
- if (table->page_size) {
- op_ret = storage_dbp->set_pagesize (storage_dbp,
- table->page_size);
- if (op_ret != 0) {
- gf_log ("bdb-ll", GF_LOG_ERROR,
- "failed to set the page_size (%"PRIu64") for directory %s (%s)",
- table->page_size, bctx->directory, db_strerror (op_ret));
- } else {
- gf_log ("bdb-ll", GF_LOG_DEBUG,
- "page-size (%"PRIu64") set on DB",
- table->page_size);
- }
- }
-
- op_ret = storage_dbp->open (storage_dbp,
- NULL,
- bctx->db_path,
- NULL,
- table->access_mode,
- table->dbflags,
- 0);
- if (op_ret != 0 ) {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "failed to open storage-db for directory %s (%s)",
- bctx->db_path, db_strerror (op_ret));
- storage_dbp = NULL;
- }
+ DB *storage_dbp = NULL;
+ int32_t op_ret = -1;
+ bctx_table_t *table = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+
+ table = bctx->table;
+ GF_VALIDATE_OR_GOTO ("bdb-ll", table, out);
+
+ /* we have to do the following, we can't deny someone of db_open ;) */
+ op_ret = db_create (&storage_dbp, table->dbenv, 0);
+ if (op_ret != 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to do db_create for directory %s (%s)",
+ bctx->directory, db_strerror (op_ret));
+ storage_dbp = NULL;
+ goto out;
+ }
+
+ if (table->page_size) {
+ op_ret = storage_dbp->set_pagesize (storage_dbp,
+ table->page_size);
+ if (op_ret != 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to set the page_size (%"PRIu64") for "
+ "directory %s (%s)",
+ table->page_size, bctx->directory,
+ db_strerror (op_ret));
+ } else {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "page-size (%"PRIu64") set on DB",
+ table->page_size);
+ }
+ }
+
+ op_ret = storage_dbp->open (storage_dbp,
+ NULL,
+ bctx->db_path,
+ NULL,
+ table->access_mode,
+ table->dbflags,
+ 0);
+ if (op_ret != 0 ) {
+ gf_log ("bdb-ll",
+ GF_LOG_ERROR,
+ "failed to open storage-db for directory %s (%s)",
+ bctx->db_path, db_strerror (op_ret));
+ storage_dbp = NULL;
+ }
out:
- return storage_dbp;
+ return storage_dbp;
}
int32_t
bdb_cursor_close (bctx_t *bctx,
- DBC *cursorp)
+ DBC *cursorp)
{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
- GF_VALIDATE_OR_GOTO ("bdb-ll", cursorp, out);
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", cursorp, out);
- LOCK (&bctx->lock);
- {
+ LOCK (&bctx->lock);
+ {
#ifdef HAVE_BDB_CURSOR_GET
- ret = cursorp->close (cursorp);
+ ret = cursorp->close (cursorp);
#else
- ret = cursorp->c_close (cursorp);
+ ret = cursorp->c_close (cursorp);
#endif
- if ((ret != 0)) {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "failed to close db cursor for directory %s (%s)",
- bctx->directory, db_strerror (ret));
- }
- }
- UNLOCK (&bctx->lock);
-
-out:
- return ret;
+ if ((ret != 0)) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to close db cursor for directory "
+ "%s (%s)",
+ bctx->directory, db_strerror (ret));
+ }
+ }
+ UNLOCK (&bctx->lock);
+
+out:
+ return ret;
}
int32_t
bdb_cursor_open (bctx_t *bctx,
- DBC **cursorpp)
+ DBC **cursorpp)
{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
- GF_VALIDATE_OR_GOTO ("bdb-ll", cursorpp, out);
-
- LOCK (&bctx->lock);
- {
- if (bctx->dbp) {
- /* do nothing, just continue */
- ret = 0;
- } else {
- bctx->dbp = bdb_db_open (bctx);
- if (!bctx->dbp) {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "failed to open storage db for %s",
- bctx->directory);
- ret = -1;
- } else {
- ret = 0;
- }
- }
-
- if (ret == 0) {
- /* all set, lets open cursor */
- ret = bctx->dbp->cursor (bctx->dbp, NULL, cursorpp, 0);
- if (ret != 0) {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "failed to create a cursor for %s (%s)",
- bctx->directory, db_strerror (ret));
- }
- }
- }
- UNLOCK (&bctx->lock);
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", cursorpp, out);
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->dbp) {
+ /* do nothing, just continue */
+ ret = 0;
+ } else {
+ bctx->dbp = bdb_db_open (bctx);
+ if (!bctx->dbp) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to open storage db for %s",
+ bctx->directory);
+ ret = -1;
+ } else {
+ ret = 0;
+ }
+ }
+
+ if (ret == 0) {
+ /* all set, lets open cursor */
+ ret = bctx->dbp->cursor (bctx->dbp, NULL, cursorpp, 0);
+ if (ret != 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to create a cursor for %s (%s)",
+ bctx->directory, db_strerror (ret));
+ }
+ }
+ }
+ UNLOCK (&bctx->lock);
out:
- return ret;
+ return ret;
}
@@ -205,167 +202,163 @@ static bdb_cache_t *
bdb_cache_lookup (bctx_t *bctx,
char *path)
{
- bdb_cache_t *bcache = NULL;
- bdb_cache_t *trav = NULL;
- char *key = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
- GF_VALIDATE_OR_GOTO ("bdb-ll", path, out);
-
- MAKE_KEY_FROM_PATH (key, path);
-
- LOCK (&bctx->lock);
- {
- list_for_each_entry (trav, &bctx->c_list, c_list) {
- if (!strcmp (trav->key, key)){
- bcache = trav;
- break;
- }
- }
- }
- UNLOCK (&bctx->lock);
+ bdb_cache_t *bcache = NULL;
+ bdb_cache_t *trav = NULL;
+ char *key = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", path, out);
+
+ MAKE_KEY_FROM_PATH (key, path);
+
+ LOCK (&bctx->lock);
+ {
+ list_for_each_entry (trav, &bctx->c_list, c_list) {
+ if (!strcmp (trav->key, key)){
+ bcache = trav;
+ break;
+ }
+ }
+ }
+ UNLOCK (&bctx->lock);
out:
- return bcache;
+ return bcache;
}
static int32_t
-bdb_cache_insert (bctx_t *bctx,
- DBT *key,
- DBT *data)
+bdb_cache_insert (bctx_t *bctx,
+ DBT *key,
+ DBT *data)
{
- bdb_cache_t *bcache = NULL;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
- GF_VALIDATE_OR_GOTO ("bdb-ll", key, out);
- GF_VALIDATE_OR_GOTO ("bdb-ll", data, out);
-
- LOCK (&bctx->lock);
- {
- if (bctx->c_count > 5) {
- /* most of the times, we enter here */
- /* FIXME: ugly, not supposed to disect any of the
- * 'struct list_head' directly */
- if (!list_empty (&bctx->c_list)) {
- bcache = list_entry (bctx->c_list.prev, bdb_cache_t, c_list);
- list_del_init (&bcache->c_list);
- }
- if (bcache->key) {
- free (bcache->key);
- bcache->key = strdup ((char *)key->data);
- GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->key, unlock);
- } else {
- /* should never come here */
- gf_log ("bdb-ll",
- GF_LOG_CRITICAL,
- "bcache->key (null)");
- } /* if(bcache->key)...else */
- if (bcache->data) {
- free (bcache->data);
- bcache->data = memdup (data->data, data->size);
- GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->data, unlock);
- bcache->size = data->size;
- } else {
- /* should never come here */
- gf_log ("bdb-ll",
- GF_LOG_CRITICAL,
- "bcache->data (null)");
- } /* if(bcache->data)...else */
- list_add (&bcache->c_list, &bctx->c_list);
- ret = 0;
- } else {
- /* we will be entering here very rarely */
- bcache = CALLOC (1, sizeof (*bcache));
- GF_VALIDATE_OR_GOTO ("bdb-ll", bcache, unlock);
- bcache->key = strdup ((char *)(key->data));
- GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->key, unlock);
- bcache->data = memdup (data->data, data->size);
- GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->data, unlock);
- bcache->size = data->size;
- list_add (&bcache->c_list, &bctx->c_list);
- bctx->c_count++;
- ret = 0;
- } /* if(private->c_count < 5)...else */
- }
+ bdb_cache_t *bcache = NULL;
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", key, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", data, out);
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->c_count > 5) {
+ /* most of the times, we enter here */
+ /* FIXME: ugly, not supposed to disect any of the
+ * 'struct list_head' directly */
+ if (!list_empty (&bctx->c_list)) {
+ bcache = list_entry (bctx->c_list.prev, bdb_cache_t, c_list);
+ list_del_init (&bcache->c_list);
+ }
+ if (bcache->key) {
+ free (bcache->key);
+ bcache->key = strdup ((char *)key->data);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->key, unlock);
+ } else {
+ /* should never come here */
+ gf_log ("bdb-ll", GF_LOG_CRITICAL,
+ "bcache->key (null)");
+ } /* if(bcache->key)...else */
+ if (bcache->data) {
+ free (bcache->data);
+ bcache->data = memdup (data->data, data->size);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->data, unlock);
+ bcache->size = data->size;
+ } else {
+ /* should never come here */
+ gf_log ("bdb-ll", GF_LOG_CRITICAL,
+ "bcache->data (null)");
+ } /* if(bcache->data)...else */
+ list_add (&bcache->c_list, &bctx->c_list);
+ ret = 0;
+ } else {
+ /* we will be entering here very rarely */
+ bcache = CALLOC (1, sizeof (*bcache));
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bcache, unlock);
+ bcache->key = strdup ((char *)(key->data));
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->key, unlock);
+ bcache->data = memdup (data->data, data->size);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->data, unlock);
+ bcache->size = data->size;
+ list_add (&bcache->c_list, &bctx->c_list);
+ bctx->c_count++;
+ ret = 0;
+ } /* if(private->c_count < 5)...else */
+ }
unlock:
- UNLOCK (&bctx->lock);
+ UNLOCK (&bctx->lock);
out:
- return ret;
+ return ret;
}
static int32_t
bdb_cache_delete (bctx_t *bctx,
- char *key)
+ char *key)
{
- bdb_cache_t *bcache = NULL;
- bdb_cache_t *trav = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
- GF_VALIDATE_OR_GOTO ("bdb-ll", key, out);
-
- LOCK (&bctx->lock);
- {
- list_for_each_entry (trav, &bctx->c_list, c_list) {
- if (!strcmp (trav->key, key)){
- bctx->c_count--;
- bcache = trav;
- break;
- }
- }
-
- if (bcache) {
- list_del_init (&bcache->c_list);
- free (bcache->key);
- free (bcache->data);
- free (bcache);
- }
- }
- UNLOCK (&bctx->lock);
+ bdb_cache_t *bcache = NULL;
+ bdb_cache_t *trav = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", key, out);
+
+ LOCK (&bctx->lock);
+ {
+ list_for_each_entry (trav, &bctx->c_list, c_list) {
+ if (!strcmp (trav->key, key)){
+ bctx->c_count--;
+ bcache = trav;
+ break;
+ }
+ }
+
+ if (bcache) {
+ list_del_init (&bcache->c_list);
+ free (bcache->key);
+ free (bcache->data);
+ free (bcache);
+ }
+ }
+ UNLOCK (&bctx->lock);
out:
- return 0;
+ return 0;
}
void *
-bdb_db_stat (bctx_t *bctx,
- DB_TXN *txnid,
- uint32_t flags)
+bdb_db_stat (bctx_t *bctx,
+ DB_TXN *txnid,
+ uint32_t flags)
{
- DB *storage = NULL;
- void *stat = NULL;
- int32_t ret = -1;
-
- LOCK (&bctx->lock);
- {
- if (bctx->dbp == NULL) {
- bctx->dbp = bdb_db_open (bctx);
- storage = bctx->dbp;
- } else {
- /* we are just fine, lets continue */
- storage = bctx->dbp;
- } /* if(bctx->dbp==NULL)...else */
- }
- UNLOCK (&bctx->lock);
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
-
- ret = storage->stat (storage, txnid, &stat, flags);
-
- if (ret != 0) {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "failed to do DB->stat() on db file %s: %s",
- bctx->db_path, db_strerror (ret));
- } else {
- gf_log ("bdb-ll",
- GF_LOG_DEBUG,
- "successfully called DB->stat() on db file %s",
- bctx->db_path);
- }
+ DB *storage = NULL;
+ void *stat = NULL;
+ int32_t ret = -1;
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->dbp == NULL) {
+ bctx->dbp = bdb_db_open (bctx);
+ storage = bctx->dbp;
+ } else {
+ /* we are just fine, lets continue */
+ storage = bctx->dbp;
+ } /* if(bctx->dbp==NULL)...else */
+ }
+ UNLOCK (&bctx->lock);
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
+
+ ret = storage->stat (storage, txnid, &stat, flags);
+
+ if (ret != 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to do DB->stat() on db file %s: %s",
+ bctx->db_path, db_strerror (ret));
+ } else {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "successfully called DB->stat() on db file %s",
+ bctx->db_path);
+ }
out:
- return stat;
-
+ return stat;
+
}
/* bdb_storage_get - retrieve a key/value pair corresponding to @path from the corresponding
@@ -374,18 +367,18 @@ out:
* @bctx: bctx_t * corresponding to the parent directory of @path. (should always be a valid
* bctx). bdb_storage_get should never be called if @bctx = NULL.
* @txnid: NULL if bdb_storage_get is not embedded in an explicit transaction or a valid
- * DB_TXN *, when embedded in an explicit transaction.
+ * DB_TXN *, when embedded in an explicit transaction.
* @path: path of the file to read from (translated to a database key using MAKE_KEY_FROM_PATH)
* @buf: char ** - pointer to a pointer to char. a read buffer is created in this procedure
* and pointer to the buffer is passed through @buf to the caller.
* @size: size of the file content to be read.
* @offset: offset from which the file content to be read.
*
- * NOTE: bdb_storage_get tries to open DB, if @bctx->dbp == NULL (@bctx->dbp == NULL,
+ * NOTE: bdb_storage_get tries to open DB, if @bctx->dbp == NULL (@bctx->dbp == NULL,
* nobody has opened DB till now or DB was closed by bdb_table_prune()).
*
* NOTE: if private->cache is set (bdb xlator's internal caching enabled), then bdb_storage_get
- * first looks up the cache for key/value pair. if bdb_lookup_cache fails, then only
+ * first looks up the cache for key/value pair. if bdb_lookup_cache fails, then only
* DB->get() is called. also, inserts a newly read key/value pair to cache through
* bdb_insert_to_cache.
*
@@ -395,300 +388,302 @@ out:
*/
int32_t
bdb_db_get (bctx_t *bctx,
- DB_TXN *txnid,
- const char *path,
- char **buf,
- size_t size,
- off_t offset)
+ DB_TXN *txnid,
+ const char *path,
+ char **buf,
+ size_t size,
+ off_t offset)
{
- DB *storage = NULL;
- DBT key = {0,};
- DBT value = {0,};
- int32_t ret = -1;
- char *key_string = NULL;
- bdb_cache_t *bcache = NULL;
- int32_t db_flags = 0;
- uint8_t need_break = 0;
- int32_t retries = 1;
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
- GF_VALIDATE_OR_GOTO ("bdb-ll", path, out);
-
- MAKE_KEY_FROM_PATH (key_string, path);
-
- if (bctx->cache &&
- ((bcache = bdb_cache_lookup (bctx, key_string)) != NULL)) {
- if (buf) {
- *buf = CALLOC (1, bcache->size);
- GF_VALIDATE_OR_GOTO ("bdb-ll", buf, out);
- memcpy (*buf, (bcache->data + offset), bcache->size);
- }
- ret = bcache->size;
- } else {
- LOCK (&bctx->lock);
- {
- if (bctx->dbp == NULL) {
- bctx->dbp = bdb_db_open (bctx);
- storage = bctx->dbp;
- } else {
- /* we are just fine, lets continue */
- storage = bctx->dbp;
- } /* if(bctx->dbp==NULL)...else */
- }
- UNLOCK (&bctx->lock);
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
-
- key.data = (char *)key_string;
- key.size = strlen (key_string);
- key.flags = DB_DBT_USERMEM;
-
- if (bctx->cache){
- /* we are called to return the size of the file */
- value.flags = DB_DBT_MALLOC;
- } else {
- if (size) {
- value.flags = DB_DBT_MALLOC | DB_DBT_PARTIAL;
- } else {
- value.flags = DB_DBT_MALLOC;
- }
- value.dlen = size;
- value.doff = offset;
- }
-
- do {
- /* TODO: we prefer to give our own buffer to value.data
- * and ask bdb to fill in it */
- ret = storage->get (storage, txnid, &key, &value, db_flags);
-
- if (ret == DB_NOTFOUND) {
- gf_log ("bdb-ll",
- GF_LOG_DEBUG,
- "failed to do DB->get() for key: %s."
- " key not found in storage DB", key_string);
- ret = -1;
- need_break = 1;
- } else if (ret == DB_LOCK_DEADLOCK) {
- retries++;
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "deadlock detected in DB->put. retrying DB->put (%d)",
- retries);
- }else if (ret == 0) {
- /* successfully read data, lets set everything in place
- * and return */
- if (buf) {
- *buf = CALLOC (1, value.size);
- ERR_ABORT (*buf);
- memcpy (*buf, value.data, value.size);
- }
- ret = value.size;
- if (bctx->cache)
- bdb_cache_insert (bctx, &key, &value);
- free (value.data);
- need_break = 1;
- } else {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "failed to do DB->get() for key %s: %s",
- key_string, db_strerror (ret));
- ret = -1;
- need_break = 1;
- }
- } while (!need_break);
- }
-out:
- return ret;
+ DB *storage = NULL;
+ DBT key = {0,};
+ DBT value = {0,};
+ int32_t ret = -1;
+ char *key_string = NULL;
+ bdb_cache_t *bcache = NULL;
+ int32_t db_flags = 0;
+ uint8_t need_break = 0;
+ int32_t retries = 1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", path, out);
+
+ MAKE_KEY_FROM_PATH (key_string, path);
+
+ if (bctx->cache &&
+ ((bcache = bdb_cache_lookup (bctx, key_string)) != NULL)) {
+ if (buf) {
+ *buf = CALLOC (1, bcache->size);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", buf, out);
+ memcpy (*buf, (bcache->data + offset), bcache->size);
+ }
+ ret = bcache->size;
+ } else {
+ LOCK (&bctx->lock);
+ {
+ if (bctx->dbp == NULL) {
+ bctx->dbp = bdb_db_open (bctx);
+ storage = bctx->dbp;
+ } else {
+ /* we are just fine, lets continue */
+ storage = bctx->dbp;
+ } /* if(bctx->dbp==NULL)...else */
+ }
+ UNLOCK (&bctx->lock);
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
+
+ key.data = (char *)key_string;
+ key.size = strlen (key_string);
+ key.flags = DB_DBT_USERMEM;
+
+ if (bctx->cache){
+ /* we are called to return the size of the file */
+ value.flags = DB_DBT_MALLOC;
+ } else {
+ if (size) {
+ value.flags = DB_DBT_MALLOC | DB_DBT_PARTIAL;
+ } else {
+ value.flags = DB_DBT_MALLOC;
+ }
+ value.dlen = size;
+ value.doff = offset;
+ }
+
+ do {
+ /* TODO: we prefer to give our own buffer to value.data
+ * and ask bdb to fill in it */
+ ret = storage->get (storage, txnid, &key, &value,
+ db_flags);
+
+ if (ret == DB_NOTFOUND) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "failed to do DB->get() for key: %s."
+ " key not found in storage DB",
+ key_string);
+ ret = -1;
+ need_break = 1;
+ } else if (ret == DB_LOCK_DEADLOCK) {
+ retries++;
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "deadlock detected in DB->put. retrying"
+ " DB->put (%d)", retries);
+ }else if (ret == 0) {
+ /* successfully read data, lets set everything
+ * in place and return */
+ if (buf) {
+ *buf = CALLOC (1, value.size);
+ ERR_ABORT (*buf);
+ memcpy (*buf, value.data, value.size);
+ }
+ ret = value.size;
+ if (bctx->cache)
+ bdb_cache_insert (bctx, &key, &value);
+ free (value.data);
+ need_break = 1;
+ } else {
+ gf_log ("bdb-ll",
+ GF_LOG_ERROR,
+ "failed to do DB->get() for key %s: %s",
+ key_string, db_strerror (ret));
+ ret = -1;
+ need_break = 1;
+ }
+ } while (!need_break);
+ }
+out:
+ return ret;
}/* bdb_db_get */
/* bdb_storage_put - insert a key/value specified to the corresponding DB.
*
- * @bctx: bctx_t * corresponding to the parent directory of @path.
- * (should always be a valid bctx). bdb_storage_put should never be called if @bctx = NULL.
- * @txnid: NULL if bdb_storage_put is not embedded in an explicit transaction or a valid
- * DB_TXN *, when embedded in an explicit transaction.
+ * @bctx: bctx_t * corresponding to the parent directory of @path.
+ * (should always be a valid bctx). bdb_storage_put should never be
+ * called if @bctx = NULL.
+ * @txnid: NULL if bdb_storage_put is not embedded in an explicit transaction
+ * or a valid DB_TXN *, when embedded in an explicit transaction.
* @key_string: key of the database entry.
* @buf: pointer to the buffer data to be written as data for @key_string.
* @size: size of @buf.
* @offset: offset in the key's data to be modified with provided data.
- * @flags: valid flags are BDB_TRUNCATE_RECORD (to reduce the data of @key_string to 0 size).
+ * @flags: valid flags are BDB_TRUNCATE_RECORD (to reduce the data of
+ * @key_string to 0 size).
*
- * NOTE: bdb_storage_put tries to open DB, if @bctx->dbp == NULL (@bctx->dbp == NULL,
- * nobody has opened DB till now or DB was closed by bdb_table_prune()).
+ * NOTE: bdb_storage_put tries to open DB, if @bctx->dbp == NULL
+ * (@bctx->dbp == NULL, nobody has opened DB till now or DB was closed by
+ * bdb_table_prune()).
*
* NOTE: bdb_storage_put deletes the key/value from bdb xlator's internal cache.
*
* return: 0 on success or -1 on error.
*
- * also see: bdb_cache_delete for details on how a cached key/value pair is removed.
+ * also see: bdb_cache_delete for details on how a cached key/value pair is
+ * removed.
*/
int32_t
bdb_db_put (bctx_t *bctx,
- DB_TXN *txnid,
- const char *key_string,
- const char *buf,
- size_t size,
- off_t offset,
- int32_t flags)
+ DB_TXN *txnid,
+ const char *key_string,
+ const char *buf,
+ size_t size,
+ off_t offset,
+ int32_t flags)
{
- DB *storage = NULL;
- DBT key = {0,}, value = {0,};
- int32_t ret = -1;
- int32_t db_flags = DB_AUTO_COMMIT;
- uint8_t need_break = 0;
- int32_t retries = 1;
-
- LOCK (&bctx->lock);
- {
- if (bctx->dbp == NULL) {
- bctx->dbp = bdb_db_open (bctx);
- storage = bctx->dbp;
- } else {
- /* we are just fine, lets continue */
- storage = bctx->dbp;
- }
- }
- UNLOCK (&bctx->lock);
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
-
- if (bctx->cache) {
- ret = bdb_cache_delete (bctx, (char *)key_string);
- GF_VALIDATE_OR_GOTO ("bdb-ll", (ret == 0), out);
- }
-
- key.data = (void *)key_string;
- key.size = strlen (key_string);
-
- /* NOTE: bdb lets us expand the file, suppose value.size > value.len, then value.len bytes
- * from value.doff offset and value.size bytes will be written from value.doff and
- * data from value.doff + value.dlen will be pushed value.doff + value.size
- */
- value.data = (void *)buf;
-
- if (flags & BDB_TRUNCATE_RECORD) {
- value.size = size;
- value.doff = 0;
- value.dlen = offset;
- } else {
- value.size = size;
- value.dlen = size;
- value.doff = offset;
- }
- value.flags = DB_DBT_PARTIAL;
- if (buf == NULL && size == 0)
- /* truncate called us */
- value.flags = 0;
-
- do {
- ret = storage->put (storage, txnid, &key, &value, db_flags);
- if (ret == DB_LOCK_DEADLOCK) {
- retries++;
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "deadlock detected in DB->put. retrying DB->put (%d)",
- retries);
- } else if (ret) {
- /* write failed */
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "failed to do DB->put() for key %s: %s",
- key_string, db_strerror (ret));
- need_break = 1;
- } else {
- /* successfully wrote */
- ret = 0;
- need_break = 1;
- }
- } while (!need_break);
+ DB *storage = NULL;
+ DBT key = {0,}, value = {0,};
+ int32_t ret = -1;
+ int32_t db_flags = DB_AUTO_COMMIT;
+ uint8_t need_break = 0;
+ int32_t retries = 1;
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->dbp == NULL) {
+ bctx->dbp = bdb_db_open (bctx);
+ storage = bctx->dbp;
+ } else {
+ /* we are just fine, lets continue */
+ storage = bctx->dbp;
+ }
+ }
+ UNLOCK (&bctx->lock);
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
+
+ if (bctx->cache) {
+ ret = bdb_cache_delete (bctx, (char *)key_string);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", (ret == 0), out);
+ }
+
+ key.data = (void *)key_string;
+ key.size = strlen (key_string);
+
+ /* NOTE: bdb lets us expand the file, suppose value.size > value.len,
+ * then value.len bytes from value.doff offset and value.size bytes
+ * will be written from value.doff and data from
+ * value.doff + value.dlen will be pushed value.doff + value.size
+ */
+ value.data = (void *)buf;
+
+ if (flags & BDB_TRUNCATE_RECORD) {
+ value.size = size;
+ value.doff = 0;
+ value.dlen = offset;
+ } else {
+ value.size = size;
+ value.dlen = size;
+ value.doff = offset;
+ }
+ value.flags = DB_DBT_PARTIAL;
+ if (buf == NULL && size == 0)
+ /* truncate called us */
+ value.flags = 0;
+
+ do {
+ ret = storage->put (storage, txnid, &key, &value, db_flags);
+ if (ret == DB_LOCK_DEADLOCK) {
+ retries++;
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "deadlock detected in DB->put. "
+ "retrying DB->put (%d)",
+ retries);
+ } else if (ret) {
+ /* write failed */
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to do DB->put() for key %s: %s",
+ key_string, db_strerror (ret));
+ need_break = 1;
+ } else {
+ /* successfully wrote */
+ ret = 0;
+ need_break = 1;
+ }
+ } while (!need_break);
out:
- return ret;
+ return ret;
}/* bdb_db_put */
/* bdb_storage_del - delete a key/value pair corresponding to @path from corresponding db file.
*
- * @bctx: bctx_t * corresponding to the parent directory of @path.
+ * @bctx: bctx_t * corresponding to the parent directory of @path.
* (should always be a valid bctx). bdb_storage_del should never be called
* if @bctx = NULL.
* @txnid: NULL if bdb_storage_del is not embedded in an explicit transaction or a
- * valid DB_TXN *, when embedded in an explicit transaction.
+ * valid DB_TXN *, when embedded in an explicit transaction.
* @path: path to the file, whose key/value pair has to be deleted.
*
- * NOTE: bdb_storage_del tries to open DB, if @bctx->dbp == NULL (@bctx->dbp == NULL,
+ * NOTE: bdb_storage_del tries to open DB, if @bctx->dbp == NULL (@bctx->dbp == NULL,
* nobody has opened DB till now or DB was closed by bdb_table_prune()).
*
* return: 0 on success or -1 on error.
*/
int32_t
bdb_db_del (bctx_t *bctx,
- DB_TXN *txnid,
- const char *path)
+ DB_TXN *txnid,
+ const char *path)
{
- DB *storage = NULL;
- DBT key = {0,};
- char *key_string = NULL;
- int32_t ret = -1;
- int32_t db_flags = 0;
- uint8_t need_break = 0;
- int32_t retries = 1;
-
- MAKE_KEY_FROM_PATH (key_string, path);
-
- LOCK (&bctx->lock);
- {
- if (bctx->dbp == NULL) {
- bctx->dbp = bdb_db_open (bctx);
- storage = bctx->dbp;
- } else {
- /* we are just fine, lets continue */
- storage = bctx->dbp;
- }
- }
- UNLOCK (&bctx->lock);
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
-
- ret = bdb_cache_delete (bctx, key_string);
- GF_VALIDATE_OR_GOTO ("bdb-ll", (ret == 0), out);
-
- key.data = key_string;
- key.size = strlen (key_string);
- key.flags = DB_DBT_USERMEM;
-
- do {
- ret = storage->del (storage, txnid, &key, db_flags);
-
- if (ret == DB_NOTFOUND) {
- gf_log ("bdb-ll",
- GF_LOG_DEBUG,
- "failed to delete %s from storage db, doesn't exist in storage DB",
- path);
- need_break = 1;
- } else if (ret == DB_LOCK_DEADLOCK) {
- retries++;
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "deadlock detected in DB->put. retrying DB->put (%d)",
- retries);
- }else if (ret == 0) {
- /* successfully deleted the entry */
- gf_log ("bdb-ll",
- GF_LOG_DEBUG,
- "deleted %s from storage db", path);
- ret = 0;
- need_break = 1;
- } else {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "failed to delete %s from storage db: %s",
- path, db_strerror (ret));
- ret = -1;
- need_break = 1;
- }
- } while (!need_break);
+ DB *storage = NULL;
+ DBT key = {0,};
+ char *key_string = NULL;
+ int32_t ret = -1;
+ int32_t db_flags = 0;
+ uint8_t need_break = 0;
+ int32_t retries = 1;
+
+ MAKE_KEY_FROM_PATH (key_string, path);
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->dbp == NULL) {
+ bctx->dbp = bdb_db_open (bctx);
+ storage = bctx->dbp;
+ } else {
+ /* we are just fine, lets continue */
+ storage = bctx->dbp;
+ }
+ }
+ UNLOCK (&bctx->lock);
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
+
+ ret = bdb_cache_delete (bctx, key_string);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", (ret == 0), out);
+
+ key.data = key_string;
+ key.size = strlen (key_string);
+ key.flags = DB_DBT_USERMEM;
+
+ do {
+ ret = storage->del (storage, txnid, &key, db_flags);
+
+ if (ret == DB_NOTFOUND) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "failed to delete %s from storage db, "
+ "doesn't exist in storage DB",
+ path);
+ need_break = 1;
+ } else if (ret == DB_LOCK_DEADLOCK) {
+ retries++;
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "deadlock detected in DB->put. "
+ "retrying DB->put (%d)",
+ retries);
+ }else if (ret == 0) {
+ /* successfully deleted the entry */
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "deleted %s from storage db", path);
+ ret = 0;
+ need_break = 1;
+ } else {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to delete %s from storage db: %s",
+ path, db_strerror (ret));
+ ret = -1;
+ need_break = 1;
+ }
+ } while (!need_break);
out:
- return ret;
+ return ret;
}
/* NOTE: bdb version compatibility wrapper */
@@ -698,31 +693,30 @@ bdb_cursor_get (DBC *cursorp,
DBT *value,
int32_t flags)
{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", cursorp, out);
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", cursorp, out);
#ifdef HAVE_BDB_CURSOR_GET
- ret = cursorp->get (cursorp, key, value, flags);
+ ret = cursorp->get (cursorp, key, value, flags);
#else
- ret = cursorp->c_get (cursorp, key, value, flags);
+ ret = cursorp->c_get (cursorp, key, value, flags);
#endif
- if ((ret != 0) && (ret != DB_NOTFOUND)) {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "failed to CURSOR->get() for key %s (%s)",
- (char *)key->data, db_strerror (ret));
- }
+ if ((ret != 0) && (ret != DB_NOTFOUND)) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to CURSOR->get() for key %s (%s)",
+ (char *)key->data, db_strerror (ret));
+ }
out:
- return ret;
+ return ret;
}/* bdb_cursor_get */
int32_t
bdb_dirent_size (DBT *key)
{
- return ALIGN (24 /* FIX MEEEE!!! */ + key->size);
+ return ALIGN (24 /* FIX MEEEE!!! */ + key->size);
}
@@ -737,29 +731,29 @@ inline void *
bdb_extract_bfd (fd_t *fd,
xlator_t *this)
{
- uint64_t tmp_bfd = 0;
- void *bfd = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb-ll", fd, out);
- GF_VALIDATE_OR_GOTO ("bdb-ll", this, out);
+ uint64_t tmp_bfd = 0;
+ void *bfd = NULL;
- fd_ctx_get (fd, this, &tmp_bfd);
- bfd = (void *)(long)bfd;
+ GF_VALIDATE_OR_GOTO ("bdb-ll", fd, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", this, out);
+
+ fd_ctx_get (fd, this, &tmp_bfd);
+ bfd = (void *)(long)bfd;
out:
- return bfd;
+ return bfd;
}
/* bdb_dbenv_init - initialize DB_ENV
*
* initialization includes:
- * 1. opening DB_ENV (db_env_create(), DB_ENV->open()).
+ * 1. opening DB_ENV (db_env_create(), DB_ENV->open()).
* NOTE: see private->envflags for flags used.
- * 2. DB_ENV->set_lg_dir - set log directory to be used for storing log files
+ * 2. DB_ENV->set_lg_dir - set log directory to be used for storing log files
* (log files are the files in which transaction logs are written by db).
* 3. DB_ENV->set_flags (DB_LOG_AUTOREMOVE) - set DB_ENV to automatically clear
* the unwanted log files (flushed at each checkpoint).
- * 4. DB_ENV->set_errfile - set errfile to be used by db to report detailed error logs.
+ * 4. DB_ENV->set_errfile - set errfile to be used by db to report detailed error logs.
* used only for debbuging purpose.
*
* return: returns a valid DB_ENV * on success or NULL on error.
@@ -767,168 +761,160 @@ out:
*/
static DB_ENV *
bdb_dbenv_init (xlator_t *this,
- char *directory)
+ char *directory)
{
- /* Create a DB environment */
- DB_ENV *dbenv = NULL;
- int32_t ret = 0;
- bdb_private_t *private = NULL;
- int32_t fatal_flags = 0;
-
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (directory, out);
-
- private = this->private;
- VALIDATE_OR_GOTO (private, out);
-
- ret = db_env_create (&dbenv, 0);
- VALIDATE_OR_GOTO ((ret == 0), out);
-
- /* NOTE: set_errpfx returns 'void' */
- dbenv->set_errpfx(dbenv, this->name);
-
- ret = dbenv->set_lk_detect (dbenv, DB_LOCK_DEFAULT);
- VALIDATE_OR_GOTO ((ret == 0), out);
-
- ret = dbenv->open(dbenv, directory,
- private->envflags,
- S_IRUSR | S_IWUSR);
- if ((ret != 0) && (ret != DB_RUNRECOVERY)) {
- gf_log (this->name,
- GF_LOG_CRITICAL,
- "failed to open DB environment (%s)",
- db_strerror (ret));
- dbenv = NULL;
- goto out;
- } else if (ret == DB_RUNRECOVERY) {
- fatal_flags = ((private->envflags & (~DB_RECOVER)) | DB_RECOVER_FATAL);
- ret = dbenv->open(dbenv, directory,
- fatal_flags,
- S_IRUSR | S_IWUSR);
- if (ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to open DB environment (%s) with DB_REOVER_FATAL",
- db_strerror (ret));
- dbenv = NULL;
- goto out;
- } else {
- gf_log (this->name,
- GF_LOG_WARNING,
- "opened DB environment after DB_RECOVER_FATAL: %s",
- db_strerror (ret));
- }
- } else {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "DB environment successfull opened: %s",
- db_strerror (ret));
- }
-
-
-
-#if (DB_VERSION_MAJOR == 4 && \
+ /* Create a DB environment */
+ DB_ENV *dbenv = NULL;
+ int32_t ret = 0;
+ bdb_private_t *private = NULL;
+ int32_t fatal_flags = 0;
+
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (directory, out);
+
+ private = this->private;
+ VALIDATE_OR_GOTO (private, out);
+
+ ret = db_env_create (&dbenv, 0);
+ VALIDATE_OR_GOTO ((ret == 0), out);
+
+ /* NOTE: set_errpfx returns 'void' */
+ dbenv->set_errpfx(dbenv, this->name);
+
+ ret = dbenv->set_lk_detect (dbenv, DB_LOCK_DEFAULT);
+ VALIDATE_OR_GOTO ((ret == 0), out);
+
+ ret = dbenv->open(dbenv, directory,
+ private->envflags,
+ S_IRUSR | S_IWUSR);
+ if ((ret != 0) && (ret != DB_RUNRECOVERY)) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "failed to open DB environment (%s)",
+ db_strerror (ret));
+ dbenv = NULL;
+ goto out;
+ } else if (ret == DB_RUNRECOVERY) {
+ fatal_flags = ((private->envflags & (~DB_RECOVER))
+ | DB_RECOVER_FATAL);
+ ret = dbenv->open(dbenv, directory, fatal_flags,
+ S_IRUSR | S_IWUSR);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to open DB environment (%s) with "
+ "DB_REOVER_FATAL",
+ db_strerror (ret));
+ dbenv = NULL;
+ goto out;
+ } else {
+ gf_log (this->name, GF_LOG_WARNING,
+ "opened DB environment after DB_RECOVER_FATAL:"
+ " %s", db_strerror (ret));
+ }
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "DB environment successfull opened: %s",
+ db_strerror (ret));
+ }
+
+
+
+#if (DB_VERSION_MAJOR == 4 && \
DB_VERSION_MINOR == 7)
- if (private->log_auto_remove) {
- ret = dbenv->log_set_config (dbenv, DB_LOG_AUTO_REMOVE, 1);
- } else {
- ret = dbenv->log_set_config (dbenv, DB_LOG_AUTO_REMOVE, 0);
- }
+ if (private->log_auto_remove) {
+ ret = dbenv->log_set_config (dbenv, DB_LOG_AUTO_REMOVE, 1);
+ } else {
+ ret = dbenv->log_set_config (dbenv, DB_LOG_AUTO_REMOVE, 0);
+ }
#else
- if (private->log_auto_remove) {
- ret = dbenv->set_flags (dbenv, DB_LOG_AUTOREMOVE, 1);
- } else {
- ret = dbenv->set_flags (dbenv, DB_LOG_AUTOREMOVE, 0);
- }
+ if (private->log_auto_remove) {
+ ret = dbenv->set_flags (dbenv, DB_LOG_AUTOREMOVE, 1);
+ } else {
+ ret = dbenv->set_flags (dbenv, DB_LOG_AUTOREMOVE, 0);
+ }
#endif
- if (ret != 0) {
- gf_log ("bctx",
- GF_LOG_ERROR,
- "failed to set DB_LOG_AUTOREMOVE on dbenv: %s", db_strerror (ret));
- } else {
- gf_log ("bctx",
- GF_LOG_DEBUG,
- "DB_LOG_AUTOREMOVE set on dbenv");
- }
-
- if (private->transaction) {
- ret = dbenv->set_flags(dbenv, DB_AUTO_COMMIT, 1);
-
- if (ret != 0) {
- gf_log ("bctx",
- GF_LOG_ERROR,
- "failed to set DB_AUTO_COMMIT on dbenv: %s",
- db_strerror (ret));
- } else {
- gf_log ("bctx",
- GF_LOG_DEBUG,
- "DB_AUTO_COMMIT set on dbenv");
- }
-
- if (private->txn_timeout) {
- ret = dbenv->set_timeout (dbenv,
- private->txn_timeout,
- DB_SET_TXN_TIMEOUT);
- if (ret != 0) {
- gf_log ("bctx",
- GF_LOG_ERROR,
- "failed to set TXN_TIMEOUT to %d milliseconds "
- "on dbenv: %s",
- private->txn_timeout, db_strerror (ret));
- } else {
- gf_log ("bctx",
- GF_LOG_DEBUG,
- "TXN_TIMEOUT set to %d milliseconds",
- private->txn_timeout);
- }
- }
-
- if (private->lock_timeout) {
- ret = dbenv->set_timeout(dbenv,
- private->txn_timeout,
- DB_SET_LOCK_TIMEOUT);
-
- if (ret != 0) {
- gf_log ("bctx",
- GF_LOG_ERROR,
- "failed to set LOCK_TIMEOUT to %d milliseconds "
- "on dbenv: %s",
- private->lock_timeout, db_strerror (ret));
- } else {
- gf_log ("bctx",
- GF_LOG_DEBUG,
- "LOCK_TIMEOUT set to %d milliseconds",
- private->lock_timeout);
- }
- }
-
- ret = dbenv->set_lg_dir (dbenv, private->logdir);
-
- if (ret != 0) {
- gf_log ("bctx",
- GF_LOG_ERROR,
- "failed to set log directory for dbenv: %s", db_strerror (ret));
- } else {
- gf_log ("bctx",
- GF_LOG_DEBUG,
- "set dbenv log dir to %s", private->logdir);
- }
-
- }
-
- if (private->errfile) {
- private->errfp = fopen (private->errfile, "a+");
- if (private->errfp) {
- dbenv->set_errfile (dbenv, private->errfp);
- } else {
- gf_log ("bctx",
- GF_LOG_ERROR,
- "failed to open errfile: %s", strerror (errno));
- }
- }
+ if (ret != 0) {
+ gf_log ("bctx", GF_LOG_ERROR,
+ "failed to set DB_LOG_AUTOREMOVE on dbenv: %s",
+ db_strerror (ret));
+ } else {
+ gf_log ("bctx", GF_LOG_DEBUG,
+ "DB_LOG_AUTOREMOVE set on dbenv");
+ }
+
+ if (private->transaction) {
+ ret = dbenv->set_flags(dbenv, DB_AUTO_COMMIT, 1);
+
+ if (ret != 0) {
+ gf_log ("bctx", GF_LOG_ERROR,
+ "failed to set DB_AUTO_COMMIT on dbenv: %s",
+ db_strerror (ret));
+ } else {
+ gf_log ("bctx", GF_LOG_DEBUG,
+ "DB_AUTO_COMMIT set on dbenv");
+ }
+
+ if (private->txn_timeout) {
+ ret = dbenv->set_timeout (dbenv,
+ private->txn_timeout,
+ DB_SET_TXN_TIMEOUT);
+ if (ret != 0) {
+ gf_log ("bctx", GF_LOG_ERROR,
+ "failed to set TXN_TIMEOUT to %d "
+ "milliseconds on dbenv: %s",
+ private->txn_timeout,
+ db_strerror (ret));
+ } else {
+ gf_log ("bctx", GF_LOG_DEBUG,
+ "TXN_TIMEOUT set to %d milliseconds",
+ private->txn_timeout);
+ }
+ }
+
+ if (private->lock_timeout) {
+ ret = dbenv->set_timeout(dbenv,
+ private->txn_timeout,
+ DB_SET_LOCK_TIMEOUT);
+
+ if (ret != 0) {
+ gf_log ("bctx", GF_LOG_ERROR,
+ "failed to set LOCK_TIMEOUT to %d "
+ "milliseconds on dbenv: %s",
+ private->lock_timeout,
+ db_strerror (ret));
+ } else {
+ gf_log ("bctx", GF_LOG_DEBUG,
+ "LOCK_TIMEOUT set to %d milliseconds",
+ private->lock_timeout);
+ }
+ }
+
+ ret = dbenv->set_lg_dir (dbenv, private->logdir);
+
+ if (ret != 0) {
+ gf_log ("bctx", GF_LOG_ERROR,
+ "failed to set log directory for dbenv: %s",
+ db_strerror (ret));
+ } else {
+ gf_log ("bctx", GF_LOG_DEBUG,
+ "set dbenv log dir to %s",
+ private->logdir);
+ }
+
+ }
+
+ if (private->errfile) {
+ private->errfp = fopen (private->errfile, "a+");
+ if (private->errfp) {
+ dbenv->set_errfile (dbenv, private->errfp);
+ } else {
+ gf_log ("bctx", GF_LOG_ERROR,
+ "failed to open errfile: %s",
+ strerror (errno));
+ }
+ }
out:
- return dbenv;
+ return dbenv;
}
#define BDB_ENV(this) ((((struct bdb_private *)this->private)->b_table)->dbenv)
@@ -937,21 +923,21 @@ out:
* files, instead db writes a 'log' (similar to a journal entry) into a
* log file. db normally clears the log files during opening of an
* environment. since we expect a filesystem server to run for a pretty
- * long duration and flushing 'log's during dbenv->open would prove very
- * costly, if we accumulate the log entries for one complete run of
+ * long duration and flushing 'log's during dbenv->open would prove very
+ * costly, if we accumulate the log entries for one complete run of
* glusterfs server. to flush the logs frequently, db provides a mechanism
* called 'checkpointing'. when we do a checkpoint, db flushes the logs to
- * disk (writes changes to db files) and we can also clear the accumulated
+ * disk (writes changes to db files) and we can also clear the accumulated
* log files after checkpointing. NOTE: removing unwanted log files is not
- * part of dbenv->txn_checkpoint() call.
+ * part of dbenv->txn_checkpoint() call.
*
* @data: xlator_t of the current instance of bdb xlator.
*
- * bdb_checkpoint is called in a different thread from the main glusterfs thread. bdb
- * xlator creates the checkpoint thread after successfully opening the db environment.
+ * bdb_checkpoint is called in a different thread from the main glusterfs thread. bdb
+ * xlator creates the checkpoint thread after successfully opening the db environment.
* NOTE: bdb_checkpoint thread shares the DB_ENV handle with the filesystem thread.
*
- * db environment checkpointing frequency is controlled by
+ * db environment checkpointing frequency is controlled by
* 'option checkpoint-timeout <time-in-seconds>' in volfile.
*
* NOTE: checkpointing thread is started only if 'option transaction on' specified in
@@ -961,495 +947,492 @@ out:
static void *
bdb_checkpoint (void *data)
{
- xlator_t *this = NULL;
- struct bdb_private *private = NULL;
- DB_ENV *dbenv = NULL;
- int32_t ret = 0;
- uint32_t active = 0;
-
- this = (xlator_t *) data;
- dbenv = BDB_ENV(this);
- private = this->private;
-
- for (;;sleep (private->checkpoint_timeout)) {
- LOCK (&private->active_lock);
- active = private->active;
- UNLOCK (&private->active_lock);
-
- if (active) {
- ret = dbenv->txn_checkpoint (dbenv, 1024, 0, 0);
- if (ret) {
- gf_log ("bctx",
- GF_LOG_ERROR,
- "failed to checkpoint environment: %s", db_strerror (ret));
- } else {
- gf_log ("bctx",
- GF_LOG_DEBUG,
- "checkpointing successful");
- }
- } else {
- ret = dbenv->txn_checkpoint (dbenv, 1024, 0, 0);
- if (ret) {
- gf_log ("bctx",
- GF_LOG_ERROR,
- "failed to do final checkpoint environment: %s",
- db_strerror (ret));
- } else {
- gf_log ("bctx",
- GF_LOG_DEBUG,
- "final checkpointing successful");
- }
- break;
- }
- }
-
- return NULL;
+ xlator_t *this = NULL;
+ struct bdb_private *private = NULL;
+ DB_ENV *dbenv = NULL;
+ int32_t ret = 0;
+ uint32_t active = 0;
+
+ this = (xlator_t *) data;
+ dbenv = BDB_ENV(this);
+ private = this->private;
+
+ for (;;sleep (private->checkpoint_interval)) {
+ LOCK (&private->active_lock);
+ active = private->active;
+ UNLOCK (&private->active_lock);
+
+ if (active) {
+ ret = dbenv->txn_checkpoint (dbenv, 1024, 0, 0);
+ if (ret) {
+ gf_log ("bctx", GF_LOG_ERROR,
+ "failed to checkpoint environment: %s",
+ db_strerror (ret));
+ } else {
+ gf_log ("bctx", GF_LOG_DEBUG,
+ "checkpointing successful");
+ }
+ } else {
+ ret = dbenv->txn_checkpoint (dbenv, 1024, 0, 0);
+ if (ret) {
+ gf_log ("bctx", GF_LOG_ERROR,
+ "failed to do final checkpoint "
+ "environment: %s",
+ db_strerror (ret));
+ } else {
+ gf_log ("bctx", GF_LOG_DEBUG,
+ "final checkpointing successful");
+ }
+ break;
+ }
+ }
+
+ return NULL;
}
static inline void
-BDB_CACHE_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_cache_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- /* cache is always on */
- private->cache = ON;
+ /* cache is always on */
+ private->cache = ON;
}
static inline void
-BDB_LOG_REMOVE_INIT(xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_log_remove_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- private->log_auto_remove = 1;
- gf_log (this->name,
- GF_LOG_DEBUG,
- "DB_ENV will use DB_LOG_AUTO_REMOVE");
+ private->log_auto_remove = 1;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "DB_ENV will use DB_LOG_AUTO_REMOVE");
}
static inline void
-BDB_ERRFILE_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_errfile_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- data_t *errfile = NULL;
-
- errfile = dict_get (options, "errfile");
- if (errfile) {
- private->errfile = strdup (errfile->data);
- gf_log (this->name,
- GF_LOG_DEBUG,
- "using errfile: %s", private->errfile);
- }
+ int ret = -1;
+ char *errfile = NULL;
+
+ ret = dict_get_str (options, "errfile", &errfile);
+ if (ret == 0) {
+ private->errfile = strdup (errfile);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "using errfile: %s", private->errfile);
+ }
}
static inline void
-BDB_TABLE_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_table_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- bctx_table_t *table = NULL;
- int32_t idx = 0;
-
- data_t *lru_limit = NULL;
- data_t *page_size = NULL;
-
- table = CALLOC (1, sizeof (*table));
- if (table) {
- INIT_LIST_HEAD(&(table->b_lru));
- INIT_LIST_HEAD(&(table->active));
- INIT_LIST_HEAD(&(table->purge));
-
- LOCK_INIT (&table->lock);
- LOCK_INIT (&table->checkpoint_lock);
-
- table->transaction = private->transaction;
- table->access_mode = private->access_mode;
- table->dbflags = private->dbflags;
- table->this = this;
-
- {
- lru_limit = dict_get (options, "lru-limit");
-
- /* TODO: set max lockers and max txns to accomodate
- * for more than lru_limit */
- if (lru_limit) {
- table->lru_limit = strtol (lru_limit->data, NULL, 0);
- gf_log ("bdb-ll",
- GF_LOG_DEBUG,
- "setting bctx lru limit to %d", table->lru_limit);
- } else {
- table->lru_limit = BDB_DEFAULT_LRU_LIMIT;
- }
- }
-
- {
- page_size = dict_get (options, "page-size");
-
- if (page_size)
- {
- if (gf_string2bytesize (page_size->data,
- &table->page_size) != 0) {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "invalid number format \"%s\""
- " of \"option page-size\"",
- page_size->data);
- }
-
- if (!(table->page_size >= BDB_LL_PAGE_SIZE_MIN &&
- table->page_size <= BDB_LL_PAGE_SIZE_MAX)) {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "pagesize %s is out of range."
- "Allowed pagesize is between %d and %d",
- page_size->data,
- BDB_LL_PAGE_SIZE_MIN,
- BDB_LL_PAGE_SIZE_MAX);
- }
- }
- else {
- table->page_size = BDB_LL_PAGE_SIZE_DEFAULT;
- }
- gf_log ("bdb-ll",
- GF_LOG_DEBUG, "using page-size %"PRIu64,
- table->page_size);
- }
-
- table->hash_size = BDB_DEFAULT_HASH_SIZE;
- table->b_hash = CALLOC (BDB_DEFAULT_HASH_SIZE, sizeof (struct list_head));
-
- for (idx = 0; idx < table->hash_size; idx++)
- INIT_LIST_HEAD(&(table->b_hash[idx]));
-
- private->b_table = table;
- } else {
- gf_log ("bdb-ll",
- GF_LOG_CRITICAL,
- "failed to allocate bctx table: out of memory");
- }
+ bctx_table_t *table = NULL;
+ int32_t idx = 0;
+
+ int ret = -1;
+ char *lru_limit_str = NULL;
+ char *page_size_str = NULL;
+
+ table = CALLOC (1, sizeof (*table));
+ if (table) {
+ INIT_LIST_HEAD(&(table->b_lru));
+ INIT_LIST_HEAD(&(table->active));
+ INIT_LIST_HEAD(&(table->purge));
+
+ LOCK_INIT (&table->lock);
+ LOCK_INIT (&table->checkpoint_lock);
+
+ table->transaction = private->transaction;
+ table->access_mode = private->access_mode;
+ table->dbflags = private->dbflags;
+ table->this = this;
+
+ {
+ ret = dict_get_str (options, "lru-limit",
+ &lru_limit_str);
+
+ /* TODO: set max lockers and max txns to accomodate
+ * for more than lru_limit */
+ if (ret == 0) {
+ ret = gf_string2uint32 (lru_limit_str,
+ &table->lru_limit);
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "setting bctx lru limit to %d",
+ table->lru_limit);
+ } else {
+ table->lru_limit = BDB_DEFAULT_LRU_LIMIT;
+ }
+ }
+
+ {
+ ret = dict_get_str (options, "page-size",
+ &page_size_str);
+
+ if (ret == 0) {
+ ret = gf_string2bytesize (page_size_str,
+ &table->page_size);
+ if (ret != 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "invalid number format \"%s\""
+ " of \"option page-size\"",
+ page_size_str);
+ }
+
+ if (!PAGE_SIZE_IN_RANGE(table->page_size)) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "pagesize %s is out of range."
+ "Allowed pagesize is between "
+ "%d and %d",
+ page_size_str,
+ BDB_LL_PAGE_SIZE_MIN,
+ BDB_LL_PAGE_SIZE_MAX);
+ }
+ }
+ else {
+ table->page_size = BDB_LL_PAGE_SIZE_DEFAULT;
+ }
+ gf_log ("bdb-ll",
+ GF_LOG_DEBUG, "using page-size %"PRIu64,
+ table->page_size);
+ }
+
+ table->hash_size = BDB_DEFAULT_HASH_SIZE;
+ table->b_hash = CALLOC (BDB_DEFAULT_HASH_SIZE,
+ sizeof (struct list_head));
+
+ for (idx = 0; idx < table->hash_size; idx++)
+ INIT_LIST_HEAD(&(table->b_hash[idx]));
+
+ private->b_table = table;
+ } else {
+ gf_log ("bdb-ll", GF_LOG_CRITICAL,
+ "failed to allocate bctx table: out of memory");
+ }
}
-static inline void
-BDB_DIRECTORY_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+static inline void
+bdb_directory_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- data_t *directory = NULL;
- data_t *logdir = NULL;
- int32_t op_ret = -1;
- struct stat stbuf = {0};
-
- directory = dict_get (options, "directory");
-
- if (directory) {
- logdir = dict_get (options, "logdir");
-
- if (logdir == NULL) {
- gf_log ("bdb-ll",
- GF_LOG_DEBUG,
- "using default logdir as database home");
- private->logdir = strdup (directory->data);
-
- } else {
- private->logdir = strdup (logdir->data);
- gf_log ("bdb-ll",
- GF_LOG_DEBUG,
- "using logdir: %s", private->logdir);
- umask (000);
- if (mkdir (private->logdir, 0777) == 0) {
- gf_log ("bdb-ll", GF_LOG_WARNING,
- "logdir specified (%s) not exists, created",
- private->logdir);
- }
-
- op_ret = stat (private->logdir, &stbuf);
- if ((op_ret != 0) || !S_ISDIR (stbuf.st_mode)) {
- gf_log ("bdb-ll",
- GF_LOG_ERROR,
- "specified logdir doesn't exist, "
- "using default (environment home directory: %s)",
- directory->data);
- private->logdir = strdup (directory->data);
- }
- }
-
- private->b_table->dbenv = bdb_dbenv_init (this, directory->data);
-
- if (!private->b_table->dbenv) {
- gf_log ("bdb-ll", GF_LOG_ERROR,
- "failed to initialize db environment");
- FREE (private);
- op_ret = -1;
- } else {
- if (private->transaction) {
- /* all well, start the checkpointing thread */
- LOCK_INIT (&private->active_lock);
-
- LOCK (&private->active_lock);
- private->active = 1;
- UNLOCK (&private->active_lock);
- pthread_create (&private->checkpoint_thread, NULL,
- bdb_checkpoint, this);
- }
- }
- }
+ int ret = -1;
+ char *directory = NULL;
+ char *logdir = NULL;
+ int32_t op_ret = -1;
+ struct stat stbuf = {0};
+
+ ret = dict_get_str (options, "directory", &directory);
+
+ if (ret == 0) {
+ ret = dict_get_str (options, "logdir", &logdir);
+
+ if (ret != 0) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "using default logdir as database home");
+ private->logdir = strdup (directory);
+
+ } else {
+ private->logdir = strdup (logdir);
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "using logdir: %s",
+ private->logdir);
+ umask (000);
+ if (mkdir (private->logdir, 0777) == 0) {
+ gf_log ("bdb-ll", GF_LOG_WARNING,
+ "logdir specified (%s) not exists, "
+ "created",
+ private->logdir);
+ }
+
+ op_ret = stat (private->logdir, &stbuf);
+ if ((op_ret != 0)
+ || (!S_ISDIR (stbuf.st_mode))) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "specified logdir doesn't exist, "
+ "using default "
+ "(environment home directory: %s)",
+ directory);
+ private->logdir = strdup (directory);
+ }
+ }
+
+ private->b_table->dbenv = bdb_dbenv_init (this, directory);
+
+ if (!private->b_table->dbenv) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to initialize db environment");
+ FREE (private);
+ op_ret = -1;
+ } else {
+ if (private->transaction) {
+ /* all well, start the checkpointing thread */
+ LOCK_INIT (&private->active_lock);
+
+ LOCK (&private->active_lock);
+ {
+ private->active = 1;
+ }
+ UNLOCK (&private->active_lock);
+ pthread_create (&private->checkpoint_thread,
+ NULL, bdb_checkpoint, this);
+ }
+ }
+ }
}
static inline void
-BDB_DIR_MODE_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_dir_mode_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- data_t *dir_mode = NULL;
- char *endptr = NULL;
-
- dir_mode = dict_get (options, "dir-mode");
-
- if (dir_mode) {
- private->dir_mode = strtol (dir_mode->data, &endptr, 8);
- if ((*endptr) ||
- (!IS_VALID_FILE_MODE(private->dir_mode))) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "invalid dir-mode %o. setting to default %o",
- private->dir_mode,
- DEFAULT_DIR_MODE);
- private->dir_mode = DEFAULT_DIR_MODE;
- } else {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "setting dir-mode to %o", private->dir_mode);
- private->dir_mode = private->dir_mode;
- }
- } else {
- private->dir_mode = DEFAULT_DIR_MODE;
- }
-
- private->dir_mode = private->dir_mode | S_IFDIR;
+ int ret = -1;
+ char *mode_str = NULL;
+ char *endptr = NULL;
+
+ ret = dict_get_str (options, "dir-mode", &mode_str);
+
+ if (ret == 0) {
+ private->dir_mode = strtol (mode_str, &endptr, 8);
+ if ((*endptr) ||
+ (!IS_VALID_FILE_MODE(private->dir_mode))) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "invalid dir-mode %o. setting to default %o",
+ private->dir_mode,
+ DEFAULT_DIR_MODE);
+ private->dir_mode = DEFAULT_DIR_MODE;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting dir-mode to %o",
+ private->dir_mode);
+ }
+ } else {
+ private->dir_mode = DEFAULT_DIR_MODE;
+ }
+
+ private->dir_mode = private->dir_mode | S_IFDIR;
}
static inline void
-BDB_FILE_MODE_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_file_mode_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- data_t *file_mode = NULL;
- char *endptr = NULL;
-
- file_mode = dict_get (options, "file-mode");
-
- if (file_mode) {
- private->file_mode = strtol (file_mode->data, &endptr, 8);
-
- if ((*endptr) ||
- (!IS_VALID_FILE_MODE(private->file_mode))) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "invalid file-mode %o. setting to default %o",
- private->file_mode,
- DEFAULT_FILE_MODE);
- private->file_mode = DEFAULT_FILE_MODE;
- } else {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "setting file-mode to %o", private->file_mode);
- private->file_mode = private->file_mode;
- }
- } else {
- private->file_mode = DEFAULT_FILE_MODE;
- }
-
- private->symlink_mode = private->file_mode | S_IFLNK;
- private->file_mode = private->file_mode | S_IFREG;
+ int ret = -1;
+ char *mode_str = NULL;
+ char *endptr = NULL;
+
+ ret = dict_get_str (options, "file-mode", &mode_str);
+
+ if (ret == 0) {
+ private->file_mode = strtol (mode_str, &endptr, 8);
+
+ if ((*endptr) ||
+ (!IS_VALID_FILE_MODE(private->file_mode))) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "invalid file-mode %o. setting to default %o",
+ private->file_mode, DEFAULT_FILE_MODE);
+ private->file_mode = DEFAULT_FILE_MODE;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting file-mode to %o",
+ private->file_mode);
+ private->file_mode = private->file_mode;
+ }
+ } else {
+ private->file_mode = DEFAULT_FILE_MODE;
+ }
+
+ private->symlink_mode = private->file_mode | S_IFLNK;
+ private->file_mode = private->file_mode | S_IFREG;
}
static inline void
-BDB_CHECKPOINT_TIMEOUT_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_checkpoint_interval_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- data_t *checkpoint_timeout = NULL;
-
- checkpoint_timeout = dict_get (options, "checkpoint-timeout");
-
- private->checkpoint_timeout = BDB_DEFAULT_CHECKPOINT_TIMEOUT;
-
- if (checkpoint_timeout) {
- private->checkpoint_timeout = strtol (checkpoint_timeout->data, NULL, 0);
-
- if (private->checkpoint_timeout < 5 || private->checkpoint_timeout > 60) {
- gf_log (this->name,
- GF_LOG_WARNING,
- "checkpoint-timeout %d seconds too %s",
- private->checkpoint_timeout,
- (private->checkpoint_timeout < 5)?"low":"high");
- } else {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "setting checkpoint-timeout to %d seconds",
- private->checkpoint_timeout);
- }
- } else {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "setting checkpoint-timeout to default: %d seconds",
- private->checkpoint_timeout);
- }
+ int ret = -1;
+ char *checkpoint_interval_str = NULL;
+
+ private->checkpoint_interval = BDB_DEFAULT_CHECKPOINT_INTERVAL;
+
+ ret = dict_get_str (options, "checkpoint-interval",
+ &checkpoint_interval_str);
+
+ if (ret == 0) {
+ ret = gf_string2time (checkpoint_interval_str,
+ &private->checkpoint_interval);
+
+ if (ret == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting checkpoint-interval to %"PRIu32" seconds",
+ private->checkpoint_interval);
+ }
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting checkpoint-interval to default: %"PRIu32" seconds",
+ private->checkpoint_interval);
+ }
}
static inline void
-BDB_LOCK_TIMEOUT_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_lock_timeout_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- data_t *lock_timeout = NULL;
-
- lock_timeout = dict_get (options, "lock-timeout");
-
- if (lock_timeout) {
- private->lock_timeout = strtol (lock_timeout->data, NULL, 0);
-
- if (private->lock_timeout > 4260000) {
- /* db allows us to DB_SET_LOCK_TIMEOUT to be set to a
- * maximum of 71 mins (4260000 milliseconds) */
- gf_log (this->name,
- GF_LOG_DEBUG,
- "lock-timeout %d, out of range",
- private->lock_timeout);
- private->lock_timeout = 0;
- } else {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "setting lock-timeout to %d milliseconds",
- private->lock_timeout);
- }
- }
+ int ret = -1;
+ char *timeout_str = NULL;
+
+ ret = dict_get_str (options, "lock-timeout", &timeout_str);
+
+ if (ret == 0) {
+ ret = gf_string2time (timeout_str, &private->lock_timeout);
+
+ if (private->lock_timeout > 4260000) {
+ /* db allows us to DB_SET_LOCK_TIMEOUT to be set to a
+ * maximum of 71 mins (4260000 milliseconds) */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "lock-timeout %d, out of range",
+ private->lock_timeout);
+ private->lock_timeout = 0;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting lock-timeout to %d milliseconds",
+ private->lock_timeout);
+ }
+ }
}
static inline void
-BDB_TRANSACTION_TIMEOUT_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_transaction_timeout_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- data_t *txn_timeout = NULL;
- txn_timeout = dict_get (options, "transaction-timeout");
-
- if (txn_timeout) {
- private->txn_timeout = strtol (txn_timeout->data, NULL, 0);
-
- if (private->txn_timeout > 4260000) {
- /* db allows us to DB_SET_TXN_TIMEOUT to be set to a maximum
- * of 71 mins (4260000 milliseconds) */
- gf_log (this->name,
- GF_LOG_DEBUG,
- "transaction-timeout %d, out of range",
- private->txn_timeout);
- private->txn_timeout = 0;
- } else {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "setting transaction-timeout to %d milliseconds",
- private->txn_timeout);
- }
- }
+ int ret = -1;
+ char *timeout_str = NULL;
+
+ ret = dict_get_str (options, "transaction-timeout", &timeout_str);
+
+ if (ret == 0) {
+ ret = gf_string2time (timeout_str, &private->txn_timeout);
+
+ if (private->txn_timeout > 4260000) {
+ /* db allows us to DB_SET_TXN_TIMEOUT to be set to
+ * a maximum of 71 mins (4260000 milliseconds) */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "transaction-timeout %d, out of range",
+ private->txn_timeout);
+ private->txn_timeout = 0;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting transaction-timeout to %d "
+ "milliseconds",
+ private->txn_timeout);
+ }
+ }
}
static inline void
-BDB_TRANSACTION_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_transaction_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- data_t *mode = NULL;
-
- mode = dict_get (options, "mode");
-
- if (mode && !strcmp (mode->data, "off")) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "cache mode selected");
- private->envflags = DB_CREATE | DB_INIT_LOG |
- DB_INIT_MPOOL | DB_THREAD;
- private->dbflags = DB_CREATE | DB_THREAD;
- private->transaction = OFF;
- } else {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "persistant mode selected");
- private->transaction = ON;
- private->envflags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
- DB_INIT_MPOOL | DB_INIT_TXN | DB_RECOVER | DB_THREAD;
- private->dbflags = DB_CREATE | DB_THREAD;
- }
+ int ret = -1;
+ char *mode = NULL;
+
+ ret = dict_get_str (options, "mode", &mode);
+
+ if ((ret == 0)
+ && (!strcmp (mode, "cache"))) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "cache mode selected");
+ private->envflags = DB_CREATE | DB_INIT_LOG |
+ DB_INIT_MPOOL | DB_THREAD;
+ private->dbflags = DB_CREATE | DB_THREAD;
+ private->transaction = OFF;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "persistant mode selected");
+ private->transaction = ON;
+ private->envflags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
+ DB_INIT_MPOOL | DB_INIT_TXN | DB_RECOVER | DB_THREAD;
+ private->dbflags = DB_CREATE | DB_THREAD;
+
+ bdb_lock_timeout_init (this, options, private);
+
+ bdb_transaction_timeout_init (this, options, private);
+
+ bdb_log_remove_init (this, options, private);
+
+ bdb_checkpoint_interval_init (this, options, private);
+ }
}
static inline void
-BDB_ACCESS_MODE_INIT (xlator_t *this,
- dict_t *options,
- struct bdb_private *private)
+bdb_access_mode_init (xlator_t *this,
+ dict_t *options,
+ struct bdb_private *private)
{
- data_t *access_mode = NULL;
-
- access_mode = dict_get (options, "access-mode");
-
- if (access_mode && !strcmp (access_mode->data, "btree")) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "using access mode BTREE");
- private->access_mode = DB_BTREE;
- } else {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "using access mode HASH");
- private->access_mode = DB_HASH;
- }
+ int ret = -1;
+ char *access_mode = NULL;
+
+ ret = dict_get_str (options, "access-mode", &access_mode);
+
+ if ((ret == 0)
+ && (!strcmp (access_mode, "btree"))) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "using access mode BTREE");
+ private->access_mode = DB_BTREE;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "using access mode HASH");
+ private->access_mode = DB_HASH;
+ }
}
/* bdb_db_init - initialize bdb xlator
- *
- * reads the options from @options dictionary and sets appropriate values in @this->private.
- * also initializes DB_ENV.
*
- * return: 0 on success or -1 on error (with logging the error through gf_log()).
+ * reads the options from @options dictionary and sets appropriate values in
+ * @this->private. also initializes DB_ENV.
+ *
+ * return: 0 on success or -1 on error
+ * (with logging the error through gf_log()).
*/
int
bdb_db_init (xlator_t *this,
dict_t *options)
{
- /* create a db entry for root */
- int32_t op_ret = 0;
- bdb_private_t *private = NULL;
-
- private = this->private;
+ /* create a db entry for root */
+ int32_t op_ret = 0;
+ bdb_private_t *private = NULL;
- BDB_CACHE_INIT (this, options, private);
-
- BDB_ACCESS_MODE_INIT (this, options, private);
+ private = this->private;
- BDB_TRANSACTION_INIT (this, options, private);
+ bdb_cache_init (this, options, private);
- BDB_TRANSACTION_TIMEOUT_INIT (this, options, private);
+ bdb_access_mode_init (this, options, private);
- BDB_LOCK_TIMEOUT_INIT (this, options, private);
+ bdb_transaction_init (this, options, private);
- {
- LOCK_INIT (&private->ino_lock);
- private->next_ino = 2;
- }
-
- BDB_CHECKPOINT_TIMEOUT_INIT (this, options, private);
-
- BDB_FILE_MODE_INIT (this, options, private);
+ {
+ LOCK_INIT (&private->ino_lock);
+ private->next_ino = 2;
+ }
- BDB_DIR_MODE_INIT (this, options, private);
+ bdb_file_mode_init (this, options, private);
- BDB_TABLE_INIT (this, options, private);
+ bdb_dir_mode_init (this, options, private);
- BDB_ERRFILE_INIT (this, options, private);
+ bdb_table_init (this, options, private);
- BDB_LOG_REMOVE_INIT (this, options, private);
+ bdb_errfile_init (this, options, private);
- BDB_DIRECTORY_INIT (this, options, private);
+ bdb_directory_init (this, options, private);
- return op_ret;
+ return op_ret;
}
diff --git a/xlators/storage/bdb/src/bdb.c b/xlators/storage/bdb/src/bdb.c
index 6044ef47371..6355855ce3c 100644
--- a/xlators/storage/bdb/src/bdb.c
+++ b/xlators/storage/bdb/src/bdb.c
@@ -1,37 +1,39 @@
/*
- Copyright (c) 2008-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
- This file is part of GlusterFS.
-
- GlusterFS 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; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS 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. If not, see
- <http://www.gnu.org/licenses/>.
+ Copyright (c) 2008-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
+ This file is part of GlusterFS.
+
+ GlusterFS 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; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS 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. If not, see
+ <http://www.gnu.org/licenses/>.
*/
/* bdb based storage translator - named as 'bdb' translator
- *
- *
+ *
+ *
* There can be only two modes for files existing on bdb translator:
- * 1. DIRECTORY - directories are stored by bdb as regular directories on background
- * file-system. directories also have an entry in the ns_db.db of their parent directory.
- * 2. REGULAR FILE - regular files are stored as records in the storage_db.db present in
- * the directory. regular files also have an entry in ns_db.db
+ * 1. DIRECTORY - directories are stored by bdb as regular directories on
+ * back-end file-system. directories also have an entry in the ns_db.db of
+ * their parent directory.
+ * 2. REGULAR FILE - regular files are stored as records in the storage_db.db
+ * present in the directory. regular files also have an entry in ns_db.db
*
- * Internally bdb has a maximum of three different types of logical files associated with
- * each directory:
- * 1. storage_db.db - storage database, used to store the data corresponding to regular
- * files in the form of key/value pair. file-name is the 'key' and data
- * is 'value'.
- * 2. directory (all subdirectories) - any subdirectory will have a regular directory entry.
+ * Internally bdb has a maximum of three different types of logical files
+ * associated with each directory:
+ * 1. storage_db.db - storage database, used to store the data corresponding to
+ * regular files in the form of key/value pair. file-name is the 'key' and
+ * data is 'value'.
+ * 2. directory (all subdirectories) - any subdirectory will have a regular
+ * directory entry.
*/
#ifndef _CONFIG_H
#define _CONFIG_H
@@ -59,494 +61,494 @@
#define B_TABLE(this) (((struct bdb_private *)this->private)->b_table)
-int32_t
+int32_t
bdb_mknod (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
mode_t mode,
dev_t dev)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- char *key_string = NULL; /* after translating loc->path to DB key */
- char *db_path = NULL;
- bctx_t *bctx = NULL;
- struct stat stbuf = {0,};
-
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- if (!S_ISREG(mode)) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "mknod for non-regular file");
- op_ret = -1;
- op_errno = EPERM;
- goto out;
- } /* if(!S_ISREG(mode)) */
-
- bctx = bctx_parent (B_TABLE(this), loc->path);
-
- if (bctx == NULL) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to get bctx for path: %s", loc->path);
- op_ret = -1;
- op_errno = ENOENT;
- goto out;
- } /* if(bctx == NULL) */
-
- MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
-
- op_ret = lstat (db_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- db_path, strerror (op_errno));
- goto out;
- }
-
- MAKE_KEY_FROM_PATH (key_string, loc->path);
- op_ret = bdb_db_put (bctx, NULL, key_string, NULL, 0, 0, 0);
- if (op_ret > 0) {
- /* create successful */
- stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
- stbuf.st_mode = mode;
- stbuf.st_size = 0;
- stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
- } else {
- gf_log (this->name,
- GF_LOG_ERROR,
- "bdb_db_get() failed for path: %s", loc->path);
- op_ret = -1;
- op_errno = ENOENT;
- }/* if (!op_ret)...else */
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *key_string = NULL; /* after translating path to DB key */
+ char *db_path = NULL;
+ bctx_t *bctx = NULL;
+ struct stat stbuf = {0,};
+
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ if (!S_ISREG(mode)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "mknod for non-regular file");
+ op_ret = -1;
+ op_errno = EPERM;
+ goto out;
+ } /* if(!S_ISREG(mode)) */
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get bctx for path: %s",
+ loc->path);
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto out;
+ } /* if(bctx == NULL) */
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+
+ op_ret = lstat (db_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ db_path, strerror (op_errno));
+ goto out;
+ }
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+ op_ret = bdb_db_put (bctx, NULL, key_string, NULL, 0, 0, 0);
+ if (op_ret > 0) {
+ /* create successful */
+ stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
+ stbuf.st_mode = mode;
+ stbuf.st_size = 0;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, \
+ stbuf.st_blksize);
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "bdb_db_get() failed for path: %s",
+ loc->path);
+ op_ret = -1;
+ op_errno = ENOENT;
+ }/* if (!op_ret)...else */
out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
-
- frame->root->rsp_refs = NULL;
-
- STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
- return 0;
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ frame->root->rsp_refs = NULL;
+
+ STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
+ return 0;
}
static inline int32_t
is_dir_empty (xlator_t *this,
loc_t *loc)
{
- int32_t ret = 1;
- bctx_t *bctx = NULL;
- DIR *dir = NULL;
- char *real_path = NULL;
- void *dbstat = NULL;
- struct dirent *entry = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- bctx = bctx_lookup (B_TABLE(this), loc->path);
- if (bctx == NULL) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "failed to get bctx from inode for dir: %s,"
- "assuming empty directory",
- loc->path);
- ret = 1;
- goto out;
- }
-
- dbstat = bdb_db_stat (bctx, NULL, 0);
- if (dbstat) {
- switch (bctx->table->access_mode)
- {
- case DB_HASH:
- ret = (((DB_HASH_STAT *)dbstat)->hash_nkeys == 0);
- break;
- case DB_BTREE:
- case DB_RECNO:
- ret = (((DB_BTREE_STAT *)dbstat)->bt_nkeys == 0);
- break;
- case DB_QUEUE:
- ret = (((DB_QUEUE_STAT *)dbstat)->qs_nkeys == 0);
- break;
- case DB_UNKNOWN:
- gf_log (this->name,
- GF_LOG_CRITICAL,
- "unknown access-mode set for db");
- ret = 0;
- }
- } else {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to get db stat for db at path: %s", loc->path);
- ret = 1;
- goto out;
- }
-
- MAKE_REAL_PATH (real_path, this, loc->path);
- dir = opendir (real_path);
- if (dir == NULL) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "failed to opendir(%s)", loc->path);
- ret = 0;
- goto out;
- }
-
- while ((entry = readdir (dir))) {
- if ((!IS_BDB_PRIVATE_FILE(entry->d_name)) &&
- (!IS_DOT_DOTDOT(entry->d_name))) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "directory (%s) not empty, has a non-db entry",
- loc->path);
- ret = 0;
- break;
- }/* if(!IS_BDB_PRIVATE_FILE()) */
- } /* while(true) */
- closedir (dir);
-out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
-
- return ret;
+ int32_t ret = 1;
+ bctx_t *bctx = NULL;
+ DIR *dir = NULL;
+ char *real_path = NULL;
+ void *dbstat = NULL;
+ struct dirent *entry = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ bctx = bctx_lookup (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get bctx from inode for dir: %s,"
+ "assuming empty directory",
+ loc->path);
+ ret = 1;
+ goto out;
+ }
+
+ dbstat = bdb_db_stat (bctx, NULL, 0);
+ if (dbstat) {
+ switch (bctx->table->access_mode)
+ {
+ case DB_HASH:
+ ret = (((DB_HASH_STAT *)dbstat)->hash_nkeys == 0);
+ break;
+ case DB_BTREE:
+ case DB_RECNO:
+ ret = (((DB_BTREE_STAT *)dbstat)->bt_nkeys == 0);
+ break;
+ case DB_QUEUE:
+ ret = (((DB_QUEUE_STAT *)dbstat)->qs_nkeys == 0);
+ break;
+ case DB_UNKNOWN:
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "unknown access-mode set for db");
+ ret = 0;
+ }
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to get db stat for db at path: %s",
+ loc->path);
+ ret = 1;
+ goto out;
+ }
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ dir = opendir (real_path);
+ if (dir == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to opendir(%s)",
+ loc->path);
+ ret = 0;
+ goto out;
+ }
+
+ while ((entry = readdir (dir))) {
+ if ((!IS_BDB_PRIVATE_FILE(entry->d_name)) &&
+ (!IS_DOT_DOTDOT(entry->d_name))) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "directory (%s) not empty, has a non-db entry",
+ loc->path);
+ ret = 0;
+ break;
+ }/* if(!IS_BDB_PRIVATE_FILE()) */
+ } /* while(true) */
+ closedir (dir);
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ return ret;
}
-int32_t
+int32_t
bdb_rename (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
loc_t *newloc)
{
- struct bdb_private *private = NULL;
- bctx_table_t *table = NULL;
- bctx_t *oldbctx = NULL;
- bctx_t *newbctx = NULL;
- bctx_t *tmpbctx = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = ENOENT;
- int32_t read_size = 0;
- struct stat stbuf = {0,};
- struct stat old_stbuf = {0,};
- DB_TXN *txnid = NULL;
- char *real_newpath = NULL;
- char *real_oldpath = NULL;
- char *oldkey = NULL;
- char *newkey = NULL;
- char *buf = NULL; /* pointer to temporary buffer, where
- * the contents of a file are read, if
- * file being renamed is a regular file */
- char *real_db_newpath = NULL;
- char *tmp_db_newpath = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, newloc, out);
- GF_VALIDATE_OR_GOTO (this->name, oldloc, out);
-
- private = this->private;
- table = private->b_table;
-
- MAKE_REAL_PATH (real_oldpath, this, oldloc->path);
-
- if (S_ISREG (oldloc->inode->st_mode)) {
- oldbctx = bctx_parent (B_TABLE(this), oldloc->path);
- MAKE_REAL_PATH (real_newpath, this, newloc->path);
-
- op_ret = lstat (real_newpath, &stbuf);
-
- if ((op_ret == 0) && (S_ISDIR (stbuf.st_mode))) {
- op_ret = -1;
- op_errno = EISDIR;
- goto out;
- }
- if (op_ret == 0) {
- /* destination is a symlink */
- MAKE_KEY_FROM_PATH (oldkey, oldloc->path);
- MAKE_KEY_FROM_PATH (newkey, newloc->path);
-
- op_ret = unlink (real_newpath);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to unlink %s (%s)",
- newloc->path, strerror (op_errno));
- goto out;
- }
- newbctx = bctx_parent (B_TABLE (this), newloc->path);
- GF_VALIDATE_OR_GOTO (this->name, newbctx, out);
-
- op_ret = bdb_txn_begin (BDB_ENV(this), &txnid);
-
- if ((read_size =
- bdb_db_get (oldbctx, txnid, oldkey, &buf, 0, 0)) < 0) {
- bdb_txn_abort (txnid);
- } else if ((op_ret =
- bdb_db_del (oldbctx, txnid, oldkey)) != 0) {
- bdb_txn_abort (txnid);
- } else if ((op_ret = bdb_db_put (newbctx, txnid,
- newkey, buf,
- read_size, 0, 0)) != 0) {
- bdb_txn_abort (txnid);
- } else {
- bdb_txn_commit (txnid);
- }
-
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (newbctx);
- } else {
- /* destination doesn't exist or a regular file */
- MAKE_KEY_FROM_PATH (oldkey, oldloc->path);
- MAKE_KEY_FROM_PATH (newkey, newloc->path);
-
- newbctx = bctx_parent (B_TABLE (this), newloc->path);
- GF_VALIDATE_OR_GOTO (this->name, newbctx, out);
-
- op_ret = bdb_txn_begin (BDB_ENV(this), &txnid);
-
- if ((read_size = bdb_db_get (oldbctx, txnid,
- oldkey, &buf,
- 0, 0)) < 0) {
- bdb_txn_abort (txnid);
- } else if ((op_ret = bdb_db_del (oldbctx,
- txnid, oldkey)) != 0) {
- bdb_txn_abort (txnid);
- } else if ((op_ret = bdb_db_put (newbctx, txnid,
- newkey, buf,
- read_size, 0, 0)) != 0) {
- bdb_txn_abort (txnid);
- } else {
- bdb_txn_commit (txnid);
- }
-
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (newbctx);
- }
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (oldbctx);
- } else if (S_ISLNK (oldloc->inode->st_mode)) {
- MAKE_REAL_PATH (real_newpath, this, newloc->path);
- op_ret = lstat (real_newpath, &stbuf);
- if ((op_ret == 0) && (S_ISDIR (stbuf.st_mode))) {
- op_ret = -1;
- op_errno = EISDIR;
- goto out;
- }
-
- if (op_ret == 0){
- /* destination exists and is also a symlink */
- MAKE_REAL_PATH (real_oldpath, this, oldloc->path);
- op_ret = rename (real_oldpath, real_newpath);
- op_errno = errno;
-
- if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to rename symlink %s (%s)",
- oldloc->path, strerror (op_errno));
- }
- goto out;
- }
-
- /* destination doesn't exist */
- MAKE_REAL_PATH (real_oldpath, this, oldloc->path);
- MAKE_KEY_FROM_PATH (newkey, newloc->path);
- newbctx = bctx_parent (B_TABLE (this), newloc->path);
- GF_VALIDATE_OR_GOTO (this->name, newbctx, out);
-
- op_ret = bdb_db_del (newbctx, txnid, newkey);
- if (op_ret != 0) {
- /* no problem */
- }
- op_ret = rename (real_oldpath, real_newpath);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to rename %s to %s (%s)",
- oldloc->path, newloc->path, strerror (op_errno));
- goto out;
- }
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (newbctx);
- } else if (S_ISDIR (oldloc->inode->st_mode) &&
- (old_stbuf.st_nlink == 2)) {
-
- tmp_db_newpath = tempnam (private->export_path, "rename_temp");
- GF_VALIDATE_OR_GOTO (this->name, tmp_db_newpath, out);
-
- MAKE_REAL_PATH (real_newpath, this, newloc->path);
-
- MAKE_REAL_PATH_TO_STORAGE_DB (real_db_newpath, this, newloc->path);
-
- oldbctx = bctx_lookup (B_TABLE(this), oldloc->path);
- op_ret = -1;
- op_errno = EINVAL;
- GF_VALIDATE_OR_GOTO (this->name, oldbctx, out);
-
- op_ret = lstat (real_newpath, &stbuf);
- if ((op_ret == 0) &&
- S_ISDIR (stbuf.st_mode) &&
- is_dir_empty (this, newloc)) {
-
- tmpbctx = bctx_rename (oldbctx, tmp_db_newpath);
- op_ret = -1;
- op_errno = ENOENT;
- GF_VALIDATE_OR_GOTO (this->name, tmpbctx, out);
-
- op_ret = rename (real_oldpath, real_newpath);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "rename directory %s to %s failed: %s",
- oldloc->path, newloc->path,
- strerror (errno));
- op_ret = bdb_db_rename (table,
- tmp_db_newpath,
- oldbctx->db_path);
- if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "renaming temp database back to old db failed"
- " for directory %s", oldloc->path);
- goto out;
- } else {
- /* this is a error case, set op_errno & op_ret */
- op_ret = -1;
- op_errno = ENOENT; /* TODO: errno */
- }
- }
- op_ret = bdb_db_rename (table, tmp_db_newpath, real_db_newpath);
- if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "renaming temp database to new db failed"
- " for directory %s", oldloc->path);
- goto out;
- }
- } else if ((op_ret != 0) && (errno == ENOENT)) {
- tmp_db_newpath = tempnam (private->export_path, "rename_temp");
- GF_VALIDATE_OR_GOTO (this->name, tmp_db_newpath, out);
-
- tmpbctx = bctx_rename (oldbctx, tmp_db_newpath);
- op_ret = -1;
- op_errno = ENOENT;
- GF_VALIDATE_OR_GOTO (this->name, tmpbctx, out);
-
- op_ret = rename (real_oldpath, real_newpath);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "rename directory %s to %s failed: %s",
- oldloc->path, newloc->path,
- strerror (errno));
- op_ret = bdb_db_rename (table,
- tmp_db_newpath,
- oldbctx->db_path);
- if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "renaming temp database back to old db failed"
- " for directory %s", oldloc->path);
- goto out;
- } else {
- /* this is a error case, set op_errno & op_ret */
- op_ret = -1;
- op_errno = ENOENT; /* TODO: errno */
- }
- } else {
- op_ret = bdb_db_rename (table,
- tmp_db_newpath,
- real_db_newpath);
- if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "renaming temp database to new db failed"
- " for directory %s", oldloc->path);
- goto out;
- } else {
- /* this is a error case, set op_errno & op_ret */
- op_ret = -1;
- op_errno = ENOENT; /* TODO: errno */
- }
- }
- }
- } else {
- gf_log (this->name,
- GF_LOG_CRITICAL,
- "rename called on non-existent file type");
- op_ret = -1;
- op_errno = EPERM;
- }
+ struct bdb_private *private = NULL;
+ bctx_table_t *table = NULL;
+ bctx_t *oldbctx = NULL;
+ bctx_t *newbctx = NULL;
+ bctx_t *tmpbctx = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = ENOENT;
+ int32_t read_size = 0;
+ struct stat stbuf = {0,};
+ struct stat old_stbuf = {0,};
+ DB_TXN *txnid = NULL;
+ char *real_newpath = NULL;
+ char *real_oldpath = NULL;
+ char *oldkey = NULL;
+ char *newkey = NULL;
+
+ /* pointer to temporary buffer, where the contents of a file are read,
+ * if file being renamed is a regular file */
+ char *buf = NULL;
+ char *real_db_newpath = NULL;
+ char *tmp_db_newpath = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, newloc, out);
+ GF_VALIDATE_OR_GOTO (this->name, oldloc, out);
+
+ private = this->private;
+ table = private->b_table;
+
+ MAKE_REAL_PATH (real_oldpath, this, oldloc->path);
+
+ if (S_ISREG (oldloc->inode->st_mode)) {
+ oldbctx = bctx_parent (B_TABLE(this), oldloc->path);
+ MAKE_REAL_PATH (real_newpath, this, newloc->path);
+
+ op_ret = lstat (real_newpath, &stbuf);
+
+ if ((op_ret == 0) && (S_ISDIR (stbuf.st_mode))) {
+ op_ret = -1;
+ op_errno = EISDIR;
+ goto out;
+ }
+ if (op_ret == 0) {
+ /* destination is a symlink */
+ MAKE_KEY_FROM_PATH (oldkey, oldloc->path);
+ MAKE_KEY_FROM_PATH (newkey, newloc->path);
+
+ op_ret = unlink (real_newpath);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "failed to unlink %s (%s)",
+ newloc->path, strerror (op_errno));
+ goto out;
+ }
+ newbctx = bctx_parent (B_TABLE (this), newloc->path);
+ GF_VALIDATE_OR_GOTO (this->name, newbctx, out);
+
+ op_ret = bdb_txn_begin (BDB_ENV(this), &txnid);
+
+ if ((read_size =
+ bdb_db_get (oldbctx, txnid, oldkey, &buf, 0, 0)) < 0) {
+ bdb_txn_abort (txnid);
+ } else if ((op_ret =
+ bdb_db_del (oldbctx, txnid, oldkey)) != 0) {
+ bdb_txn_abort (txnid);
+ } else if ((op_ret = bdb_db_put (newbctx, txnid,
+ newkey, buf,
+ read_size, 0, 0)) != 0) {
+ bdb_txn_abort (txnid);
+ } else {
+ bdb_txn_commit (txnid);
+ }
+
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (newbctx);
+ } else {
+ /* destination doesn't exist or a regular file */
+ MAKE_KEY_FROM_PATH (oldkey, oldloc->path);
+ MAKE_KEY_FROM_PATH (newkey, newloc->path);
+
+ newbctx = bctx_parent (B_TABLE (this), newloc->path);
+ GF_VALIDATE_OR_GOTO (this->name, newbctx, out);
+
+ op_ret = bdb_txn_begin (BDB_ENV(this), &txnid);
+
+ if ((read_size = bdb_db_get (oldbctx, txnid,
+ oldkey, &buf,
+ 0, 0)) < 0) {
+ bdb_txn_abort (txnid);
+ } else if ((op_ret = bdb_db_del (oldbctx,
+ txnid, oldkey)) != 0) {
+ bdb_txn_abort (txnid);
+ } else if ((op_ret = bdb_db_put (newbctx, txnid,
+ newkey, buf,
+ read_size, 0, 0)) != 0) {
+ bdb_txn_abort (txnid);
+ } else {
+ bdb_txn_commit (txnid);
+ }
+
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (newbctx);
+ }
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (oldbctx);
+ } else if (S_ISLNK (oldloc->inode->st_mode)) {
+ MAKE_REAL_PATH (real_newpath, this, newloc->path);
+ op_ret = lstat (real_newpath, &stbuf);
+ if ((op_ret == 0) && (S_ISDIR (stbuf.st_mode))) {
+ op_ret = -1;
+ op_errno = EISDIR;
+ goto out;
+ }
+
+ if (op_ret == 0){
+ /* destination exists and is also a symlink */
+ MAKE_REAL_PATH (real_oldpath, this, oldloc->path);
+ op_ret = rename (real_oldpath, real_newpath);
+ op_errno = errno;
+
+ if (op_ret != 0) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "failed to rename symlink %s (%s)",
+ oldloc->path, strerror (op_errno));
+ }
+ goto out;
+ }
+
+ /* destination doesn't exist */
+ MAKE_REAL_PATH (real_oldpath, this, oldloc->path);
+ MAKE_KEY_FROM_PATH (newkey, newloc->path);
+ newbctx = bctx_parent (B_TABLE (this), newloc->path);
+ GF_VALIDATE_OR_GOTO (this->name, newbctx, out);
+
+ op_ret = bdb_db_del (newbctx, txnid, newkey);
+ if (op_ret != 0) {
+ /* no problem */
+ }
+ op_ret = rename (real_oldpath, real_newpath);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "failed to rename %s to %s (%s)",
+ oldloc->path, newloc->path, strerror (op_errno));
+ goto out;
+ }
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (newbctx);
+ } else if (S_ISDIR (oldloc->inode->st_mode) &&
+ (old_stbuf.st_nlink == 2)) {
+
+ tmp_db_newpath = tempnam (private->export_path, "rename_temp");
+ GF_VALIDATE_OR_GOTO (this->name, tmp_db_newpath, out);
+
+ MAKE_REAL_PATH (real_newpath, this, newloc->path);
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (real_db_newpath, this, newloc->path);
+
+ oldbctx = bctx_lookup (B_TABLE(this), oldloc->path);
+ op_ret = -1;
+ op_errno = EINVAL;
+ GF_VALIDATE_OR_GOTO (this->name, oldbctx, out);
+
+ op_ret = lstat (real_newpath, &stbuf);
+ if ((op_ret == 0) &&
+ S_ISDIR (stbuf.st_mode) &&
+ is_dir_empty (this, newloc)) {
+
+ tmpbctx = bctx_rename (oldbctx, tmp_db_newpath);
+ op_ret = -1;
+ op_errno = ENOENT;
+ GF_VALIDATE_OR_GOTO (this->name, tmpbctx, out);
+
+ op_ret = rename (real_oldpath, real_newpath);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "rename directory %s to %s failed: %s",
+ oldloc->path, newloc->path,
+ strerror (errno));
+ op_ret = bdb_db_rename (table,
+ tmp_db_newpath,
+ oldbctx->db_path);
+ if (op_ret != 0) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "renaming temp database back to old db failed"
+ " for directory %s", oldloc->path);
+ goto out;
+ } else {
+ /* this is a error case, set op_errno & op_ret */
+ op_ret = -1;
+ op_errno = ENOENT; /* TODO: errno */
+ }
+ }
+ op_ret = bdb_db_rename (table, tmp_db_newpath, real_db_newpath);
+ if (op_ret != 0) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "renaming temp database to new db failed"
+ " for directory %s", oldloc->path);
+ goto out;
+ }
+ } else if ((op_ret != 0) && (errno == ENOENT)) {
+ tmp_db_newpath = tempnam (private->export_path, "rename_temp");
+ GF_VALIDATE_OR_GOTO (this->name, tmp_db_newpath, out);
+
+ tmpbctx = bctx_rename (oldbctx, tmp_db_newpath);
+ op_ret = -1;
+ op_errno = ENOENT;
+ GF_VALIDATE_OR_GOTO (this->name, tmpbctx, out);
+
+ op_ret = rename (real_oldpath, real_newpath);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "rename directory %s to %s failed: %s",
+ oldloc->path, newloc->path,
+ strerror (errno));
+ op_ret = bdb_db_rename (table,
+ tmp_db_newpath,
+ oldbctx->db_path);
+ if (op_ret != 0) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "renaming temp database back to old db failed"
+ " for directory %s", oldloc->path);
+ goto out;
+ } else {
+ /* this is a error case, set op_errno & op_ret */
+ op_ret = -1;
+ op_errno = ENOENT; /* TODO: errno */
+ }
+ } else {
+ op_ret = bdb_db_rename (table,
+ tmp_db_newpath,
+ real_db_newpath);
+ if (op_ret != 0) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "renaming temp database to new db failed"
+ " for directory %s", oldloc->path);
+ goto out;
+ } else {
+ /* this is a error case, set op_errno & op_ret */
+ op_ret = -1;
+ op_errno = ENOENT; /* TODO: errno */
+ }
+ }
+ }
+ } else {
+ gf_log (this->name,
+ GF_LOG_CRITICAL,
+ "rename called on non-existent file type");
+ op_ret = -1;
+ op_errno = EPERM;
+ }
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+ return 0;
}
-int32_t
-bdb_link (call_frame_t *frame,
+int32_t
+bdb_link (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
loc_t *newloc)
{
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, -1, EPERM, NULL, NULL);
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, -1, EPERM, NULL, NULL);
+ return 0;
}
int32_t
is_space_left (xlator_t *this,
- size_t size)
+ size_t size)
{
- struct bdb_private *private = this->private;
- struct statvfs stbuf = {0,};
- int32_t ret = -1;
- fsblkcnt_t req_blocks = 0;
- fsblkcnt_t usable_blocks = 0;
-
- ret = statvfs (private->export_path, &stbuf);
- if (ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to do statvfs on %s", private->export_path);
- return 0;
- } else {
- req_blocks = (size / stbuf.f_frsize) + 1;
-
- usable_blocks = (stbuf.f_bfree - BDB_ENOSPC_THRESHOLD);
-
- gf_log (this->name, GF_LOG_DEBUG,
- "requested size: %"GF_PRI_SIZET"\nfree blocks: %"PRIu64"\nblock size: %lu\nfrag size: %lu",
- size, stbuf.f_bfree, stbuf.f_bsize, stbuf.f_frsize);
-
- if (req_blocks < usable_blocks)
- return 1;
- else
- return 0;
- }
+ struct bdb_private *private = this->private;
+ struct statvfs stbuf = {0,};
+ int32_t ret = -1;
+ fsblkcnt_t req_blocks = 0;
+ fsblkcnt_t usable_blocks = 0;
+
+ ret = statvfs (private->export_path, &stbuf);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to do statvfs on %s",
+ private->export_path);
+ return 0;
+ } else {
+ req_blocks = (size / stbuf.f_frsize) + 1;
+
+ usable_blocks = (stbuf.f_bfree - BDB_ENOSPC_THRESHOLD);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "requested size: %"GF_PRI_SIZET"\n"
+ "free blocks: %"PRIu64"\n"
+ "block size: %lu\nfrag size: %lu",
+ size, stbuf.f_bfree, stbuf.f_bsize, stbuf.f_frsize);
+
+ if (req_blocks < usable_blocks)
+ return 1;
+ else
+ return 0;
+ }
}
-int32_t
+int32_t
bdb_create (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
@@ -554,214 +556,211 @@ bdb_create (call_frame_t *frame,
mode_t mode,
fd_t *fd)
{
- int32_t op_ret = -1;
- int32_t op_errno = EPERM;
- char *db_path = NULL;
- struct stat stbuf = {0,};
- bctx_t *bctx = NULL;
- struct bdb_private *private = NULL;
- char *key_string = NULL;
- struct bdb_fd *bfd = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- private = this->private;
-
- bctx = bctx_parent (B_TABLE(this), loc->path);
- op_errno = ENOENT;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
- op_ret = lstat (db_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- db_path, strerror (op_errno));
- goto out;
- }
-
- MAKE_KEY_FROM_PATH (key_string, loc->path);
- op_ret = bdb_db_put (bctx, NULL, key_string, NULL, 0, 0, 0);
- op_errno = EINVAL;
- GF_VALIDATE_OR_GOTO (this->name, (op_ret == 0), out);
-
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ char *db_path = NULL;
+ struct stat stbuf = {0,};
+ bctx_t *bctx = NULL;
+ struct bdb_private *private = NULL;
+ char *key_string = NULL;
+ struct bdb_fd *bfd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ private = this->private;
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ op_errno = ENOENT;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ db_path, strerror (op_errno));
+ goto out;
+ }
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+ op_ret = bdb_db_put (bctx, NULL, key_string, NULL, 0, 0, 0);
+ op_errno = EINVAL;
+ GF_VALIDATE_OR_GOTO (this->name, (op_ret == 0), out);
+
/* create successful */
- bfd = CALLOC (1, sizeof (*bfd));
- op_ret = -1;
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
-
- /* NOTE: bdb_get_bctx_from () returns bctx with a ref */
- bfd->ctx = bctx;
- bfd->key = strdup (key_string);
- op_ret = -1;
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, bfd->key, out);
-
- BDB_SET_BFD (this, fd, bfd);
-
- stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
- stbuf.st_mode = private->file_mode;
- stbuf.st_size = 0;
- stbuf.st_nlink = 1;
- stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
- op_ret = 0;
- op_errno = 0;
+ bfd = CALLOC (1, sizeof (*bfd));
+ op_ret = -1;
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+
+ /* NOTE: bdb_get_bctx_from () returns bctx with a ref */
+ bfd->ctx = bctx;
+ bfd->key = strdup (key_string);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, bfd->key, out);
+
+ BDB_SET_BFD (this, fd, bfd);
+
+ stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
+ stbuf.st_mode = private->file_mode;
+ stbuf.st_size = 0;
+ stbuf.st_nlink = 1;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
+ op_ret = 0;
+ op_errno = 0;
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, fd, loc->inode, &stbuf);
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, fd, loc->inode, &stbuf);
- return 0;
+ return 0;
}
/* bdb_open
*
- * as input parameters bdb_open gets the file name, i.e key. bdb_open should effectively
+ * as input parameters bdb_open gets the file name, i.e key. bdb_open should
+ * effectively
* do: store key, open storage db, store storage-db pointer.
*
*/
-int32_t
+int32_t
bdb_open (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
int32_t flags,
fd_t *fd)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- bctx_t *bctx = NULL;
- char *key_string = NULL;
- struct bdb_fd *bfd = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- bctx = bctx_parent (B_TABLE(this), loc->path);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- bfd = CALLOC (1, sizeof (*bfd));
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
-
- /* NOTE: bctx_parent () returns bctx with a ref */
- bfd->ctx = bctx;
-
- MAKE_KEY_FROM_PATH (key_string, loc->path);
- bfd->key = strdup (key_string);
- op_ret = -1;
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, bfd->key, out);
-
- BDB_SET_BFD (this, fd, bfd);
- op_ret = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ bctx_t *bctx = NULL;
+ char *key_string = NULL;
+ struct bdb_fd *bfd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ bfd = CALLOC (1, sizeof (*bfd));
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+
+ /* NOTE: bctx_parent () returns bctx with a ref */
+ bfd->ctx = bctx;
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+ bfd->key = strdup (key_string);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, bfd->key, out);
+
+ BDB_SET_BFD (this, fd, bfd);
+ op_ret = 0;
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, fd);
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
- return 0;
+ return 0;
}
-int32_t
+int32_t
bdb_readv (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
off_t offset)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- struct iovec vec = {0,};
- struct stat stbuf = {0,};
- struct bdb_fd *bfd = NULL;
- dict_t *reply_dict = NULL;
- char *buf = NULL;
- data_t *buf_data = NULL;
- char *db_path = NULL;
- int32_t read_size = 0;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- bfd = bdb_extract_bfd (fd, this);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
-
- MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bfd->ctx->directory);
- op_ret = lstat (db_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- db_path, strerror (op_errno));
- goto out;
- }
-
- /* we are ready to go */
- op_ret = bdb_db_get (bfd->ctx, NULL,
- bfd->key, &buf,
- size, offset);
- read_size = op_ret;
- if (op_ret == -1) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to do db_storage_get()");
- op_ret = -1;
- op_errno = ENOENT;
- goto out;
- } else if (op_ret == 0) {
- goto out;
- }
-
- buf_data = get_new_data ();
- op_ret = -1;
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, buf_data, out);
-
- reply_dict = get_new_dict ();
- op_ret = -1;
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, reply_dict, out);
-
- buf_data->data = buf;
-
- if (size < read_size) {
- op_ret = size;
- read_size = size;
- }
-
- buf_data->len = op_ret;
-
- dict_set (reply_dict, NULL, buf_data);
-
- frame->root->rsp_refs = dict_ref (reply_dict);
-
- vec.iov_base = buf;
- vec.iov_len = read_size;
-
- stbuf.st_ino = fd->inode->ino;
- stbuf.st_size = op_ret ;
- stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
- op_ret = size;
-out:
- STACK_UNWIND (frame, op_ret, op_errno, &vec, 1, &stbuf);
-
- if (reply_dict)
- dict_unref (reply_dict);
-
- return 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ struct iovec vec = {0,};
+ struct stat stbuf = {0,};
+ struct bdb_fd *bfd = NULL;
+ dict_t *reply_dict = NULL;
+ char *buf = NULL;
+ data_t *buf_data = NULL;
+ char *db_path = NULL;
+ int32_t read_size = 0;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ bfd = bdb_extract_bfd (fd, this);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bfd->ctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ db_path, strerror (op_errno));
+ goto out;
+ }
+
+ /* we are ready to go */
+ op_ret = bdb_db_get (bfd->ctx, NULL,
+ bfd->key, &buf,
+ size, offset);
+ read_size = op_ret;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to do db_storage_get()");
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto out;
+ } else if (op_ret == 0) {
+ goto out;
+ }
+
+ reply_dict = dict_new ();
+ op_ret = -1;
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, reply_dict, out);
+
+ if (size < read_size) {
+ op_ret = size;
+ read_size = size;
+ }
+
+ buf_data->len = op_ret;
+
+ op_ret = dict_set_dynptr (reply_dict, NULL, buf, op_ret);
+ if (op_ret < 0) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ free (buf);
+ goto out;
+ }
+
+ vec.iov_base = buf;
+ vec.iov_len = read_size;
+
+ stbuf.st_ino = fd->inode->ino;
+ stbuf.st_size = op_ret ;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
+ op_ret = size;
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, &vec, 1, &stbuf);
+
+ if (reply_dict)
+ dict_unref (reply_dict);
+
+ return 0;
}
-int32_t
+int32_t
bdb_writev (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
@@ -769,174 +768,174 @@ bdb_writev (call_frame_t *frame,
int32_t count,
off_t offset)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- struct stat stbuf = {0,};
- struct bdb_fd *bfd = NULL;
- int32_t idx = 0;
- off_t c_off = offset;
- int32_t c_ret = -1;
- char *db_path = NULL;
- size_t total_size = 0;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, vector, out);
-
- bfd = bdb_extract_bfd (fd, this);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
-
- MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bfd->ctx->directory);
- op_ret = lstat (db_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- db_path, strerror (op_errno));
- goto out;
- }
-
-
- for (idx = 0; idx < count; idx++)
- total_size += vector[idx].iov_len;
-
- if (!is_space_left (this, total_size)) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "requested storage for %"GF_PRI_SIZET", ENOSPC", total_size);
- op_ret = -1;
- op_errno = ENOSPC;
- goto out;
- }
-
-
- /* we are ready to go */
- for (idx = 0; idx < count; idx++) {
- c_ret = bdb_db_put (bfd->ctx, NULL,
- bfd->key, vector[idx].iov_base,
- vector[idx].iov_len, c_off, 0);
- if (c_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to do bdb_db_put at offset: %"PRIu64" for file: %s",
- c_off, bfd->key);
- break;
- } else {
- c_off += vector[idx].iov_len;
- }
- op_ret += vector[idx].iov_len;
- } /* for(idx=0;...)... */
-
- if (c_ret) {
- /* write failed */
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to do bdb_db_put(): %s",
- db_strerror (op_ret));
- op_ret = -1;
- op_errno = EBADFD; /* TODO: search for a more meaningful errno */
- goto out;
- }
- /* NOTE: we want to increment stbuf->st_size, as stored in db */
- stbuf.st_size = op_ret;
- stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
- op_errno = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ struct stat stbuf = {0,};
+ struct bdb_fd *bfd = NULL;
+ int32_t idx = 0;
+ off_t c_off = offset;
+ int32_t c_ret = -1;
+ char *db_path = NULL;
+ size_t total_size = 0;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+ GF_VALIDATE_OR_GOTO (this->name, vector, out);
+
+ bfd = bdb_extract_bfd (fd, this);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bfd->ctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ db_path, strerror (op_errno));
+ goto out;
+ }
+
+
+ for (idx = 0; idx < count; idx++)
+ total_size += vector[idx].iov_len;
+
+ if (!is_space_left (this, total_size)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "requested storage for %"GF_PRI_SIZET", ENOSPC",
+ total_size);
+ op_ret = -1;
+ op_errno = ENOSPC;
+ goto out;
+ }
+
+
+ /* we are ready to go */
+ for (idx = 0; idx < count; idx++) {
+ c_ret = bdb_db_put (bfd->ctx, NULL,
+ bfd->key, vector[idx].iov_base,
+ vector[idx].iov_len, c_off, 0);
+ if (c_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to do bdb_db_put at offset: "
+ "%"PRIu64" for file: %s",
+ c_off, bfd->key);
+ break;
+ } else {
+ c_off += vector[idx].iov_len;
+ }
+ op_ret += vector[idx].iov_len;
+ } /* for(idx=0;...)... */
+
+ if (c_ret) {
+ /* write failed */
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to do bdb_db_put(): %s",
+ db_strerror (op_ret));
+ op_ret = -1;
+ op_errno = EBADFD; /* TODO: search for a meaningful errno */
+ goto out;
+ }
+ /* NOTE: we want to increment stbuf->st_size, as stored in db */
+ stbuf.st_size = op_ret;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
+ op_errno = 0;
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+ return 0;
}
-int32_t
+int32_t
bdb_flush (call_frame_t *frame,
xlator_t *this,
fd_t *fd)
{
- int32_t op_ret = -1;
- int32_t op_errno = EPERM;
- struct bdb_fd *bfd = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- bfd = bdb_extract_bfd (fd, this);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
-
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ struct bdb_fd *bfd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ bfd = bdb_extract_bfd (fd, this);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+
/* do nothing */
- op_ret = 0;
- op_errno = 0;
+ op_ret = 0;
+ op_errno = 0;
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
}
-int32_t
+int32_t
bdb_release (xlator_t *this,
- fd_t *fd)
+ fd_t *fd)
{
- int32_t op_ret = -1;
- int32_t op_errno = EBADFD;
- struct bdb_fd *bfd = NULL;
-
- if ((bfd = bdb_extract_bfd (fd, this)) == NULL){
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to extract %s specific information from fd:%p", this->name, fd);
- op_ret = -1;
- op_errno = EBADFD;
- } else {
- bctx_unref (bfd->ctx);
- bfd->ctx = NULL;
-
- if (bfd->key)
- free (bfd->key); /* we did strdup() in bdb_open() */
- free (bfd);
- op_ret = 0;
- op_errno = 0;
- } /* if((fd->ctx == NULL)...)...else */
-
- return 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EBADFD;
+ struct bdb_fd *bfd = NULL;
+
+ if ((bfd = bdb_extract_bfd (fd, this)) == NULL){
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to extract %s specific information from fd:%p",
+ this->name, fd);
+ op_ret = -1;
+ op_errno = EBADFD;
+ } else {
+ bctx_unref (bfd->ctx);
+ bfd->ctx = NULL;
+
+ if (bfd->key)
+ free (bfd->key); /* we did strdup() in bdb_open() */
+ free (bfd);
+ op_ret = 0;
+ op_errno = 0;
+ } /* if((fd->ctx == NULL)...)...else */
+
+ return 0;
}/* bdb_release */
-int32_t
+int32_t
bdb_fsync (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
int32_t datasync)
{
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, 0, 0);
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, 0, 0);
+ return 0;
}/* bdb_fsync */
static int gf_bdb_lk_log;
-int32_t
+int32_t
bdb_lk (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
int32_t cmd,
struct flock *lock)
{
- struct flock nullock = {0, };
+ struct flock nullock = {0, };
- gf_bdb_lk_log++;
- if (!(gf_bdb_lk_log % GF_UNIVERSAL_ANSWER)) {
- gf_log (this->name, GF_LOG_ERROR,
- "\"features/posix-locks\" translator is not loaded, you need to use it");
- }
+ gf_bdb_lk_log++;
+ if (!(gf_bdb_lk_log % GF_UNIVERSAL_ANSWER)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "\"features/posix-locks\" translator is not loaded, "
+ "you need to use it");
+ }
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, -1, ENOSYS, &nullock);
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, -1, ENOSYS, &nullock);
+ return 0;
}/* bdb_lk */
/* bdb_lookup
@@ -946,30 +945,33 @@ bdb_lk (call_frame_t *frame,
* 2. file exists and is a symlink.
* 3. file exists and is a regular file.
* 4. file does not exist.
- * case 1 and 2 are handled by doing lstat() on the @loc. if the file is a directory or symlink,
- * lstat() succeeds. lookup continues to check if the @loc belongs to case-3 only if lstat() fails.
- * to check for case 3, bdb_lookup does a bdb_db_get() for the given @loc. (see description of
- * bdb_db_get() for more details on how @loc is transformed into db handle and key). if check
- * for case 1, 2 and 3 fail, we proceed to conclude that file doesn't exist (case 4).
+ * case 1 and 2 are handled by doing lstat() on the @loc. if the file is a
+ * directory or symlink, lstat() succeeds. lookup continues to check if the
+ * @loc belongs to case-3 only if lstat() fails.
+ * to check for case 3, bdb_lookup does a bdb_db_get() for the given @loc.
+ * (see description of bdb_db_get() for more details on how @loc is transformed
+ * into db handle and key). if check for case 1, 2 and 3 fail, we proceed to
+ * conclude that file doesn't exist (case 4).
*
* @frame: call frame.
* @this: xlator_t of this instance of bdb xlator.
* @loc: loc_t specifying the file to operate upon.
- * @need_xattr: if need_xattr != 0, we are asked to return all the extended attributed of @loc,
- * if any exist, in a dictionary. if @loc is a regular file and need_xattr is set, then
- * we look for value of need_xattr. if need_xattr > sizo-of-the-file @loc, then the file
- * content of @loc is returned in dictionary of xattr with 'glusterfs.content' as
- * dictionary key.
+ * @need_xattr: if need_xattr != 0, we are asked to return all the extended
+ * attributed of @loc, if any exist, in a dictionary. if @loc is a regular
+ * file and need_xattr is set, then we look for value of need_xattr. if
+ * need_xattr > sizo-of-the-file @loc, then the file content of @loc is
+ * returned in dictionary of xattr with 'glusterfs.content' as dictionary key.
*
- * NOTE: bdb currently supports only directories, symlinks and regular files.
+ * NOTE: bdb currently supports only directories, symlinks and regular files.
*
- * NOTE: bdb_lookup returns the 'struct stat' of underlying file itself, in case of directory and
- * symlink (st_ino is modified as bdb allocates its own set of inodes of all files). for
- * regular files, bdb uses 'struct stat' of the database file in which the @loc is stored
- * as templete and modifies st_ino (see bdb_inode_transform for more details), st_mode (can
- * be set in volfile 'option file-mode <mode>'), st_size (exact size of the @loc
- * contents), st_blocks (block count on the underlying filesystem to accomodate st_size,
- * see BDB_COUNT_BLOCKS in bdb.h for more details).
+ * NOTE: bdb_lookup returns the 'struct stat' of underlying file itself, in
+ * case of directory and symlink (st_ino is modified as bdb allocates its own
+ * set of inodes of all files). for regular files, bdb uses 'struct stat' of
+ * the database file in which the @loc is stored as templete and modifies
+ * st_ino (see bdb_inode_transform for more details), st_mode (can be set in
+ * volfile 'option file-mode <mode>'), st_size (exact size of the @loc
+ * contents), st_blocks (block count on the underlying filesystem to
+ * accomodate st_size, see BDB_COUNT_BLOCKS in bdb.h for more details).
*/
int32_t
bdb_lookup (call_frame_t *frame,
@@ -977,186 +979,188 @@ bdb_lookup (call_frame_t *frame,
loc_t *loc,
dict_t *xattr_req)
{
- struct stat stbuf = {0, };
- int32_t op_ret = -1;
- int32_t op_errno = ENOENT;
- dict_t *xattr = NULL;
- char *pathname = NULL;
- char *directory = NULL;
- char *real_path = NULL;
- bctx_t *bctx = NULL;
- char *db_path = NULL;
- struct bdb_private *private = NULL;
- char *key_string = NULL;
- int32_t entry_size = 0;
- char *file_content = NULL;
- data_t *file_content_data = NULL;
- uint64_t need_xattr = 0;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- private = this->private;
-
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- pathname = strdup (loc->path);
- GF_VALIDATE_OR_GOTO (this->name, pathname, out);
-
- directory = dirname (pathname);
- GF_VALIDATE_OR_GOTO (this->name, directory, out);
-
- if (!strcmp (directory, loc->path)) {
- /* SPECIAL CASE: looking up root */
- op_ret = lstat (real_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- real_path, strerror (op_errno));
- goto out;
- }
-
- /* bctx_lookup() returns NULL only when its time to wind up,
- * we should shutdown functioning */
- bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
- op_ret = -1;
- op_errno = EINVAL;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- stbuf.st_ino = 1;
- stbuf.st_mode = private->dir_mode;
- } else {
- MAKE_KEY_FROM_PATH (key_string, loc->path);
- op_ret = lstat (real_path, &stbuf);
- if ((op_ret == 0) && (S_ISDIR (stbuf.st_mode))){
- bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
- op_ret = -1;
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- if (loc->ino) {
- /* revalidating directory inode */
- gf_log (this->name,
- GF_LOG_DEBUG,
- "revalidating directory %s", (char *)loc->path);
- stbuf.st_ino = loc->ino;
- } else {
- stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
- }
- stbuf.st_mode = private->dir_mode;
- op_ret = 0;
- op_errno = 0;
- goto out;
- } else if (op_ret == 0) {
- /* a symlink */
- gf_log (this->name,
- GF_LOG_DEBUG,
- "lookup called for symlink: %s", loc->path);
- bctx = bctx_parent (B_TABLE(this), loc->path);
- op_ret = -1;
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- if (loc->ino) {
- stbuf.st_ino = loc->ino;
- } else {
- stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
- }
- stbuf.st_mode = private->symlink_mode;
- op_ret = 0;
- op_errno = 0;
- goto out;
- }
-
- /* for regular files */
- bctx = bctx_parent (B_TABLE(this), loc->path);
- op_ret = -1;
- op_errno = ENOENT;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- if (GF_FILE_CONTENT_REQUESTED(xattr_req, &need_xattr)) {
- entry_size = bdb_db_get (bctx,
- NULL,
- loc->path,
- &file_content,
- 0, 0);
- } else {
- entry_size = bdb_db_get (bctx,
- NULL,
- loc->path,
- NULL,
- 0, 0);
- }
-
- op_ret = entry_size;
- op_errno = ENOENT;
- if (op_ret == -1) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "returning ENOENT for %s", loc->path);
- goto out;
- }
-
- MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
- op_ret = lstat (db_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- db_path, strerror (op_errno));
- goto out;
- }
-
- if ((need_xattr >= entry_size)
- && (entry_size) && (file_content)) {
- file_content_data = data_from_dynptr (file_content,
- entry_size);
- xattr = get_new_dict ();
- dict_set (xattr, "glusterfs.content",
- file_content_data);
- } else {
- if (file_content)
- free (file_content);
- }
-
- if (loc->ino) {
- /* revalidate */
- stbuf.st_ino = loc->ino;
- stbuf.st_size = entry_size;
- stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
- } else {
- /* fresh lookup, create an inode number */
- stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
- stbuf.st_size = entry_size;
- stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
- }/* if(inode->ino)...else */
- stbuf.st_nlink = 1;
- stbuf.st_mode = private->file_mode;
- }
- op_ret = 0;
-out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
-
- if (pathname)
- free (pathname);
-
- if (xattr)
- dict_ref (xattr);
-
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf, xattr);
-
- if (xattr)
- dict_unref (xattr);
-
- return 0;
-
+ struct stat stbuf = {0, };
+ int32_t op_ret = -1;
+ int32_t op_errno = ENOENT;
+ dict_t *xattr = NULL;
+ char *pathname = NULL;
+ char *directory = NULL;
+ char *real_path = NULL;
+ bctx_t *bctx = NULL;
+ char *db_path = NULL;
+ struct bdb_private *private = NULL;
+ char *key_string = NULL;
+ int32_t entry_size = 0;
+ char *file_content = NULL;
+ uint64_t need_xattr = 0;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ private = this->private;
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ pathname = strdup (loc->path);
+ GF_VALIDATE_OR_GOTO (this->name, pathname, out);
+
+ directory = dirname (pathname);
+ GF_VALIDATE_OR_GOTO (this->name, directory, out);
+
+ if (!strcmp (directory, loc->path)) {
+ /* SPECIAL CASE: looking up root */
+ op_ret = lstat (real_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ real_path, strerror (op_errno));
+ goto out;
+ }
+
+ /* bctx_lookup() returns NULL only when its time to wind up,
+ * we should shutdown functioning */
+ bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
+ op_ret = -1;
+ op_errno = EINVAL;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ stbuf.st_ino = 1;
+ stbuf.st_mode = private->dir_mode;
+
+ op_ret = 0;
+ goto out;
+ }
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+ op_ret = lstat (real_path, &stbuf);
+ if ((op_ret == 0) && (S_ISDIR (stbuf.st_mode))){
+ bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ if (loc->ino) {
+ /* revalidating directory inode */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "revalidating directory %s",
+ (char *)loc->path);
+ stbuf.st_ino = loc->ino;
+ } else {
+ stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
+ }
+ stbuf.st_mode = private->dir_mode;
+ op_ret = 0;
+ op_errno = 0;
+ goto out;
+ } else if (op_ret == 0) {
+ /* a symlink */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "lookup called for symlink: %s",
+ loc->path);
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ if (loc->ino) {
+ stbuf.st_ino = loc->ino;
+ } else {
+ stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
+ }
+ stbuf.st_mode = private->symlink_mode;
+ op_ret = 0;
+ op_errno = 0;
+ goto out;
+ }
+
+ /* for regular files */
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ op_ret = -1;
+ op_errno = ENOENT;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ if (GF_FILE_CONTENT_REQUESTED(xattr_req, &need_xattr)) {
+ entry_size = bdb_db_get (bctx, NULL,
+ loc->path, &file_content,
+ 0, 0);
+ } else {
+ entry_size = bdb_db_get (bctx, NULL, loc->path, NULL,
+ 0, 0);
+ }
+
+ op_ret = entry_size;
+ op_errno = ENOENT;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "returning ENOENT for %s",
+ loc->path);
+ goto out;
+ }
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ db_path, strerror (op_errno));
+ goto out;
+ }
+
+ if ((need_xattr >= entry_size)
+ && (entry_size) && (file_content)) {
+ xattr = dict_new ();
+ op_ret = dict_set_dynptr (xattr, "glusterfs.content",
+ file_content, entry_size);
+ if (op_ret < 0) {
+ /* continue without giving file contents */
+ FREE (file_content);
+ }
+ } else {
+ if (file_content)
+ FREE (file_content);
+ }
+
+ if (loc->ino) {
+ /* revalidate */
+ stbuf.st_ino = loc->ino;
+ stbuf.st_size = entry_size;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size,
+ stbuf.st_blksize);
+ } else {
+ /* fresh lookup, create an inode number */
+ stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
+ stbuf.st_size = entry_size;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size,
+ stbuf.st_blksize);
+ }/* if(inode->ino)...else */
+ stbuf.st_nlink = 1;
+ stbuf.st_mode = private->file_mode;
+
+ op_ret = 0;
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ if (pathname)
+ free (pathname);
+
+ if (xattr)
+ dict_ref (xattr);
+
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf, xattr);
+
+ if (xattr)
+ dict_unref (xattr);
+
+ return 0;
+
}/* bdb_lookup */
int32_t
@@ -1164,77 +1168,78 @@ bdb_stat (call_frame_t *frame,
xlator_t *this,
loc_t *loc)
{
-
- struct stat stbuf = {0,};
- char *real_path = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- struct bdb_private *private = NULL;
- char *db_path = NULL;
- bctx_t *bctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- private = this->private;
- GF_VALIDATE_OR_GOTO (this->name, private, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- op_ret = lstat (real_path, &stbuf);
- op_errno = errno;
- if (op_ret == 0) {
- /* directory or symlink */
- stbuf.st_ino = loc->inode->ino;
- if (S_ISDIR(stbuf.st_mode))
- stbuf.st_mode = private->dir_mode;
- else
- stbuf.st_mode = private->symlink_mode;
- /* we are done, lets unwind the stack */
- goto out;
- }
-
- bctx = bctx_parent (B_TABLE(this), loc->path);
- op_ret = -1;
- op_errno = ENOENT;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
- op_ret = lstat (db_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- db_path, strerror (op_errno));
- goto out;
- }
-
- stbuf.st_size = bdb_db_get (bctx, NULL, loc->path, NULL, 0, 0);
- stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
- stbuf.st_ino = loc->inode->ino;
-
+
+ struct stat stbuf = {0,};
+ char *real_path = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ struct bdb_private *private = NULL;
+ char *db_path = NULL;
+ bctx_t *bctx = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ private = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, private, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ op_ret = lstat (real_path, &stbuf);
+ op_errno = errno;
+ if (op_ret == 0) {
+ /* directory or symlink */
+ stbuf.st_ino = loc->inode->ino;
+ if (S_ISDIR(stbuf.st_mode))
+ stbuf.st_mode = private->dir_mode;
+ else
+ stbuf.st_mode = private->symlink_mode;
+ /* we are done, lets unwind the stack */
+ goto out;
+ }
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ op_ret = -1;
+ op_errno = ENOENT;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ db_path, strerror (op_errno));
+ goto out;
+ }
+
+ stbuf.st_size = bdb_db_get (bctx, NULL, loc->path, NULL, 0, 0);
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
+ stbuf.st_ino = loc->inode->ino;
+
out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
- return 0;
+ return 0;
}/* bdb_stat */
-/* bdb_opendir - in the world of bdb, open/opendir is all about opening correspondind databases.
- * opendir in particular, opens the database for the directory which is
- * to be opened. after opening the database, a cursor to the database is also created.
- * cursor helps us get the dentries one after the other, and cursor maintains the state
- * about current positions in directory. pack 'pointer to db', 'pointer to the
- * cursor' into struct bdb_dir and store it in fd->ctx, we get from our parent xlator.
+/* bdb_opendir - in the world of bdb, open/opendir is all about opening
+ * correspondind databases. opendir in particular, opens the database for the
+ * directory which is to be opened. after opening the database, a cursor to
+ * the database is also created. cursor helps us get the dentries one after
+ * the other, and cursor maintains the state about current positions in
+ * directory. pack 'pointer to db', 'pointer to the cursor' into
+ * struct bdb_dir and store it in fd->ctx, we get from our parent xlator.
*
* @frame: call frame
* @this: our information, as we filled during init()
@@ -1244,51 +1249,51 @@ out:
* return value - immaterial, async call.
*
*/
-int32_t
+int32_t
bdb_opendir (call_frame_t *frame,
xlator_t *this,
- loc_t *loc,
+ loc_t *loc,
fd_t *fd)
{
- char *real_path = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- bctx_t *bctx = NULL;
- struct bdb_dir *bfd = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- bfd = CALLOC (1, sizeof (*bfd));
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
-
- bfd->dir = opendir (real_path);
- op_errno = errno;
- GF_VALIDATE_OR_GOTO (this->name, bfd->dir, out);
-
- /* NOTE: bctx_lookup() return bctx with ref */
- bfd->ctx = bctx;
-
- bfd->path = strdup (real_path);
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, bfd->path, out);
-
- BDB_SET_BFD (this, fd, bfd);
- op_ret = 0;
-out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, fd);
-
- return 0;
+ char *real_path = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ bctx_t *bctx = NULL;
+ struct bdb_dir *bfd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ bfd = CALLOC (1, sizeof (*bfd));
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+
+ bfd->dir = opendir (real_path);
+ op_errno = errno;
+ GF_VALIDATE_OR_GOTO (this->name, bfd->dir, out);
+
+ /* NOTE: bctx_lookup() return bctx with ref */
+ bfd->ctx = bctx;
+
+ bfd->path = strdup (real_path);
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, bfd->path, out);
+
+ BDB_SET_BFD (this, fd, bfd);
+ op_ret = 0;
+out:
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
+
+ return 0;
}/* bdb_opendir */
@@ -1300,396 +1305,397 @@ bdb_getdents (call_frame_t *frame,
off_t off,
int32_t flag)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- int32_t ret = -1;
- int32_t real_path_len = 0;
- int32_t entry_path_len = 0;
- int32_t count = 0;
- char *real_path = NULL;
- char *entry_path = NULL;
- char *db_path = NULL;
- dir_entry_t entries = {0, };
- dir_entry_t *tmp = NULL;
- DIR *dir = NULL;
- struct dirent *dirent = NULL;
- struct bdb_dir *bfd = NULL;
- struct stat db_stbuf = {0,};
- struct stat buf = {0,};
- DBC *cursorp = NULL;
- size_t tmp_name_len = 0;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- bfd = bdb_extract_bfd (fd, this);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
-
- MAKE_REAL_PATH (real_path, this, bfd->path);
- dir = bfd->dir;
-
- while ((dirent = readdir (dir))) {
- if (!dirent)
- break;
-
- if (IS_BDB_PRIVATE_FILE(dirent->d_name)) {
- continue;
- }
-
- tmp_name_len = strlen (dirent->d_name);
- if (entry_path_len < (real_path_len + 1 + (tmp_name_len) + 1)) {
- entry_path_len = real_path_len + tmp_name_len + 1024;
- entry_path = realloc (entry_path, entry_path_len);
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, entry_path, out);
- }
-
- strncpy (&entry_path[real_path_len+1], dirent->d_name, tmp_name_len);
- op_ret = stat (entry_path, &buf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- entry_path, strerror (op_errno));
- goto out;
- }
-
- if ((flag == GF_GET_DIR_ONLY) &&
- (ret != -1 && !S_ISDIR(buf.st_mode))) {
- continue;
- }
-
- tmp = CALLOC (1, sizeof (*tmp));
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, tmp, out);
-
- tmp->name = strdup (dirent->d_name);
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, dirent->d_name, out);
-
- memcpy (&tmp->buf, &buf, sizeof (buf));
-
- tmp->buf.st_ino = -1;
- if (S_ISLNK(tmp->buf.st_mode)) {
- char linkpath[ZR_PATH_MAX] = {0,};
- ret = readlink (entry_path, linkpath, ZR_PATH_MAX);
- if (ret != -1) {
- linkpath[ret] = '\0';
- tmp->link = strdup (linkpath);
- }
- } else {
- tmp->link = "";
- }
-
- count++;
-
- tmp->next = entries.next;
- entries.next = tmp;
- /* if size is 0, count can never be = size, so entire dir is read */
-
- if (count == size)
- break;
- }
-
- if ((flag != GF_GET_DIR_ONLY) && (count < size)) {
- /* read from db */
- op_ret = bdb_cursor_open (bfd->ctx, &cursorp);
- op_errno = EINVAL;
- GF_VALIDATE_OR_GOTO (this->name, (op_ret == 0), out);
-
- MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bfd->ctx->directory);
- op_ret = lstat (db_path, &db_stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- db_path, strerror (op_errno));
- goto out;
- }
-
- /* read all the entries in database, one after the other and put into dictionary */
- while (1) {
- DBT key = {0,}, value = {0,};
-
- key.flags = DB_DBT_MALLOC;
- value.flags = DB_DBT_MALLOC;
- op_ret = bdb_cursor_get (cursorp, &key, &value, DB_NEXT);
-
- if (op_ret == DB_NOTFOUND) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "end of list of key/value pair in db for directory: %s",
- bfd->ctx->directory);
- op_ret = 0;
- op_errno = 0;
- break;
- } else if (op_ret != 0){
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to do cursor get for directory %s: %s",
- bfd->ctx->directory, db_strerror (op_ret));
- op_ret = -1;
- op_errno = ENOENT;
- break;
- }
- /* successfully read */
- tmp = CALLOC (1, sizeof (*tmp));
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, tmp, out);
-
- tmp->name = CALLOC (1, key.size + 1);
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, tmp->name, out);
-
- memcpy (tmp->name, key.data, key.size);
- tmp->buf = db_stbuf;
- tmp->buf.st_size = bdb_db_get (bfd->ctx, NULL,
- tmp->name, NULL,
- 0, 0);
- tmp->buf.st_blocks = BDB_COUNT_BLOCKS (tmp->buf.st_size, \
- tmp->buf.st_blksize);
- /* FIXME: wat will be the effect of this? */
- tmp->buf.st_ino = -1;
- count++;
-
- tmp->next = entries.next;
- tmp->link = "";
- entries.next = tmp;
- /* if size is 0, count can never be = size, so entire dir is read */
- if (count == size)
- break;
-
- free (key.data);
- } /* while(1){ } */
- bdb_cursor_close (bfd->ctx, cursorp);
- } else {
- /* do nothing */
- }
- FREE (entry_path);
- op_ret = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ int32_t ret = -1;
+ int32_t real_path_len = 0;
+ int32_t entry_path_len = 0;
+ int32_t count = 0;
+ char *real_path = NULL;
+ char *entry_path = NULL;
+ char *db_path = NULL;
+ dir_entry_t entries = {0, };
+ dir_entry_t *tmp = NULL;
+ DIR *dir = NULL;
+ struct dirent *dirent = NULL;
+ struct bdb_dir *bfd = NULL;
+ struct stat db_stbuf = {0,};
+ struct stat buf = {0,};
+ DBC *cursorp = NULL;
+ size_t tmp_name_len = 0;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ bfd = bdb_extract_bfd (fd, this);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+
+ MAKE_REAL_PATH (real_path, this, bfd->path);
+ dir = bfd->dir;
+
+ while ((dirent = readdir (dir))) {
+ if (!dirent)
+ break;
+
+ if (IS_BDB_PRIVATE_FILE(dirent->d_name)) {
+ continue;
+ }
+
+ tmp_name_len = strlen (dirent->d_name);
+ if (entry_path_len < (real_path_len + 1 + (tmp_name_len) + 1)) {
+ entry_path_len = real_path_len + tmp_name_len + 1024;
+ entry_path = realloc (entry_path, entry_path_len);
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, entry_path, out);
+ }
+
+ strncpy (&entry_path[real_path_len+1], dirent->d_name,
+ tmp_name_len);
+ op_ret = stat (entry_path, &buf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ entry_path, strerror (op_errno));
+ goto out;
+ }
+
+ if ((flag == GF_GET_DIR_ONLY) &&
+ (ret != -1 && !S_ISDIR(buf.st_mode))) {
+ continue;
+ }
+
+ tmp = CALLOC (1, sizeof (*tmp));
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, tmp, out);
+
+ tmp->name = strdup (dirent->d_name);
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, dirent->d_name, out);
+
+ memcpy (&tmp->buf, &buf, sizeof (buf));
+
+ tmp->buf.st_ino = -1;
+ if (S_ISLNK(tmp->buf.st_mode)) {
+ char linkpath[ZR_PATH_MAX] = {0,};
+ ret = readlink (entry_path, linkpath, ZR_PATH_MAX);
+ if (ret != -1) {
+ linkpath[ret] = '\0';
+ tmp->link = strdup (linkpath);
+ }
+ } else {
+ tmp->link = "";
+ }
+
+ count++;
+
+ tmp->next = entries.next;
+ entries.next = tmp;
+ /* if size is 0, count can never be = size,
+ so entire dir is read */
+
+ if (count == size)
+ break;
+ }
+
+ if ((flag != GF_GET_DIR_ONLY) && (count < size)) {
+ /* read from db */
+ op_ret = bdb_cursor_open (bfd->ctx, &cursorp);
+ op_errno = EINVAL;
+ GF_VALIDATE_OR_GOTO (this->name, (op_ret == 0), out);
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this,
+ bfd->ctx->directory);
+ op_ret = lstat (db_path, &db_stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ db_path, strerror (op_errno));
+ goto out;
+ }
+
+ /* read all the entries in database, one after the other and
+ * put into dictionary */
+ while (1) {
+ DBT key = {0,}, value = {0,};
+
+ key.flags = DB_DBT_MALLOC;
+ value.flags = DB_DBT_MALLOC;
+ op_ret = bdb_cursor_get (cursorp, &key, &value,
+ DB_NEXT);
+
+ if (op_ret == DB_NOTFOUND) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "end of list of key/value pair in db"
+ " for directory: %s",
+ bfd->ctx->directory);
+ op_ret = 0;
+ op_errno = 0;
+ break;
+ } else if (op_ret != 0){
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to do cursor get for "
+ "directory %s: %s",
+ bfd->ctx->directory,
+ db_strerror (op_ret));
+ op_ret = -1;
+ op_errno = ENOENT;
+ break;
+ }
+ /* successfully read */
+ tmp = CALLOC (1, sizeof (*tmp));
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, tmp, out);
+
+ tmp->name = CALLOC (1, key.size + 1);
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, tmp->name, out);
+
+ memcpy (tmp->name, key.data, key.size);
+ tmp->buf = db_stbuf;
+ tmp->buf.st_size = bdb_db_get (bfd->ctx, NULL,
+ tmp->name, NULL,
+ 0, 0);
+ tmp->buf.st_blocks = BDB_COUNT_BLOCKS (tmp->buf.st_size, \
+ tmp->buf.st_blksize);
+ /* FIXME: wat will be the effect of this? */
+ tmp->buf.st_ino = -1;
+ count++;
+
+ tmp->next = entries.next;
+ tmp->link = "";
+ entries.next = tmp;
+ /* if size is 0, count can never be = size, so entire dir is read */
+ if (count == size)
+ break;
+
+ free (key.data);
+ } /* while(1){ } */
+ bdb_cursor_close (bfd->ctx, cursorp);
+ } else {
+ /* do nothing */
+ }
+ FREE (entry_path);
+ op_ret = 0;
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &entries, count);
-
- while (entries.next) {
- tmp = entries.next;
- entries.next = entries.next->next;
- FREE (tmp->name);
- FREE (tmp);
- }
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &entries, count);
+
+ while (entries.next) {
+ tmp = entries.next;
+ entries.next = entries.next->next;
+ FREE (tmp->name);
+ FREE (tmp);
+ }
+ return 0;
}/* bdb_getdents */
-int32_t
+int32_t
bdb_releasedir (xlator_t *this,
- fd_t *fd)
+ fd_t *fd)
{
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- struct bdb_dir *bfd = NULL;
-
- if ((bfd = bdb_extract_bfd (fd, this)) == NULL) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to extract fd data from fd=%p", fd);
- op_ret = -1;
- op_errno = EBADF;
- } else {
- if (bfd->path) {
- free (bfd->path);
- } else {
- gf_log (this->name, GF_LOG_ERROR, "bfd->path was NULL. fd=%p bfd=%p",
- fd, bfd);
- }
-
- if (bfd->dir) {
- closedir (bfd->dir);
- } else {
- gf_log (this->name,
- GF_LOG_ERROR,
- "bfd->dir is NULL.");
- }
- if (bfd->ctx) {
- bctx_unref (bfd->ctx);
- } else {
- gf_log (this->name,
- GF_LOG_ERROR,
- "bfd->ctx is NULL");
- }
- free (bfd);
- }
-
- return 0;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct bdb_dir *bfd = NULL;
+
+ if ((bfd = bdb_extract_bfd (fd, this)) == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to extract fd data from fd=%p", fd);
+ op_ret = -1;
+ op_errno = EBADF;
+ } else {
+ if (bfd->path) {
+ free (bfd->path);
+ } else {
+ gf_log (this->name, GF_LOG_ERROR, "bfd->path was NULL. fd=%p bfd=%p",
+ fd, bfd);
+ }
+
+ if (bfd->dir) {
+ closedir (bfd->dir);
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "bfd->dir is NULL.");
+ }
+ if (bfd->ctx) {
+ bctx_unref (bfd->ctx);
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "bfd->ctx is NULL");
+ }
+ free (bfd);
+ }
+
+ return 0;
}/* bdb_releasedir */
-int32_t
+int32_t
bdb_readlink (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
size_t size)
{
- char *dest = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EPERM;
- char *real_path = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- dest = alloca (size + 1);
- GF_VALIDATE_OR_GOTO (this->name, dest, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- op_ret = readlink (real_path, dest, size);
-
- if (op_ret > 0)
- dest[op_ret] = 0;
-
- op_errno = errno;
-
- if (op_ret == -1) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "readlink failed on %s: %s",
- loc->path, strerror (op_errno));
- }
+ char *dest = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ char *real_path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ dest = alloca (size + 1);
+ GF_VALIDATE_OR_GOTO (this->name, dest, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ op_ret = readlink (real_path, dest, size);
+
+ if (op_ret > 0)
+ dest[op_ret] = 0;
+
+ op_errno = errno;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "readlink failed on %s: %s",
+ loc->path, strerror (op_errno));
+ }
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, dest);
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, dest);
- return 0;
+ return 0;
}/* bdb_readlink */
-int32_t
+int32_t
bdb_mkdir (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
mode_t mode)
{
- int32_t op_ret = -1;
- int32_t ret = -1;
- int32_t op_errno = EINVAL;
- char *real_path = NULL;
- struct stat stbuf = {0, };
- bctx_t *bctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- op_ret = mkdir (real_path, mode);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to mkdir %s (%s)",
- real_path, strerror (op_errno));
- goto out;
- }
-
- op_ret = chown (real_path, frame->root->uid, frame->root->gid);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to chmod on %s (%s)",
- real_path, strerror (op_errno));
- goto err;
- }
-
- op_ret = lstat (real_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- real_path, strerror (op_errno));
- goto err;
- }
-
- bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, bctx, err);
-
- stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
-
- goto out;
+ int32_t op_ret = -1;
+ int32_t ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct stat stbuf = {0, };
+ bctx_t *bctx = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ op_ret = mkdir (real_path, mode);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to mkdir %s (%s)",
+ real_path, strerror (op_errno));
+ goto out;
+ }
+
+ op_ret = chown (real_path, frame->root->uid, frame->root->gid);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to chmod on %s (%s)",
+ real_path, strerror (op_errno));
+ goto err;
+ }
+
+ op_ret = lstat (real_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ real_path, strerror (op_errno));
+ goto err;
+ }
+
+ bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, err);
+
+ stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
+
+ goto out;
err:
- ret = rmdir (real_path);
- if (ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to rmdir the directory created (%s)",
- strerror (errno));
- }
-
-
-out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
-
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
-
- return 0;
+ ret = rmdir (real_path);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to rmdir the directory created (%s)",
+ strerror (errno));
+ }
+
+
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
+
+ return 0;
}/* bdb_mkdir */
-int32_t
+int32_t
bdb_unlink (call_frame_t *frame,
xlator_t *this,
loc_t *loc)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- bctx_t *bctx = NULL;
- char *real_path = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- bctx = bctx_parent (B_TABLE(this), loc->path);
- op_errno = ENOENT;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- op_ret = bdb_db_del (bctx, NULL, loc->path);
- if (op_ret == DB_NOTFOUND) {
- MAKE_REAL_PATH (real_path, this, loc->path);
- op_ret = unlink (real_path);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to unlink on %s (%s)",
- real_path, strerror (op_errno));
- goto out;
- }
-
- } else if (op_ret == 0) {
- op_errno = 0;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ bctx_t *bctx = NULL;
+ char *real_path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ op_errno = ENOENT;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ op_ret = bdb_db_del (bctx, NULL, loc->path);
+ if (op_ret == DB_NOTFOUND) {
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ op_ret = unlink (real_path);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to unlink on %s (%s)",
+ real_path, strerror (op_errno));
+ goto out;
+ }
+
+ } else if (op_ret == 0) {
+ op_errno = 0;
+ }
out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno);
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
+ return 0;
}/* bdb_unlink */
@@ -1698,527 +1704,526 @@ int32_t
bdb_do_rmdir (xlator_t *this,
loc_t *loc)
{
- char *real_path = NULL;
- int32_t ret = -1;
- bctx_t *bctx = NULL;
- DB_ENV *dbenv = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- dbenv = BDB_ENV(this);
- GF_VALIDATE_OR_GOTO (this->name, dbenv, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- bctx = bctx_lookup (B_TABLE(this), loc->path);
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- LOCK(&bctx->lock);
- {
- if (bctx->dbp == NULL) {
- goto unlock;
- }
-
- ret = bctx->dbp->close (bctx->dbp, 0);
- GF_VALIDATE_OR_GOTO (this->name, (ret == 0), unlock);
-
- bctx->dbp = NULL;
-
- ret = dbenv->dbremove (dbenv, NULL, bctx->db_path, NULL, 0);
- if (ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to DB_ENV->dbremove() on path %s: %s",
- loc->path, db_strerror (ret));
- }
- }
+ char *real_path = NULL;
+ int32_t ret = -1;
+ bctx_t *bctx = NULL;
+ DB_ENV *dbenv = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ dbenv = BDB_ENV(this);
+ GF_VALIDATE_OR_GOTO (this->name, dbenv, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ bctx = bctx_lookup (B_TABLE(this), loc->path);
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ LOCK(&bctx->lock);
+ {
+ if (bctx->dbp == NULL) {
+ goto unlock;
+ }
+
+ ret = bctx->dbp->close (bctx->dbp, 0);
+ GF_VALIDATE_OR_GOTO (this->name, (ret == 0), unlock);
+
+ bctx->dbp = NULL;
+
+ ret = dbenv->dbremove (dbenv, NULL, bctx->db_path, NULL, 0);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to DB_ENV->dbremove() on path %s: %s",
+ loc->path, db_strerror (ret));
+ }
+ }
unlock:
- UNLOCK(&bctx->lock);
-
- if (ret) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to remove db %s: %s", bctx->db_path, db_strerror (ret));
- ret = -1;
- goto out;
- }
- gf_log (this->name,
- GF_LOG_DEBUG,
- "removed db %s", bctx->db_path);
- ret = rmdir (real_path);
+ UNLOCK(&bctx->lock);
+
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to remove db %s: %s",
+ bctx->db_path, db_strerror (ret));
+ ret = -1;
+ goto out;
+ }
+ gf_log (this->name, GF_LOG_DEBUG,
+ "removed db %s", bctx->db_path);
+ ret = rmdir (real_path);
out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
- return ret;
+ return ret;
}
-int32_t
+int32_t
bdb_rmdir (call_frame_t *frame,
xlator_t *this,
loc_t *loc)
{
- int32_t op_ret = -1;
- int32_t op_errno = ENOTEMPTY;
-
- if (!is_dir_empty (this, loc)) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "rmdir: directory %s not empty", loc->path);
- op_errno = ENOTEMPTY;
- op_ret = -1;
- goto out;
- }
-
- op_ret = bdb_do_rmdir (this, loc);
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to bdb_do_rmdir on %s",
- loc->path);
- goto out;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = ENOTEMPTY;
+
+ if (!is_dir_empty (this, loc)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "rmdir: directory %s not empty",
+ loc->path);
+ op_errno = ENOTEMPTY;
+ op_ret = -1;
+ goto out;
+ }
+
+ op_ret = bdb_do_rmdir (this, loc);
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to bdb_do_rmdir on %s",
+ loc->path);
+ goto out;
+ }
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno);
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
+ return 0;
} /* bdb_rmdir */
-int32_t
+int32_t
bdb_symlink (call_frame_t *frame,
xlator_t *this,
const char *linkname,
loc_t *loc)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- char *real_path = NULL;
- struct stat stbuf = {0,};
- struct bdb_private *private = NULL;
- bctx_t *bctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, linkname, out);
-
- private = this->private;
- GF_VALIDATE_OR_GOTO (this->name, private, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
- op_ret = symlink (linkname, real_path);
- op_errno = errno;
- if (op_ret == 0) {
- op_ret = lstat (real_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- real_path, strerror (op_errno));
- goto err;
- }
-
- bctx = bctx_parent (B_TABLE(this), loc->path);
- GF_VALIDATE_OR_GOTO (this->name, bctx, err);
-
- stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
- stbuf.st_mode = private->symlink_mode;
-
- goto out;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct stat stbuf = {0,};
+ struct bdb_private *private = NULL;
+ bctx_t *bctx = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, linkname, out);
+
+ private = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, private, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ op_ret = symlink (linkname, real_path);
+ op_errno = errno;
+ if (op_ret == 0) {
+ op_ret = lstat (real_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ real_path, strerror (op_errno));
+ goto err;
+ }
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ GF_VALIDATE_OR_GOTO (this->name, bctx, err);
+
+ stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
+ stbuf.st_mode = private->symlink_mode;
+
+ goto out;
+ }
err:
- op_ret = unlink (real_path);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to unlink the previously created symlink (%s)",
- strerror (op_errno));
- }
- op_ret = -1;
- op_errno = ENOENT;
+ op_ret = unlink (real_path);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to unlink the previously created symlink (%s)",
+ strerror (op_errno));
+ }
+ op_ret = -1;
+ op_errno = ENOENT;
out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
- return 0;
+ return 0;
} /* bdb_symlink */
-int32_t
+int32_t
bdb_chmod (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
mode_t mode)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- char *real_path = NULL;
- struct stat stbuf = {0,};
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
- op_ret = lstat (real_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- real_path, strerror (op_errno));
- goto out;
- }
-
- /* directory or symlink */
- op_ret = chmod (real_path, mode);
- op_errno = errno;
-
-out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct stat stbuf = {0,};
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ op_ret = lstat (real_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ real_path, strerror (op_errno));
+ goto out;
+ }
+
+ /* directory or symlink */
+ op_ret = chmod (real_path, mode);
+ op_errno = errno;
+
+out:
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+
+ return 0;
}/* bdb_chmod */
-int32_t
+int32_t
bdb_chown (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
uid_t uid,
gid_t gid)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- char *real_path = NULL;
- struct stat stbuf = {0,};
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
- op_ret = lstat (real_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- real_path, strerror (op_errno));
- goto out;
- }
-
- /* directory or symlink */
- op_ret = lchown (real_path, uid, gid);
- op_errno = errno;
-out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct stat stbuf = {0,};
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ op_ret = lstat (real_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ real_path, strerror (op_errno));
+ goto out;
+ }
+
+ /* directory or symlink */
+ op_ret = lchown (real_path, uid, gid);
+ op_errno = errno;
+out:
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+
+ return 0;
}/* bdb_chown */
-int32_t
+int32_t
bdb_truncate (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
off_t offset)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- char *real_path = NULL;
- struct stat stbuf = {0,};
- char *db_path = NULL;
- bctx_t *bctx = NULL;
- char *key_string = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- bctx = bctx_parent (B_TABLE(this), loc->path);
- op_errno = ENOENT;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
- MAKE_KEY_FROM_PATH (key_string, loc->path);
-
- /* now truncate */
- MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
- op_ret = lstat (db_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- db_path, strerror (op_errno));
- goto out;
- }
-
- if (loc->inode->ino) {
- stbuf.st_ino = loc->inode->ino;
- }else {
- stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
- }
-
- op_ret = bdb_db_put (bctx, NULL, key_string, NULL, 0, 1, 0);
- if (op_ret == -1) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "failed to do bdb_db_put: %s",
- db_strerror (op_ret));
- op_ret = -1;
- op_errno = EINVAL; /* TODO: better errno */
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct stat stbuf = {0,};
+ char *db_path = NULL;
+ bctx_t *bctx = NULL;
+ char *key_string = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ op_errno = ENOENT;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+
+ /* now truncate */
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ db_path, strerror (op_errno));
+ goto out;
+ }
+
+ if (loc->inode->ino) {
+ stbuf.st_ino = loc->inode->ino;
+ }else {
+ stbuf.st_ino = bdb_inode_transform (stbuf.st_ino, bctx);
+ }
+
+ op_ret = bdb_db_put (bctx, NULL, key_string, NULL, 0, 1, 0);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to do bdb_db_put: %s",
+ db_strerror (op_ret));
+ op_ret = -1;
+ op_errno = EINVAL; /* TODO: better errno */
+ }
out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
-
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+
+ return 0;
}/* bdb_truncate */
-int32_t
+int32_t
bdb_utimens (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
struct timespec ts[2])
{
- int32_t op_ret = -1;
- int32_t op_errno = EPERM;
- char *real_path = NULL;
- struct stat stbuf = {0,};
- struct timeval tv[2] = {{0,},};
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
- op_ret = lstat (real_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- op_errno = EPERM;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- real_path, strerror (op_errno));
- goto out;
- }
-
- /* directory or symlink */
- tv[0].tv_sec = ts[0].tv_sec;
- tv[0].tv_usec = ts[0].tv_nsec / 1000;
- tv[1].tv_sec = ts[1].tv_sec;
- tv[1].tv_usec = ts[1].tv_nsec / 1000;
-
- op_ret = lutimes (real_path, tv);
- if (op_ret == -1 && errno == ENOSYS) {
- op_ret = utimes (real_path, tv);
- }
- op_errno = errno;
- if (op_ret == -1) {
- gf_log (this->name,
- GF_LOG_WARNING,
- "utimes on %s failed: %s",
- loc->path, strerror (op_errno));
- goto out;
- }
-
- op_ret = lstat (real_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- real_path, strerror (op_errno));
- goto out;
- }
-
- stbuf.st_ino = loc->inode->ino;
-
-out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
-
- return 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ char *real_path = NULL;
+ struct stat stbuf = {0,};
+ struct timeval tv[2] = {{0,},};
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ op_ret = lstat (real_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ real_path, strerror (op_errno));
+ goto out;
+ }
+
+ /* directory or symlink */
+ tv[0].tv_sec = ts[0].tv_sec;
+ tv[0].tv_usec = ts[0].tv_nsec / 1000;
+ tv[1].tv_sec = ts[1].tv_sec;
+ tv[1].tv_usec = ts[1].tv_nsec / 1000;
+
+ op_ret = lutimes (real_path, tv);
+ if (op_ret == -1 && errno == ENOSYS) {
+ op_ret = utimes (real_path, tv);
+ }
+ op_errno = errno;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "utimes on %s failed: %s",
+ loc->path, strerror (op_errno));
+ goto out;
+ }
+
+ op_ret = lstat (real_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ real_path, strerror (op_errno));
+ goto out;
+ }
+
+ stbuf.st_ino = loc->inode->ino;
+
+out:
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+
+ return 0;
}/* bdb_utimens */
-int32_t
+int32_t
bdb_statfs (call_frame_t *frame,
xlator_t *this,
loc_t *loc)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- char *real_path = NULL;
- struct statvfs buf = {0, };
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct statvfs buf = {0, };
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_REAL_PATH (real_path, this, loc->path);
- op_ret = statvfs (real_path, &buf);
- op_errno = errno;
+ op_ret = statvfs (real_path, &buf);
+ op_errno = errno;
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &buf);
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &buf);
+ return 0;
}/* bdb_statfs */
static int gf_bdb_xattr_log;
/* bdb_setxattr - set extended attributes.
*
- * bdb allows setxattr operation only on directories.
- * bdb reservers 'glusterfs.file.<attribute-name>' to operate on the content of the files
- * under the specified directory. 'glusterfs.file.<attribute-name>' transforms to contents of
- * file of name '<attribute-name>' under specified directory.
+ * bdb allows setxattr operation only on directories.
+ * bdb reservers 'glusterfs.file.<attribute-name>' to operate on the content
+ * of the files under the specified directory.
+ * 'glusterfs.file.<attribute-name>' transforms to contents of file of name
+ * '<attribute-name>' under specified directory.
*
* @frame: call frame.
* @this: xlator_t of this instance of bdb xlator.
* @loc: loc_t specifying the file to operate upon.
* @dict: list of extended attributes to set on @loc.
- * @flags: can be XATTR_REPLACE (replace an existing extended attribute only if it exists) or
- * XATTR_CREATE (create an extended attribute only if it doesn't already exist).
+ * @flags: can be XATTR_REPLACE (replace an existing extended attribute only if
+ * it exists) or XATTR_CREATE (create an extended attribute only if it
+ * doesn't already exist).
*
*
*/
-int32_t
+int32_t
bdb_setxattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
dict_t *dict,
int flags)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- data_pair_t *trav = dict->members_list;
- bctx_t *bctx = NULL;
- char *real_path = NULL;
- char *key = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
- if (!S_ISDIR (loc->inode->st_mode)) {
- op_ret = -1;
- op_errno = EPERM;
- goto out;
- }
-
- while (trav) {
- if (ZR_FILE_CONTENT_REQUEST(trav->key) ) {
- bctx = bctx_lookup (B_TABLE(this), loc->path);
- op_errno = EINVAL;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- key = &(trav->key[15]);
-
- if (flags & XATTR_REPLACE) {
- /* replace only if previously exists, otherwise error out */
- op_ret = bdb_db_get (bctx, NULL, key,
- NULL, 0, 0);
- if (op_ret == -1) {
- /* key doesn't exist in database */
- gf_log (this->name,
- GF_LOG_DEBUG,
- "cannot XATTR_REPLACE, xattr %s doesn't exist "
- "on path %s", key, loc->path);
- op_ret = -1;
- op_errno = ENOENT;
- break;
- }
- op_ret = bdb_db_put (bctx, NULL,
- key, trav->value->data,
- trav->value->len,
- op_ret, BDB_TRUNCATE_RECORD);
- if (op_ret != 0) {
- op_ret = -1;
- op_errno = EINVAL;
- break;
- }
- } else {
- /* fresh create */
- op_ret = bdb_db_put (bctx, NULL, key,
- trav->value->data,
- trav->value->len,
- 0, 0);
- if (op_ret != 0) {
- op_ret = -1;
- op_errno = EINVAL;
- break;
- } else {
- op_ret = 0;
- op_errno = 0;
- } /* if(op_ret!=0)...else */
- } /* if(flags&XATTR_REPLACE)...else */
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
- } else {
- /* do plain setxattr */
- op_ret = lsetxattr (real_path,
- trav->key,
- trav->value->data,
- trav->value->len,
- flags);
- op_errno = errno;
- if ((op_ret == -1) && (op_errno != ENOENT)) {
- if (op_errno == ENOTSUP) {
- gf_bdb_xattr_log++;
- if (!(gf_bdb_xattr_log % GF_UNIVERSAL_ANSWER)) {
- gf_log (this->name, GF_LOG_WARNING,
- "Extended Attributes support not present."\
- "Please check");
- }
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "setxattr failed on %s (%s)",
- loc->path, strerror (op_errno));
- }
- break;
- }
- } /* if(ZR_FILE_CONTENT_REQUEST())...else */
- trav = trav->next;
- }/* while(trav) */
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ data_pair_t *trav = dict->members_list;
+ bctx_t *bctx = NULL;
+ char *real_path = NULL;
+ char *key = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, dict, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ if (!S_ISDIR (loc->inode->st_mode)) {
+ op_ret = -1;
+ op_errno = EPERM;
+ goto out;
+ }
+
+ while (trav) {
+ if (ZR_FILE_CONTENT_REQUEST(trav->key) ) {
+ bctx = bctx_lookup (B_TABLE(this), loc->path);
+ op_errno = EINVAL;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ key = &(trav->key[15]);
+
+ if (flags & XATTR_REPLACE) {
+ /* replace only if previously exists, otherwise
+ * error out */
+ op_ret = bdb_db_get (bctx, NULL, key,
+ NULL, 0, 0);
+ if (op_ret == -1) {
+ /* key doesn't exist in database */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "cannot XATTR_REPLACE, xattr %s"
+ " doesn't exist on path %s",
+ key, loc->path);
+ op_ret = -1;
+ op_errno = ENOENT;
+ break;
+ }
+ op_ret = bdb_db_put (bctx, NULL,
+ key, trav->value->data,
+ trav->value->len,
+ op_ret,
+ BDB_TRUNCATE_RECORD);
+ if (op_ret != 0) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ break;
+ }
+ } else {
+ /* fresh create */
+ op_ret = bdb_db_put (bctx, NULL, key,
+ trav->value->data,
+ trav->value->len,
+ 0, 0);
+ if (op_ret != 0) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ break;
+ } else {
+ op_ret = 0;
+ op_errno = 0;
+ } /* if(op_ret!=0)...else */
+ } /* if(flags&XATTR_REPLACE)...else */
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success, see
+ * description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+ } else {
+ /* do plain setxattr */
+ op_ret = lsetxattr (real_path,
+ trav->key,
+ trav->value->data,
+ trav->value->len,
+ flags);
+ op_errno = errno;
+ if ((op_ret == -1) && (op_errno != ENOENT)) {
+ if (op_errno == ENOTSUP) {
+ gf_bdb_xattr_log++;
+ if (!(gf_bdb_xattr_log % GF_UNIVERSAL_ANSWER)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Extended Attributes support not present."\
+ "Please check");
+ }
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setxattr failed on %s (%s)",
+ loc->path, strerror (op_errno));
+ }
+ break;
+ }
+ } /* if(ZR_FILE_CONTENT_REQUEST())...else */
+ trav = trav->next;
+ }/* while(trav) */
out:
- frame->root->rsp_refs = NULL;
-
- STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
+ frame->root->rsp_refs = NULL;
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
}/* bdb_setxattr */
/* bdb_gettxattr - get extended attributes.
*
- * bdb allows getxattr operation only on directories.
- * bdb_getxattr retrieves the whole content of the file, when glusterfs.file.<attribute-name>
- * is specified.
+ * bdb allows getxattr operation only on directories.
+ * bdb_getxattr retrieves the whole content of the file, when
+ * glusterfs.file.<attribute-name> is specified.
*
* @frame: call frame.
* @this: xlator_t of this instance of bdb xlator.
@@ -2228,334 +2233,342 @@ out:
* NOTE: see description of bdb_setxattr for details on how
* 'glusterfs.file.<attribute-name>' is handles by bdb.
*/
-int32_t
+int32_t
bdb_getxattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
const char *name)
{
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- dict_t *dict = NULL;
- bctx_t *bctx = NULL;
- char *buf = NULL;
- char *key_string = NULL;
- int32_t list_offset = 0;
- size_t size = 0;
- size_t remaining_size = 0;
- char *real_path = NULL;
- char key[1024] = {0,};
- char *value = NULL;
- char *list = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, name, out);
-
- dict = get_new_dict ();
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
-
- if (!S_ISDIR (loc->inode->st_mode)) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "operation not permitted on a non-directory file: %s", loc->path);
- op_ret = -1;
- op_errno = ENODATA;
- goto out;
- }
-
- if (name && ZR_FILE_CONTENT_REQUEST(name)) {
- bctx = bctx_lookup (B_TABLE(this), loc->path);
- op_errno = EINVAL;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- key_string = (char *)&(name[15]);
-
- op_ret = bdb_db_get (bctx, NULL, key_string, &buf, 0, 0);
- if (op_ret == -1) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "failed to db get on directory: %s for key: %s",
- bctx->directory, name);
- op_ret = -1;
- op_errno = ENODATA;
- goto out;
- }
-
- dict_set (dict, (char *)name, data_from_dynptr (buf, op_ret));
- } else {
- MAKE_REAL_PATH (real_path, this, loc->path);
- size = llistxattr (real_path, NULL, 0);
- op_errno = errno;
- if (size <= 0) {
- /* There are no extended attributes, send an empty dictionary */
- if (size == -1 && op_errno != ENODATA) {
- if (op_errno == ENOTSUP) {
- gf_bdb_xattr_log++;
- if (!(gf_bdb_xattr_log % GF_UNIVERSAL_ANSWER))
- gf_log (this->name,
- GF_LOG_WARNING,
- "Extended Attributes support not present."\
- "Please check");
- } else {
- gf_log (this->name,
- GF_LOG_WARNING,
- "llistxattr failed on %s (%s)",
- loc->path, strerror (op_errno));
- }
- }
- op_ret = -1;
- op_errno = ENODATA;
- } else {
- list = alloca (size + 1);
- op_errno = ENOMEM;
- GF_VALIDATE_OR_GOTO (this->name, list, out);
-
- size = llistxattr (real_path, list, size);
- op_ret = size;
- op_errno = errno;
- if (size == -1) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "llistxattr failed on %s (%s)",
- loc->path, strerror (errno));
- goto out;
- }
- remaining_size = size;
- list_offset = 0;
- while (remaining_size > 0) {
- if(*(list+list_offset) == '\0')
- break;
- strcpy (key, list + list_offset);
- op_ret = lgetxattr (real_path, key, NULL, 0);
- if (op_ret == -1)
- break;
- value = CALLOC (op_ret + 1, sizeof(char));
- GF_VALIDATE_OR_GOTO (this->name, value, out);
-
- op_ret = lgetxattr (real_path, key, value, op_ret);
- if (op_ret == -1)
- break;
- value [op_ret] = '\0';
- dict_set (dict, key, data_from_dynptr (value, op_ret));
- remaining_size -= strlen (key) + 1;
- list_offset += strlen (key) + 1;
- } /* while(remaining_size>0) */
- } /* if(size <= 0)...else */
- } /* if(name...)...else */
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ dict_t *dict = NULL;
+ bctx_t *bctx = NULL;
+ char *buf = NULL;
+ char *key_string = NULL;
+ int32_t list_offset = 0;
+ size_t size = 0;
+ size_t remaining_size = 0;
+ char *real_path = NULL;
+ char key[1024] = {0,};
+ char *value = NULL;
+ char *list = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, name, out);
+
+ dict = get_new_dict ();
+ GF_VALIDATE_OR_GOTO (this->name, dict, out);
+
+ if (!S_ISDIR (loc->inode->st_mode)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "operation not permitted on a non-directory file: %s",
+ loc->path);
+ op_ret = -1;
+ op_errno = ENODATA;
+ goto out;
+ }
+
+ if (name && ZR_FILE_CONTENT_REQUEST(name)) {
+ bctx = bctx_lookup (B_TABLE(this), loc->path);
+ op_errno = EINVAL;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ key_string = (char *)&(name[15]);
+
+ op_ret = bdb_db_get (bctx, NULL, key_string, &buf, 0, 0);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to db get on directory: %s for key: %s",
+ bctx->directory, name);
+ op_ret = -1;
+ op_errno = ENODATA;
+ goto out;
+ }
+
+ op_ret = dict_set_dynptr (dict, (char *)name, buf, op_ret);
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set to dictionary");
+ op_ret = -1;
+ op_errno = ENODATA;
+ }
+ } else {
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ size = llistxattr (real_path, NULL, 0);
+ op_errno = errno;
+ if (size <= 0) {
+ /* There are no extended attributes, send an empty
+ * dictionary */
+ if (size == -1 && op_errno != ENODATA) {
+ if (op_errno == ENOTSUP) {
+ gf_bdb_xattr_log++;
+ if (!(gf_bdb_xattr_log % GF_UNIVERSAL_ANSWER))
+ gf_log (this->name, GF_LOG_WARNING,
+ "Extended Attributes support not present."\
+ "Please check");
+ } else {
+ gf_log (this->name, GF_LOG_WARNING,
+ "llistxattr failed on %s (%s)",
+ loc->path, strerror (op_errno));
+ }
+ }
+ op_ret = -1;
+ op_errno = ENODATA;
+ } else {
+ list = alloca (size + 1);
+ op_errno = ENOMEM;
+ GF_VALIDATE_OR_GOTO (this->name, list, out);
+
+ size = llistxattr (real_path, list, size);
+ op_ret = size;
+ op_errno = errno;
+ if (size == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "llistxattr failed on %s (%s)",
+ loc->path, strerror (errno));
+ goto out;
+ }
+ remaining_size = size;
+ list_offset = 0;
+ while (remaining_size > 0) {
+ if(*(list+list_offset) == '\0')
+ break;
+ strcpy (key, list + list_offset);
+ op_ret = lgetxattr (real_path, key, NULL, 0);
+ if (op_ret == -1)
+ break;
+ value = CALLOC (op_ret + 1, sizeof(char));
+ GF_VALIDATE_OR_GOTO (this->name, value, out);
+
+ op_ret = lgetxattr (real_path, key, value,
+ op_ret);
+ if (op_ret == -1)
+ break;
+ value [op_ret] = '\0';
+ op_ret = dict_set_dynptr (dict, key,
+ value, op_ret);
+ if (op_ret < 0) {
+ FREE (value);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "skipping key %s", key);
+ continue;
+ }
+ remaining_size -= strlen (key) + 1;
+ list_offset += strlen (key) + 1;
+ } /* while(remaining_size>0) */
+ } /* if(size <= 0)...else */
+ } /* if(name...)...else */
out:
- if(bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
+ if(bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
- if (dict)
- dict_ref (dict);
+ if (dict)
+ dict_ref (dict);
- STACK_UNWIND (frame, op_ret, op_errno, dict);
+ STACK_UNWIND (frame, op_ret, op_errno, dict);
- if (dict)
- dict_unref (dict);
-
- return 0;
+ if (dict)
+ dict_unref (dict);
+
+ return 0;
}/* bdb_getxattr */
-int32_t
+int32_t
bdb_removexattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
const char *name)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- bctx_t *bctx = NULL;
- char *real_path = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
- GF_VALIDATE_OR_GOTO (this->name, name, out);
-
- if (!S_ISDIR(loc->inode->st_mode)) {
- gf_log (this->name,
- GF_LOG_WARNING,
- "operation not permitted on non-directory files");
- op_ret = -1;
- op_errno = EPERM;
- goto out;
- }
-
- if (ZR_FILE_CONTENT_REQUEST(name)) {
- bctx = bctx_lookup (B_TABLE(this), loc->path);
- op_errno = EINVAL;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- op_ret = bdb_db_del (bctx, NULL, name);
- if (op_ret == -1) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to delete %s from db of %s directory",
- name, loc->path);
- op_errno = EINVAL; /* TODO: errno */
- goto out;
- }
- } else {
- MAKE_REAL_PATH(real_path, this, loc->path);
- op_ret = lremovexattr (real_path, name);
- op_errno = errno;
- if (op_ret == -1) {
- if (op_errno == ENOTSUP) {
- gf_bdb_xattr_log++;
- if (!(gf_bdb_xattr_log % GF_UNIVERSAL_ANSWER))
- gf_log (this->name, GF_LOG_WARNING,
- "Extended Attributes support not present."
- "Please check");
- } else {
- gf_log (this->name,
- GF_LOG_WARNING,
- "%s: %s",
- loc->path, strerror (op_errno));
- }
- } /* if(op_ret == -1) */
- } /* if (ZR_FILE_CONTENT_REQUEST(name))...else */
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ bctx_t *bctx = NULL;
+ char *real_path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, name, out);
+
+ if (!S_ISDIR(loc->inode->st_mode)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "operation not permitted on non-directory files");
+ op_ret = -1;
+ op_errno = EPERM;
+ goto out;
+ }
+
+ if (ZR_FILE_CONTENT_REQUEST(name)) {
+ bctx = bctx_lookup (B_TABLE(this), loc->path);
+ op_errno = EINVAL;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ op_ret = bdb_db_del (bctx, NULL, name);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to delete %s from db of %s directory",
+ name, loc->path);
+ op_errno = EINVAL; /* TODO: errno */
+ goto out;
+ }
+ } else {
+ MAKE_REAL_PATH(real_path, this, loc->path);
+ op_ret = lremovexattr (real_path, name);
+ op_errno = errno;
+ if (op_ret == -1) {
+ if (op_errno == ENOTSUP) {
+ gf_bdb_xattr_log++;
+ if (!(gf_bdb_xattr_log % GF_UNIVERSAL_ANSWER))
+ gf_log (this->name, GF_LOG_WARNING,
+ "Extended Attributes support not present."
+ "Please check");
+ } else {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: %s",
+ loc->path, strerror (op_errno));
+ }
+ } /* if(op_ret == -1) */
+ } /* if (ZR_FILE_CONTENT_REQUEST(name))...else */
out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
-
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
}/* bdb_removexattr */
-int32_t
+int32_t
bdb_fsyncdir (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int datasync)
+ xlator_t *this,
+ fd_t *fd,
+ int datasync)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- struct bdb_fd *bfd = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- frame->root->rsp_refs = NULL;
-
- bfd = bdb_extract_bfd (fd, this);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ struct bdb_fd *bfd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ frame->root->rsp_refs = NULL;
+
+ bfd = bdb_extract_bfd (fd, this);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
out:
- STACK_UNWIND (frame, op_ret, op_errno);
+ STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
+ return 0;
}/* bdb_fsycndir */
-int32_t
+int32_t
bdb_access (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t mask)
+ xlator_t *this,
+ loc_t *loc,
+ int32_t mask)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- char *real_path = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- op_ret = access (real_path, mask);
- op_errno = errno;
- /* TODO: implement for db entries */
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ op_ret = access (real_path, mask);
+ op_errno = errno;
+ /* TODO: implement for db entries */
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno);
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
}/* bdb_access */
-int32_t
+int32_t
bdb_ftruncate (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset)
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset)
{
- int32_t op_ret = -1;
- int32_t op_errno = EPERM;
- struct stat buf = {0,};
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- /* TODO: impelement */
-out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &buf);
-
- return 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ struct stat buf = {0,};
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+ /* TODO: impelement */
+out:
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &buf);
+
+ return 0;
}
-int32_t
+int32_t
bdb_fchown (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
uid_t uid,
gid_t gid)
{
- int32_t op_ret = -1;
- int32_t op_errno = EPERM;
- struct stat buf = {0,};
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- /* TODO: implement */
-out:
- STACK_UNWIND (frame, op_ret, op_errno, &buf);
-
- return 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ struct stat buf = {0,};
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ /* TODO: implement */
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, &buf);
+
+ return 0;
}
-int32_t
+int32_t
bdb_fchmod (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
mode_t mode)
{
- int32_t op_ret = -1;
- int32_t op_errno = EPERM;
- struct stat buf = {0,};
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- /* TODO: impelement */
-out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &buf);
-
- return 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ struct stat buf = {0,};
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ /* TODO: impelement */
+out:
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, &buf);
+
+ return 0;
}
-int32_t
+int32_t
bdb_setdents (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
@@ -2563,160 +2576,156 @@ bdb_setdents (call_frame_t *frame,
dir_entry_t *entries,
int32_t count)
{
- int32_t op_ret = -1, op_errno = EINVAL;
- char *entry_path = NULL;
- int32_t real_path_len = 0;
- int32_t entry_path_len = 0;
- int32_t ret = 0;
- struct bdb_dir *bfd = NULL;
- dir_entry_t *trav = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
- GF_VALIDATE_OR_GOTO (this->name, entries, out);
-
- frame->root->rsp_refs = NULL;
-
- bfd = bdb_extract_bfd (fd, this);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
-
- real_path_len = strlen (bfd->path);
- entry_path_len = real_path_len + 256;
- entry_path = CALLOC (1, entry_path_len);
- GF_VALIDATE_OR_GOTO (this->name, entry_path, out);
-
- strcpy (entry_path, bfd->path);
- entry_path[real_path_len] = '/';
-
- trav = entries->next;
- while (trav) {
- char pathname[ZR_PATH_MAX] = {0,};
- strcpy (pathname, entry_path);
- strcat (pathname, trav->name);
-
- if (S_ISDIR(trav->buf.st_mode)) {
- /* If the entry is directory, create it by calling 'mkdir'. If
- * directory is not present, it will be created, if its present,
- * no worries even if it fails.
- */
- ret = mkdir (pathname, trav->buf.st_mode);
- if ((ret == -1) && (errno != EEXIST)) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to created directory %s: %s",
- pathname, strerror(errno));
- goto loop;
- }
-
- gf_log (this->name,
- GF_LOG_DEBUG,
- "Creating directory %s with mode (0%o)",
- pathname,
- trav->buf.st_mode);
- /* Change the mode
- * NOTE: setdents tries its best to restore the state
- * of storage. if chmod and chown fail, they can be
- * ignored now */
- ret = chmod (pathname, trav->buf.st_mode);
- if (ret != 0) {
- op_ret = -1;
- op_errno = errno;
- gf_log (this->name,
- GF_LOG_ERROR,
- "chmod failed on %s (%s)",
- pathname, strerror (errno));
- goto loop;
- }
- /* change the ownership */
- ret = chown (pathname, trav->buf.st_uid, trav->buf.st_gid);
- if (ret != 0) {
- op_ret = -1;
- op_errno = errno;
- gf_log (this->name,
- GF_LOG_ERROR,
- "chown failed on %s (%s)",
- pathname, strerror (errno));
- goto loop;
- }
- } else if ((flags == GF_SET_IF_NOT_PRESENT) ||
- (flags != GF_SET_DIR_ONLY)) {
- /* Create a 0 byte file here */
- if (S_ISREG (trav->buf.st_mode)) {
- op_ret = bdb_db_put (bfd->ctx, NULL,
- trav->name, NULL, 0, 0, 0);
- if (op_ret != 0) {
- /* create successful */
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to create file %s",
- pathname);
- } /* if (!op_ret)...else */
- } else if (S_ISLNK (trav->buf.st_mode)) {
- /* TODO: impelement */;
- } else {
- gf_log (this->name,
- GF_LOG_ERROR,
- "storage/bdb allows to create regular files only"
- "file %s (mode = %d) cannot be created",
- pathname, trav->buf.st_mode);
- } /* if(S_ISREG())...else */
- } /* if(S_ISDIR())...else if */
- loop:
- /* consider the next entry */
- trav = trav->next;
- } /* while(trav) */
+ int32_t op_ret = -1, op_errno = EINVAL;
+ char *entry_path = NULL;
+ int32_t real_path_len = 0;
+ int32_t entry_path_len = 0;
+ int32_t ret = 0;
+ struct bdb_dir *bfd = NULL;
+ dir_entry_t *trav = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+ GF_VALIDATE_OR_GOTO (this->name, entries, out);
+
+ frame->root->rsp_refs = NULL;
+
+ bfd = bdb_extract_bfd (fd, this);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+
+ real_path_len = strlen (bfd->path);
+ entry_path_len = real_path_len + 256;
+ entry_path = CALLOC (1, entry_path_len);
+ GF_VALIDATE_OR_GOTO (this->name, entry_path, out);
+
+ strcpy (entry_path, bfd->path);
+ entry_path[real_path_len] = '/';
+
+ trav = entries->next;
+ while (trav) {
+ char pathname[ZR_PATH_MAX] = {0,};
+ strcpy (pathname, entry_path);
+ strcat (pathname, trav->name);
+
+ if (S_ISDIR(trav->buf.st_mode)) {
+ /* If the entry is directory, create it by calling
+ * 'mkdir'. If directory is not present, it will be
+ * created, if its present, no worries even if it fails.
+ */
+ ret = mkdir (pathname, trav->buf.st_mode);
+ if ((ret == -1) && (errno != EEXIST)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to created directory %s: %s",
+ pathname, strerror(errno));
+ goto loop;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Creating directory %s with mode (0%o)",
+ pathname,
+ trav->buf.st_mode);
+ /* Change the mode
+ * NOTE: setdents tries its best to restore the state
+ * of storage. if chmod and chown fail, they can
+ * be ignored now */
+ ret = chmod (pathname, trav->buf.st_mode);
+ if (ret != 0) {
+ op_ret = -1;
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "chmod failed on %s (%s)",
+ pathname, strerror (errno));
+ goto loop;
+ }
+ /* change the ownership */
+ ret = chown (pathname, trav->buf.st_uid,
+ trav->buf.st_gid);
+ if (ret != 0) {
+ op_ret = -1;
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "chown failed on %s (%s)",
+ pathname, strerror (errno));
+ goto loop;
+ }
+ } else if ((flags == GF_SET_IF_NOT_PRESENT) ||
+ (flags != GF_SET_DIR_ONLY)) {
+ /* Create a 0 byte file here */
+ if (S_ISREG (trav->buf.st_mode)) {
+ op_ret = bdb_db_put (bfd->ctx, NULL,
+ trav->name, NULL, 0, 0, 0);
+ if (op_ret != 0) {
+ /* create successful */
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to create file %s",
+ pathname);
+ } /* if (!op_ret)...else */
+ } else if (S_ISLNK (trav->buf.st_mode)) {
+ /* TODO: impelement */;
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "storage/bdb allows to create regular"
+ " files only file %s (mode = %d) cannot"
+ " be created",
+ pathname, trav->buf.st_mode);
+ } /* if(S_ISREG())...else */
+ } /* if(S_ISDIR())...else if */
+ loop:
+ /* consider the next entry */
+ trav = trav->next;
+ } /* while(trav) */
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno);
-
- FREE (entry_path);
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ FREE (entry_path);
+ return 0;
}
-int32_t
+int32_t
bdb_fstat (call_frame_t *frame,
xlator_t *this,
fd_t *fd)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- struct stat stbuf = {0,};
- struct bdb_fd *bfd = NULL;
- bctx_t *bctx = NULL;
- char *db_path = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- bfd = bdb_extract_bfd (fd, this);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
-
- bctx = bfd->ctx;
-
- MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
- op_ret = lstat (db_path, &stbuf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to lstat on %s (%s)",
- db_path, strerror (op_errno));
- goto out;
- }
-
- stbuf.st_ino = fd->inode->ino;
- stbuf.st_size = bdb_db_get (bctx, NULL, bfd->key, NULL, 0, 0);
- stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ struct stat stbuf = {0,};
+ struct bdb_fd *bfd = NULL;
+ bctx_t *bctx = NULL;
+ char *db_path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ bfd = bdb_extract_bfd (fd, this);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+
+ bctx = bfd->ctx;
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to lstat on %s (%s)",
+ db_path, strerror (op_errno));
+ goto out;
+ }
+
+ stbuf.st_ino = fd->inode->ino;
+ stbuf.st_size = bdb_db_get (bctx, NULL, bfd->key, NULL, 0, 0);
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
out:
- frame->root->rsp_refs = NULL;
+ frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
- return 0;
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+ return 0;
}
@@ -2727,392 +2736,400 @@ bdb_readdir (call_frame_t *frame,
size_t size,
off_t off)
{
- struct bdb_dir *bfd = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- size_t filled = 0;
- gf_dirent_t *this_entry = NULL;
- gf_dirent_t entries;
- struct dirent *entry = NULL;
- off_t in_case = 0;
- int32_t this_size = 0;
- DBC *cursorp = NULL;
- int32_t count = 0;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fd, out);
-
- INIT_LIST_HEAD (&entries.list);
-
- bfd = bdb_extract_bfd (fd, this);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, bfd, out);
-
- op_errno = ENOMEM;
-
- while (filled <= size) {
- this_entry = NULL;
- entry = NULL;
- in_case = 0;
- this_size = 0;
-
- in_case = telldir (bfd->dir);
- entry = readdir (bfd->dir);
- if (!entry)
- break;
-
- if (IS_BDB_PRIVATE_FILE(entry->d_name))
- continue;
-
- this_size = dirent_size (entry);
-
- if (this_size + filled > size) {
- seekdir (bfd->dir, in_case);
- break;
- }
-
- count++;
-
- this_entry = gf_dirent_for_name (entry->d_name);
- this_entry->d_ino = entry->d_ino;
-
- this_entry->d_off = -1;
-
- this_entry->d_type = entry->d_type;
- this_entry->d_len = entry->d_reclen;
-
-
- list_add (&this_entry->list, &entries.list);
-
- filled += this_size;
- }
- op_ret = filled;
- op_errno = 0;
- if (filled >= size) {
- goto out;
- }
-
- /* hungry kyaa? */
- op_ret = bdb_cursor_open (bfd->ctx, &cursorp);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, (op_ret == 0), out);
-
- /* TODO: fix d_off, don't use bfd->offset. wrong method */
- if (strlen (bfd->offset)) {
- DBT key = {0,}, value = {0,};
- key.data = bfd->offset;
- key.size = strlen (bfd->offset);
- key.flags = DB_DBT_USERMEM;
- value.dlen = 0;
- value.doff = 0;
- value.flags = DB_DBT_PARTIAL;
-
- op_ret = bdb_cursor_get (cursorp, &key, &value, DB_SET);
- op_errno = EBADFD;
- GF_VALIDATE_OR_GOTO (this->name, (op_ret == 0), out);
-
- } else {
- /* first time or last time, do nothing */
- }
-
- while (filled <= size) {
- DBT key = {0,}, value = {0,};
- this_entry = NULL;
-
- key.flags = DB_DBT_MALLOC;
- value.dlen = 0;
- value.doff = 0;
- value.flags = DB_DBT_PARTIAL;
- op_ret = bdb_cursor_get (cursorp, &key, &value, DB_NEXT);
-
- if (op_ret == DB_NOTFOUND) {
- /* we reached end of the directory */
- op_ret = 0;
- op_errno = 0;
- break;
- } else if (op_ret != 0) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "database error during readdir");
- op_ret = -1;
- op_errno = ENOENT;
- break;
- } /* if (op_ret == DB_NOTFOUND)...else if...else */
-
- if (key.data == NULL) {
- /* NOTE: currently ignore when we get key.data == NULL.
- * TODO: we should not get key.data = NULL */
- gf_log (this->name,
- GF_LOG_DEBUG,
- "null key read from db");
- continue;
- }/* if(key.data)...else */
- count++;
- this_size = bdb_dirent_size (&key);
- if (this_size + filled > size)
- break;
- /* TODO - consider endianness here */
- this_entry = gf_dirent_for_name ((const char *)key.data);
- /* FIXME: bug, if someone is going to use ->d_ino */
- this_entry->d_ino = -1;
- this_entry->d_off = 0;
- this_entry->d_type = 0;
- this_entry->d_len = key.size;
-
- if (key.data) {
- strncpy (bfd->offset, key.data, key.size);
- bfd->offset [key.size] = '\0';
- free (key.data);
- }
-
- list_add (&this_entry->list, &entries.list);
-
- filled += this_size;
- }/* while */
- bdb_cursor_close (bfd->ctx, cursorp);
- op_ret = filled;
- op_errno = 0;
+ struct bdb_dir *bfd = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ size_t filled = 0;
+ gf_dirent_t *this_entry = NULL;
+ gf_dirent_t entries;
+ struct dirent *entry = NULL;
+ off_t in_case = 0;
+ int32_t this_size = 0;
+ DBC *cursorp = NULL;
+ int32_t count = 0;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ INIT_LIST_HEAD (&entries.list);
+
+ bfd = bdb_extract_bfd (fd, this);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, bfd, out);
+
+ op_errno = ENOMEM;
+
+ while (filled <= size) {
+ this_entry = NULL;
+ entry = NULL;
+ in_case = 0;
+ this_size = 0;
+
+ in_case = telldir (bfd->dir);
+ entry = readdir (bfd->dir);
+ if (!entry)
+ break;
+
+ if (IS_BDB_PRIVATE_FILE(entry->d_name))
+ continue;
+
+ this_size = dirent_size (entry);
+
+ if (this_size + filled > size) {
+ seekdir (bfd->dir, in_case);
+ break;
+ }
+
+ count++;
+
+ this_entry = gf_dirent_for_name (entry->d_name);
+ this_entry->d_ino = entry->d_ino;
+
+ this_entry->d_off = -1;
+
+ this_entry->d_type = entry->d_type;
+ this_entry->d_len = entry->d_reclen;
+
+
+ list_add (&this_entry->list, &entries.list);
+
+ filled += this_size;
+ }
+ op_ret = filled;
+ op_errno = 0;
+ if (filled >= size) {
+ goto out;
+ }
+
+ /* hungry kyaa? */
+ op_ret = bdb_cursor_open (bfd->ctx, &cursorp);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, (op_ret == 0), out);
+
+ /* TODO: fix d_off, don't use bfd->offset. wrong method */
+ if (strlen (bfd->offset)) {
+ DBT key = {0,}, value = {0,};
+ key.data = bfd->offset;
+ key.size = strlen (bfd->offset);
+ key.flags = DB_DBT_USERMEM;
+ value.dlen = 0;
+ value.doff = 0;
+ value.flags = DB_DBT_PARTIAL;
+
+ op_ret = bdb_cursor_get (cursorp, &key, &value, DB_SET);
+ op_errno = EBADFD;
+ GF_VALIDATE_OR_GOTO (this->name, (op_ret == 0), out);
+
+ } else {
+ /* first time or last time, do nothing */
+ }
+
+ while (filled <= size) {
+ DBT key = {0,}, value = {0,};
+ this_entry = NULL;
+
+ key.flags = DB_DBT_MALLOC;
+ value.dlen = 0;
+ value.doff = 0;
+ value.flags = DB_DBT_PARTIAL;
+ op_ret = bdb_cursor_get (cursorp, &key, &value, DB_NEXT);
+
+ if (op_ret == DB_NOTFOUND) {
+ /* we reached end of the directory */
+ op_ret = 0;
+ op_errno = 0;
+ break;
+ } else if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "database error during readdir");
+ op_ret = -1;
+ op_errno = ENOENT;
+ break;
+ } /* if (op_ret == DB_NOTFOUND)...else if...else */
+
+ if (key.data == NULL) {
+ /* NOTE: currently ignore when we get key.data == NULL.
+ * TODO: we should not get key.data = NULL */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "null key read from db");
+ continue;
+ }/* if(key.data)...else */
+ count++;
+ this_size = bdb_dirent_size (&key);
+ if (this_size + filled > size)
+ break;
+ /* TODO - consider endianness here */
+ this_entry = gf_dirent_for_name ((const char *)key.data);
+ /* FIXME: bug, if someone is going to use ->d_ino */
+ this_entry->d_ino = -1;
+ this_entry->d_off = 0;
+ this_entry->d_type = 0;
+ this_entry->d_len = key.size;
+
+ if (key.data) {
+ strncpy (bfd->offset, key.data, key.size);
+ bfd->offset [key.size] = '\0';
+ free (key.data);
+ }
+
+ list_add (&this_entry->list, &entries.list);
+
+ filled += this_size;
+ }/* while */
+ bdb_cursor_close (bfd->ctx, cursorp);
+ op_ret = filled;
+ op_errno = 0;
out:
- frame->root->rsp_refs = NULL;
- gf_log (this->name,
- GF_LOG_DEBUG,
- "read %"GF_PRI_SIZET" bytes for %d entries", filled, count);
- STACK_UNWIND (frame, count, op_errno, &entries);
-
- gf_dirent_free (&entries);
-
- return 0;
+ frame->root->rsp_refs = NULL;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "read %"GF_PRI_SIZET" bytes for %d entries",
+ filled, count);
+ STACK_UNWIND (frame, count, op_errno, &entries);
+
+ gf_dirent_free (&entries);
+
+ return 0;
}
-int32_t
+int32_t
bdb_stats (call_frame_t *frame,
xlator_t *this,
int32_t flags)
{
- int32_t op_ret = 0;
- int32_t op_errno = 0;
-
- struct xlator_stats xlstats = {0, }, *stats = NULL;
- struct statvfs buf;
- struct timeval tv;
- struct bdb_private *private = NULL;
- int64_t avg_read = 0;
- int64_t avg_write = 0;
- int64_t _time_ms = 0;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
-
- private = (struct bdb_private *)(this->private);
- stats = &xlstats;
-
- op_ret = statvfs (private->export_path, &buf);
- op_errno = errno;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to statvfs on %s (%s)",
- private->export_path, strerror (op_errno));
- goto out;
- }
-
- stats->nr_files = private->stats.nr_files;
- stats->nr_clients = private->stats.nr_clients; /* client info is maintained at FSd */
- stats->free_disk = buf.f_bfree * buf.f_bsize; /* Number of Free block in the filesystem. */
- stats->total_disk_size = buf.f_blocks * buf.f_bsize; /* */
- stats->disk_usage = (buf.f_blocks - buf.f_bavail) * buf.f_bsize;
-
- /* Calculate read and write usage */
- gettimeofday (&tv, NULL);
-
- /* Read */
- _time_ms = (tv.tv_sec - private->init_time.tv_sec) * 1000 +
- ((tv.tv_usec - private->init_time.tv_usec) / 1000);
-
- avg_read = (_time_ms) ? (private->read_value / _time_ms) : 0; /* KBps */
- avg_write = (_time_ms) ? (private->write_value / _time_ms) : 0; /* KBps */
-
- _time_ms = (tv.tv_sec - private->prev_fetch_time.tv_sec) * 1000 +
- ((tv.tv_usec - private->prev_fetch_time.tv_usec) / 1000);
- if (_time_ms && ((private->interval_read / _time_ms) > private->max_read)) {
- private->max_read = (private->interval_read / _time_ms);
- }
- if (_time_ms && ((private->interval_write / _time_ms) > private->max_write)) {
- private->max_write = private->interval_write / _time_ms;
- }
-
- stats->read_usage = avg_read / private->max_read;
- stats->write_usage = avg_write / private->max_write;
-
- gettimeofday (&(private->prev_fetch_time), NULL);
- private->interval_read = 0;
- private->interval_write = 0;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ struct xlator_stats xlstats = {0, }, *stats = NULL;
+ struct statvfs buf;
+ struct timeval tv;
+ struct bdb_private *private = NULL;
+ int64_t avg_read = 0;
+ int64_t avg_write = 0;
+ int64_t _time_ms = 0;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+
+ private = (struct bdb_private *)(this->private);
+ stats = &xlstats;
+
+ op_ret = statvfs (private->export_path, &buf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to statvfs on %s (%s)",
+ private->export_path, strerror (op_errno));
+ goto out;
+ }
+
+ stats->nr_files = private->stats.nr_files;
+
+ /* client info is maintained at FSd */
+ stats->nr_clients = private->stats.nr_clients;
+
+ /* Number of Free block in the filesystem. */
+ stats->free_disk = buf.f_bfree * buf.f_bsize;
+ stats->total_disk_size = buf.f_blocks * buf.f_bsize; /* */
+ stats->disk_usage = (buf.f_blocks - buf.f_bavail) * buf.f_bsize;
+
+ /* Calculate read and write usage */
+ gettimeofday (&tv, NULL);
+
+ /* Read */
+ _time_ms = (tv.tv_sec - private->init_time.tv_sec) * 1000 +
+ ((tv.tv_usec - private->init_time.tv_usec) / 1000);
+
+ avg_read = (_time_ms) ? (private->read_value / _time_ms) : 0; /* KBps */
+ avg_write = (_time_ms) ? (private->write_value / _time_ms) : 0;
+
+ _time_ms = (tv.tv_sec - private->prev_fetch_time.tv_sec) * 1000 +
+ ((tv.tv_usec - private->prev_fetch_time.tv_usec) / 1000);
+ if (_time_ms
+ && ((private->interval_read / _time_ms) > private->max_read)) {
+ private->max_read = (private->interval_read / _time_ms);
+ }
+ if (_time_ms
+ && ((private->interval_write / _time_ms) > private->max_write)) {
+ private->max_write = private->interval_write / _time_ms;
+ }
+
+ stats->read_usage = avg_read / private->max_read;
+ stats->write_usage = avg_write / private->max_write;
+
+ gettimeofday (&(private->prev_fetch_time), NULL);
+ private->interval_read = 0;
+ private->interval_write = 0;
out:
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, stats);
- return 0;
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, stats);
+ return 0;
}
-int32_t
+int32_t
bdb_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd, struct flock *lock)
+ const char *volume, loc_t *loc, int32_t cmd, struct flock *lock)
{
frame->root->rsp_refs = NULL;
- gf_log (this->name, GF_LOG_CRITICAL,
- "\"features/posix-locks\" translator is not loaded. You need to use it for proper functioning of GlusterFS");
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "\"features/posix-locks\" translator is not loaded. "
+ "You need to use it for proper functioning of GlusterFS");
STACK_UNWIND (frame, -1, ENOSYS);
return 0;
}
-int32_t
+int32_t
bdb_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd, struct flock *lock)
+ const char *volume, fd_t *fd, int32_t cmd, struct flock *lock)
{
frame->root->rsp_refs = NULL;
- gf_log (this->name, GF_LOG_CRITICAL,
- "\"features/posix-locks\" translator is not loaded. You need to use it for proper functioning of GlusterFS");
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "\"features/posix-locks\" translator is not loaded. "
+ "You need to use it for proper functioning of GlusterFS");
STACK_UNWIND (frame, -1, ENOSYS);
return 0;
}
-int32_t
+int32_t
bdb_entrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, const char *basename,
+ const char *volume, loc_t *loc, const char *basename,
entrylk_cmd cmd, entrylk_type type)
{
frame->root->rsp_refs = NULL;
- gf_log (this->name, GF_LOG_CRITICAL,
- "\"features/posix-locks\" translator is not loaded. You need to use it for proper functioning of GlusterFS");
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "\"features/posix-locks\" translator is not loaded. "
+ "You need to use it for proper functioning of GlusterFS");
STACK_UNWIND (frame, -1, ENOSYS);
return 0;
}
-int32_t
+int32_t
bdb_fentrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, const char *basename,
+ const char *volume, fd_t *fd, const char *basename,
entrylk_cmd cmd, entrylk_type type)
{
frame->root->rsp_refs = NULL;
- gf_log (this->name, GF_LOG_CRITICAL,
- "\"features/posix-locks\" translator is not loaded. You need to use it for proper functioning of GlusterFS");
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "\"features/posix-locks\" translator is not loaded. "
+ "You need to use it for proper functioning of GlusterFS");
STACK_UNWIND (frame, -1, ENOSYS);
return 0;
}
-int32_t
+int32_t
bdb_checksum (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
int32_t flag)
{
- char *real_path = NULL;
- DIR *dir = NULL;
- struct dirent *dirent = NULL;
- uint8_t file_checksum[ZR_FILENAME_MAX] = {0,};
- uint8_t dir_checksum[ZR_FILENAME_MAX] = {0,};
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
- int32_t i = 0, length = 0;
- bctx_t *bctx = NULL;
- DBC *cursorp = NULL;
- char *data = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", frame, out);
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- {
- dir = opendir (real_path);
- op_errno = errno;
- GF_VALIDATE_OR_GOTO (this->name, dir, out);
- while ((dirent = readdir (dir))) {
- if (!dirent)
- break;
-
- if (IS_BDB_PRIVATE_FILE(dirent->d_name))
- continue;
-
- length = strlen (dirent->d_name);
- for (i = 0; i < length; i++)
- dir_checksum[i] ^= dirent->d_name[i];
- } /* while((dirent...)) */
- closedir (dir);
- }
-
- {
- bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
- op_errno = EINVAL;
- GF_VALIDATE_OR_GOTO (this->name, bctx, out);
-
- op_ret = bdb_cursor_open (bctx, &cursorp);
- op_errno = EINVAL;
- GF_VALIDATE_OR_GOTO (this->name, (op_ret == 0), out);
-
- while (1) {
- DBT key = {0,}, value = {0,};
-
- key.flags = DB_DBT_MALLOC;
- value.doff = 0;
- value.dlen = 0;
- op_ret = bdb_cursor_get (cursorp, &key, &value, DB_NEXT);
-
- if (op_ret == DB_NOTFOUND) {
- gf_log (this->name,
- GF_LOG_DEBUG,
- "end of list of key/value pair in db for "
- "directory: %s", bctx->directory);
- op_ret = 0;
- op_errno = 0;
- break;
- } else if (op_ret == 0){
- /* successfully read */
- data = key.data;
- length = key.size;
- for (i = 0; i < length; i++)
- file_checksum[i] ^= data[i];
-
- free (key.data);
- } else {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to do cursor get for directory %s: %s",
- bctx->directory, db_strerror (op_ret));
- op_ret = -1;
- op_errno = ENOENT;
- break;
- }/* if(op_ret == DB_NOTFOUND)...else if...else */
- } /* while(1) */
- bdb_cursor_close (bctx, cursorp);
- }
+ char *real_path = NULL;
+ DIR *dir = NULL;
+ struct dirent *dirent = NULL;
+ uint8_t file_checksum[ZR_FILENAME_MAX] = {0,};
+ uint8_t dir_checksum[ZR_FILENAME_MAX] = {0,};
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ int32_t i = 0, length = 0;
+ bctx_t *bctx = NULL;
+ DBC *cursorp = NULL;
+ char *data = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ {
+ dir = opendir (real_path);
+ op_errno = errno;
+ GF_VALIDATE_OR_GOTO (this->name, dir, out);
+ while ((dirent = readdir (dir))) {
+ if (!dirent)
+ break;
+
+ if (IS_BDB_PRIVATE_FILE(dirent->d_name))
+ continue;
+
+ length = strlen (dirent->d_name);
+ for (i = 0; i < length; i++)
+ dir_checksum[i] ^= dirent->d_name[i];
+ } /* while((dirent...)) */
+ closedir (dir);
+ }
+
+ {
+ bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
+ op_errno = EINVAL;
+ GF_VALIDATE_OR_GOTO (this->name, bctx, out);
+
+ op_ret = bdb_cursor_open (bctx, &cursorp);
+ op_errno = EINVAL;
+ GF_VALIDATE_OR_GOTO (this->name, (op_ret == 0), out);
+
+ while (1) {
+ DBT key = {0,}, value = {0,};
+
+ key.flags = DB_DBT_MALLOC;
+ value.doff = 0;
+ value.dlen = 0;
+ op_ret = bdb_cursor_get (cursorp, &key, &value,
+ DB_NEXT);
+
+ if (op_ret == DB_NOTFOUND) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "end of list of key/value pair in db"
+ " for directory: %s", bctx->directory);
+ op_ret = 0;
+ op_errno = 0;
+ break;
+ } else if (op_ret == 0){
+ /* successfully read */
+ data = key.data;
+ length = key.size;
+ for (i = 0; i < length; i++)
+ file_checksum[i] ^= data[i];
+
+ free (key.data);
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to do cursor get for directory"
+ " %s: %s",
+ bctx->directory, db_strerror (op_ret));
+ op_ret = -1;
+ op_errno = ENOENT;
+ break;
+ }/* if(op_ret == DB_NOTFOUND)...else if...else */
+ } /* while(1) */
+ bdb_cursor_close (bctx, cursorp);
+ }
out:
- if (bctx) {
- /* NOTE: bctx_unref always returns success,
- * see description of bctx_unref for more details */
- bctx_unref (bctx);
- }
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
- frame->root->rsp_refs = NULL;
- STACK_UNWIND (frame, op_ret, op_errno, file_checksum, dir_checksum);
+ frame->root->rsp_refs = NULL;
+ STACK_UNWIND (frame, op_ret, op_errno, file_checksum, dir_checksum);
- return 0;
+ return 0;
}
/**
@@ -3124,248 +3141,307 @@ notify (xlator_t *this,
void *data,
...)
{
- switch (event)
- {
- case GF_EVENT_PARENT_UP:
- {
- /* Tell the parent that bdb xlator is up */
- assert ((this->private != NULL) &&
- (BDB_ENV(this) != NULL));
- default_notify (this, GF_EVENT_CHILD_UP, data);
- }
- break;
- default:
- /* */
- break;
- }
- return 0;
+ switch (event)
+ {
+ case GF_EVENT_PARENT_UP:
+ {
+ /* Tell the parent that bdb xlator is up */
+ assert ((this->private != NULL) &&
+ (BDB_ENV(this) != NULL));
+ default_notify (this, GF_EVENT_CHILD_UP, data);
+ }
+ break;
+ default:
+ /* */
+ break;
+ }
+ return 0;
}
/**
- * init -
+ * init -
*/
-int32_t
+int32_t
init (xlator_t *this)
{
- int32_t ret = -1;
- struct stat buf = {0,};
- struct bdb_private *_private = NULL;
- data_t *directory = NULL;
- bctx_t *bctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("bdb", this, out);
-
- _private = CALLOC (1, sizeof (*_private));
- GF_VALIDATE_OR_GOTO (this->name, _private, out);
-
- if (this->children) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "FATAL: storage/bdb cannot have subvolumes");
- FREE (_private);
- goto out;;
- }
-
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "dangling volume. check volfile ");
- }
-
- directory = dict_get (this->options, "directory");
- if (!directory) {
- gf_log (this->name, GF_LOG_ERROR,
- "export directory not specified in volfile");
- FREE (_private);
- goto out;
- }
- umask (000); // umask `masking' is done at the client side
- /* // * No need to create directory, sys admin should do it himself
- if (mkdir (directory->data, 0777) == 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "directory specified not exists, created");
- }
- */
-
- /* Check whether the specified directory exists, if not create it. */
- ret = stat (directory->data, &buf);
- if ((ret != 0) || !S_ISDIR (buf.st_mode)) {
- gf_log (this->name, GF_LOG_ERROR,
- "specified directory '%s' doesn't exists, Exiting", directory->data);
- FREE (_private);
- goto out;
- } else {
- ret = 0;
- }
-
-
- _private->export_path = strdup (directory->data);
- _private->export_path_length = strlen (_private->export_path);
-
- {
- /* Stats related variables */
- gettimeofday (&_private->init_time, NULL);
- gettimeofday (&_private->prev_fetch_time, NULL);
- _private->max_read = 1;
- _private->max_write = 1;
- }
-
- this->private = (void *)_private;
- {
- ret = bdb_db_init (this, this->options);
-
- if (ret == -1){
- gf_log (this->name,
- GF_LOG_DEBUG,
- "failed to initialize database");
- goto out;
- } else {
- bctx = bctx_lookup (_private->b_table, "/");
- /* NOTE: we are not doing bctx_unref() for root bctx,
- * let it remain in active list forever */
- if (!bctx) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "failed to allocate memory for root (/) bctx: out of memory");
- goto out;
- } else {
- ret = 0;
- }
- }
- }
+ int32_t ret = -1;
+ struct stat buf = {0,};
+ struct bdb_private *_private = NULL;
+ char *directory = NULL;
+ bctx_t *bctx = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+
+ _private = CALLOC (1, sizeof (*_private));
+ GF_VALIDATE_OR_GOTO (this->name, _private, out);
+
+ if (this->children) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "FATAL: storage/bdb cannot have subvolumes");
+ FREE (_private);
+ goto out;;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile ");
+ }
+
+ ret = dict_get_str (this->options, "directory", &directory);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "export directory not specified in volfile");
+ FREE (_private);
+ goto out;
+ }
+ umask (000); /* umask `masking' is done at the client side */
+
+ /* Check whether the specified directory exists, if not create it. */
+ ret = stat (directory, &buf);
+ if ((ret != 0) || !S_ISDIR (buf.st_mode)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "specified directory '%s' doesn't exists, Exiting",
+ directory);
+ FREE (_private);
+ goto out;
+ } else {
+ ret = 0;
+ }
+
+
+ _private->export_path = strdup (directory);
+ _private->export_path_length = strlen (_private->export_path);
+
+ {
+ /* Stats related variables */
+ gettimeofday (&_private->init_time, NULL);
+ gettimeofday (&_private->prev_fetch_time, NULL);
+ _private->max_read = 1;
+ _private->max_write = 1;
+ }
+
+ this->private = (void *)_private;
+ {
+ ret = bdb_db_init (this, this->options);
+
+ if (ret == -1){
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to initialize database");
+ goto out;
+ } else {
+ bctx = bctx_lookup (_private->b_table, "/");
+ /* NOTE: we are not doing bctx_unref() for root bctx,
+ * let it remain in active list forever */
+ if (!bctx) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to allocate memory for root (/)"
+ " bctx: out of memory");
+ goto out;
+ } else {
+ ret = 0;
+ }
+ }
+ }
out:
- return ret;
+ return ret;
}
-void
+void
bctx_cleanup (struct list_head *head)
{
- bctx_t *trav = NULL;
- bctx_t *tmp = NULL;
- DB *storage = NULL;
-
- list_for_each_entry_safe (trav, tmp, head, list) {
- LOCK (&trav->lock);
- storage = trav->dbp;
- trav->dbp = NULL;
- list_del_init (&trav->list);
- UNLOCK (&trav->lock);
-
- if (storage) {
- storage->close (storage, 0);
- storage = NULL;
- }
- }
- return;
+ bctx_t *trav = NULL;
+ bctx_t *tmp = NULL;
+ DB *storage = NULL;
+
+ list_for_each_entry_safe (trav, tmp, head, list) {
+ LOCK (&trav->lock);
+ {
+ storage = trav->dbp;
+ trav->dbp = NULL;
+ list_del_init (&trav->list);
+ }
+ UNLOCK (&trav->lock);
+
+ if (storage) {
+ storage->close (storage, 0);
+ storage = NULL;
+ }
+ }
+ return;
}
void
fini (xlator_t *this)
{
- struct bdb_private *private = NULL;
- int32_t idx = 0;
- int32_t ret = 0;
- private = this->private;
-
- if (B_TABLE(this)) {
- /* close all the dbs from lru list */
- bctx_cleanup (&(B_TABLE(this)->b_lru));
- for (idx = 0; idx < B_TABLE(this)->hash_size; idx++)
- bctx_cleanup (&(B_TABLE(this)->b_hash[idx]));
-
- if (BDB_ENV(this)) {
- LOCK (&private->active_lock);
- private->active = 0;
- UNLOCK (&private->active_lock);
-
- ret = pthread_join (private->checkpoint_thread, NULL);
- if (ret != 0) {
- gf_log (this->name,
- GF_LOG_CRITICAL,
- "failed to join checkpoint thread");
- }
-
- /* TODO: pick each of the 'struct bctx' from private->b_hash
- * and close all the databases that are open */
- BDB_ENV(this)->close (BDB_ENV(this), 0);
- } else {
- /* impossible to reach here */
- }
-
- FREE (B_TABLE(this));
- }
- FREE (private);
- return;
+ struct bdb_private *private = NULL;
+ int32_t ret = 0;
+
+ private = this->private;
+
+ if (B_TABLE(this)) {
+ /* close all the dbs from lru list */
+ bctx_cleanup (&(B_TABLE(this)->b_lru));
+ bctx_cleanup (&(B_TABLE(this)->active));
+
+ if (BDB_ENV(this)) {
+ LOCK (&private->active_lock);
+ {
+ private->active = 0;
+ }
+ UNLOCK (&private->active_lock);
+
+ ret = pthread_join (private->checkpoint_thread, NULL);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "failed to join checkpoint thread");
+ }
+
+ BDB_ENV(this)->close (BDB_ENV(this), 0);
+ } else {
+ /* impossible to reach here */
+ }
+
+ FREE (B_TABLE(this));
+ }
+ FREE (private);
+ return;
}
struct xlator_mops mops = {
- .stats = bdb_stats,
+ .stats = bdb_stats,
};
struct xlator_fops fops = {
- .lookup = bdb_lookup,
- .stat = bdb_stat,
- .opendir = bdb_opendir,
- .readdir = bdb_readdir,
- .readlink = bdb_readlink,
- .mknod = bdb_mknod,
- .mkdir = bdb_mkdir,
- .unlink = bdb_unlink,
- .rmdir = bdb_rmdir,
- .symlink = bdb_symlink,
- .rename = bdb_rename,
- .link = bdb_link,
- .chmod = bdb_chmod,
- .chown = bdb_chown,
- .truncate = bdb_truncate,
- .utimens = bdb_utimens,
- .create = bdb_create,
- .open = bdb_open,
- .readv = bdb_readv,
- .writev = bdb_writev,
- .statfs = bdb_statfs,
- .flush = bdb_flush,
- .fsync = bdb_fsync,
- .setxattr = bdb_setxattr,
- .getxattr = bdb_getxattr,
- .removexattr = bdb_removexattr,
- .fsyncdir = bdb_fsyncdir,
- .access = bdb_access,
- .ftruncate = bdb_ftruncate,
- .fstat = bdb_fstat,
- .lk = bdb_lk,
- .inodelk = bdb_inodelk,
- .finodelk = bdb_finodelk,
- .entrylk = bdb_entrylk,
- .fentrylk = bdb_fentrylk,
- .fchown = bdb_fchown,
- .fchmod = bdb_fchmod,
- .setdents = bdb_setdents,
- .getdents = bdb_getdents,
- .checksum = bdb_checksum,
+ .lookup = bdb_lookup,
+ .stat = bdb_stat,
+ .opendir = bdb_opendir,
+ .readdir = bdb_readdir,
+ .readlink = bdb_readlink,
+ .mknod = bdb_mknod,
+ .mkdir = bdb_mkdir,
+ .unlink = bdb_unlink,
+ .rmdir = bdb_rmdir,
+ .symlink = bdb_symlink,
+ .rename = bdb_rename,
+ .link = bdb_link,
+ .chmod = bdb_chmod,
+ .chown = bdb_chown,
+ .truncate = bdb_truncate,
+ .utimens = bdb_utimens,
+ .create = bdb_create,
+ .open = bdb_open,
+ .readv = bdb_readv,
+ .writev = bdb_writev,
+ .statfs = bdb_statfs,
+ .flush = bdb_flush,
+ .fsync = bdb_fsync,
+ .setxattr = bdb_setxattr,
+ .getxattr = bdb_getxattr,
+ .removexattr = bdb_removexattr,
+ .fsyncdir = bdb_fsyncdir,
+ .access = bdb_access,
+ .ftruncate = bdb_ftruncate,
+ .fstat = bdb_fstat,
+ .lk = bdb_lk,
+ .inodelk = bdb_inodelk,
+ .finodelk = bdb_finodelk,
+ .entrylk = bdb_entrylk,
+ .fentrylk = bdb_fentrylk,
+ .fchown = bdb_fchown,
+ .fchmod = bdb_fchmod,
+ .setdents = bdb_setdents,
+ .getdents = bdb_getdents,
+ .checksum = bdb_checksum,
};
struct xlator_cbks cbks = {
- .release = bdb_release,
- .releasedir = bdb_releasedir
+ .release = bdb_release,
+ .releasedir = bdb_releasedir
};
-#if 0
+
struct volume_options options[] = {
- { "directory", GF_OPTION_TYPE_PATH, 0, },
- { "logdir", GF_OPTION_TYPE_PATH, 0, },
- { "errfile", GF_OPTION_TYPE_PATH, 0, },
- { "dir-mode", GF_OPTION_TYPE_ANY, 0, }, // base 8 number
- { "file-mode", GF_OPTION_TYPE_ANY, 0, }, // base 8 number
- { "page-size", GF_OPTION_TYPE_SIZET, -1, },
- { "lru-limit", GF_OPTION_TYPE_INT, -1, },
- { "lock-timeout", GF_OPTION_TYPE_TIME, 0, },
- { "checkpoint-timeout", GF_OPTION_TYPE_TIME, 0, },
- { "transaction-timeout", GF_OPTION_TYPE_TIME, 0, },
- { "mode", GF_OPTION_TYPE_BOOL, 0, }, // Should be 'cache' ??
- { "access-mode", GF_OPTION_TYPE_STR, 0, 0, 0, "btree"},
- { NULL, 0, }
+ { .key = { "directory" },
+ .type = GF_OPTION_TYPE_PATH,
+ .description = "export directory"
+ },
+ { .key = { "logdir" },
+ .type = GF_OPTION_TYPE_PATH,
+ .description = "directory to be used by libdb for writing"
+ "transaction logs. NOTE: in absence of 'logdir' "
+ "export directory itself will be used as 'logdir' also"
+ },
+ { .key = { "errfile" },
+ .type = GF_OPTION_TYPE_PATH,
+ .description = "path to be used for libdb error logging. "
+ "NOTE: absence of 'errfile' will disable any "
+ "error logging by libdb."
+ },
+ { .key = { "dir-mode" },
+ .type = GF_OPTION_TYPE_ANY /* base 8 number */
+ },
+ { .key = { "file-mode" },
+ .type = GF_OPTION_TYPE_ANY,
+ .description = "file mode for regular files. stat() on a regular file"
+ " returns the mode specified by this option. "
+ "NOTE: specify value in octal"
+ },
+ { .key = { "page-size" },
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = 512,
+ .max = 16384,
+ .description = "size of pages used to hold data by libdb. set it to "
+ "block size of exported filesystem for "
+ "optimal performance"
+ },
+ { .key = { "open-db-lru-limit" },
+ .type = GF_OPTION_TYPE_INT,
+ .min = 1,
+ .max = 2048,
+ .description = "maximum number of per directory databases that can "
+ "be kept open. NOTE: for _advanced_ users only."
+ },
+ { .key = { "lock-timeout" },
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 0,
+ .max = 4260000,
+ .description = "define the maximum time a lock request can "
+ "be blocked by libdb. NOTE: only for _advanced_ users."
+ " do not specify this option when not sure."
+ },
+ { .key = { "checkpoint-interval" },
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 1,
+ .max = 86400,
+ .description = "define the time interval between two consecutive "
+ "libdb checpoints. setting to lower value will leave "
+ "bdb perform slowly, but guarantees that minimum data"
+ " will be lost in case of a crash. NOTE: this option "
+ "is valid only when "
+ "'option mode=\"persistent\"' is set."
+ },
+ { .key = { "transaction-timeout" },
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 0,
+ .max = 4260000,
+ .description = "maximum time for which a transaction can block "
+ "waiting for required resources."
+ },
+ { .key = { "mode" },
+ .type = GF_OPTION_TYPE_BOOL,
+ .value = { "cache", "persistent" },
+ .description = "cache: data recovery is not guaranteed in case "
+ "of crash. persistent: data recovery is guaranteed, "
+ "since all operations are transaction protected."
+ },
+ { .key = { "access-mode" },
+ .type = GF_OPTION_TYPE_STR,
+ .value = {"btree", "hash" },
+ .description = "chose the db access method. "
+ "NOTE: for _advanced_ users. leave the choice to "
+ "glusterfs when in doubt."
+ },
+ { .key = { NULL } }
};
-
-#endif /* #if 0 */
diff --git a/xlators/storage/bdb/src/bdb.h b/xlators/storage/bdb/src/bdb.h
index f85fa4c5f85..a041d942da3 100644
--- a/xlators/storage/bdb/src/bdb.h
+++ b/xlators/storage/bdb/src/bdb.h
@@ -55,7 +55,7 @@
#include "compat.h"
#include "compat-errno.h"
-#define GLFS_BDB_STORAGE "/glusterfs_storage.db"
+#define BDB_STORAGE "/glusterfs_storage.db"
/* numbers are not so reader-friendly, so lets have ON and OFF macros */
#define ON 1
@@ -66,49 +66,58 @@
#define BDB_ENOSPC_THRESHOLD 25600
-#define BDB_DEFAULT_CHECKPOINT_TIMEOUT 30
+#define BDB_DEFAULT_CHECKPOINT_INTERVAL 30
#define BCTX_ENV(bctx) (bctx->table->dbenv)
+
+#define BDB_EXPORT_PATH_LEN(_private) \
+ (((struct bdb_private *)_private)->export_path_length)
+
+#define BDB_EXPORT_PATH(_private) \
+ (((struct bdb_private *)_private)->export_path)
/* MAKE_REAL_PATH(var,this,path)
* make the real path on the underlying file-system
*
* @var: destination to hold the real path
- * @this: pointer to xlator_t corresponding to bdb xlator
- * @path: path, as seen from mount-point
+ * @this: pointer to xlator_t corresponding to bdb xlator
+ * @path: path, as seen from mount-point
*/
-#define MAKE_REAL_PATH(var, this, path) do { \
- int base_len = ((struct bdb_private *)this->private)->export_path_length; \
- var = alloca (strlen (path) + base_len + 2); \
- strcpy (var, ((struct bdb_private *)this->private)->export_path); \
- strcpy (&var[base_len], path); \
- } while (0)
+#define MAKE_REAL_PATH(var, this, path) do { \
+ int base_len = BDB_EXPORT_PATH_LEN(this->private); \
+ var = alloca (strlen (path) + base_len + 2); \
+ strcpy (var, BDB_EXPORT_PATH(this->private)); \
+ strcpy (&var[base_len], path); \
+ } while (0)
/* MAKE_REAL_PATH_TO_STORAGE_DB(var,this,path)
* make the real path to the storage-database file on file-system
*
* @var: destination to hold the real path
- * @this: pointer to xlator_t corresponding to bdb xlator
- * @path: path of the directory, as seen from mount-point
+ * @this: pointer to xlator_t corresponding to bdb xlator
+ * @path: path of the directory, as seen from mount-point
*/
-#define MAKE_REAL_PATH_TO_STORAGE_DB(var, this, path) do { \
- int base_len = ((struct bdb_private *)this->private)->export_path_length; \
- var = alloca (strlen (path) + base_len + strlen (GLFS_BDB_STORAGE)); \
- strcpy (var, ((struct bdb_private *)this->private)->export_path); \
- strcpy (&var[base_len], path); \
- strcat (var, GLFS_BDB_STORAGE); \
- } while (0)
+#define MAKE_REAL_PATH_TO_STORAGE_DB(var, this, path) do { \
+ int base_len = BDB_EXPORT_PATH_LEN(this->private); \
+ var = alloca (strlen (path) + \
+ base_len + \
+ strlen (BDB_STORAGE)); \
+ strcpy (var, BDB_EXPORT_PATH(this->private)); \
+ strcpy (&var[base_len], path); \
+ strcat (var, BDB_STORAGE); \
+ } while (0)
/* MAKE_KEY_FROM_PATH(key,path)
- * make a 'key', which we use as key in the underlying database by using the path
+ * make a 'key', which we use as key in the underlying database by using
+ * the path
*
* @key: destination to hold the key
- * @path: path to file as seen from mount-point
+ * @path: path to file as seen from mount-point
*/
-#define MAKE_KEY_FROM_PATH(key, path) do { \
- char *tmp = alloca (strlen (path)); \
- strcpy (tmp, path); \
- key = basename (tmp); \
- }while (0);
+#define MAKE_KEY_FROM_PATH(key, path) do { \
+ char *tmp = alloca (strlen (path)); \
+ strcpy (tmp, path); \
+ key = basename (tmp); \
+ }while (0);
/* BDB_DO_LSTAT(path,stbuf,dirent)
* construct real-path to a dirent and do lstat on the real-path
@@ -117,42 +126,44 @@
* @stbuf: a 'struct stat *'
* @dirent: a 'struct dirent *'
*/
-#define BDB_DO_LSTAT(path, stbuf, dirent) do { \
- char tmp_real_path[GF_PATH_MAX]; \
- strcpy(tmp_real_path, path); \
- strcat (tmp_real_path, "/"); \
- strcat(tmp_real_path, dirent->d_name); \
- ret = lstat (tmp_real_path, stbuf); \
- } while(0);
+#define BDB_DO_LSTAT(path, stbuf, dirent) do { \
+ char tmp_real_path[GF_PATH_MAX]; \
+ strcpy(tmp_real_path, path); \
+ strcat (tmp_real_path, "/"); \
+ strcat(tmp_real_path, dirent->d_name); \
+ ret = lstat (tmp_real_path, stbuf); \
+ } while(0);
/* IS_BDB_PRIVATE_FILE(name)
- * check if a given 'name' is bdb xlator's internal file name
+ * check if a given 'name' is bdb xlator's internal file name
*
* @name: basename of a file.
*
- * bdb xlator reserves file names 'glusterfs_storage.db',
- * 'glusterfs_ns.db'(used by bdb xlator itself), 'log.*', '__db.*' (used by libdb)
+ * bdb xlator reserves file names 'glusterfs_storage.db',
+ * 'glusterfs_ns.db'(used by bdb xlator itself), 'log.*', '__db.*'
+ * (used by libdb)
*/
-#define IS_BDB_PRIVATE_FILE(name) ((!strncmp(name, "__db.", 5)) || \
+#define IS_BDB_PRIVATE_FILE(name) ((!strncmp(name, "__db.", 5)) || \
(!strcmp(name, "glusterfs_storage.db")) || \
- (!strcmp(name, "glusterfs_ns.db")) || \
+ (!strcmp(name, "glusterfs_ns.db")) || \
(!strncmp(name, "log.0000", 8)))
/* check if 'name' is '.' or '..' entry */
-#define IS_DOT_DOTDOT(name) ((!strncmp(name,".", 1)) || (!strncmp(name,"..", 2)))
+#define IS_DOT_DOTDOT(name) \
+ ((!strncmp(name,".", 1)) || (!strncmp(name,"..", 2)))
/* BDB_SET_BCTX(this,inode,bctx)
* put a stamp on inode. d00d, you are using bdb.. huhaha.
- * pointer to 'struct bdb_ctx' is stored in inode's ctx of all directories.
+ * pointer to 'struct bdb_ctx' is stored in inode's ctx of all directories.
* this will happen either in lookup() or mkdir().
*
* @this: pointer xlator_t of bdb xlator.
* @inode: inode where 'struct bdb_ctx *' has to be stored.
* @bctx: a 'struct bdb_ctx *'
*/
-#define BDB_SET_BCTX(this,inode,bctx) do{ \
- inode_ctx_put(inode, this, (uint64_t)(long)bctx); \
- }while (0);
+#define BDB_SET_BCTX(this,inode,bctx) do{ \
+ inode_ctx_put(inode, this, (uint64_t)(long)bctx); \
+ }while (0);
/* MAKE_BCTX_FROM_INODE(this,bctx,inode)
* extract bdb xlator's 'struct bdb_ctx *' from an inode's ctx.
@@ -160,18 +171,18 @@
*
* @this: pointer xlator_t of bdb xlator.
* @bctx: a 'struct bdb_ctx *'
- * @inode: inode from where 'struct bdb_ctx *' has to be extracted.
+ * @inode: inode from where 'struct bdb_ctx *' has to be extracted.
*/
-#define MAKE_BCTX_FROM_INODE(this,bctx,inode) do{ \
- uint64_t tmp_bctx = 0; \
- inode_ctx_get (inode, this, &tmp_bctx); \
- if (ret == 0) \
- bctx = (void *)(long)tmp_bctx; \
- }while (0);
+#define MAKE_BCTX_FROM_INODE(this,bctx,inode) do{ \
+ uint64_t tmp_bctx = 0; \
+ inode_ctx_get (inode, this, &tmp_bctx); \
+ if (ret == 0) \
+ bctx = (void *)(long)tmp_bctx; \
+ }while (0);
-#define BDB_SET_BFD(this,fd,bfd) do{ \
- fd_ctx_set (fd, this, (uint64_t)(long)bfd); \
- }while (0);
+#define BDB_SET_BFD(this,fd,bfd) do{ \
+ fd_ctx_set (fd, this, (uint64_t)(long)bfd); \
+ }while (0);
/* maximum number of open dbs that bdb xlator will ever have */
#define BDB_MAX_OPEN_DBS 100
@@ -188,159 +199,241 @@
#define IS_VALID_FILE_MODE(mode) (!(mode & (~RWXRWXRWX)))
#define IS_VALID_DIR_MODE(mode) (!(mode & (~(RWXRWXRWX)))
-/* maximum retries for a failed transactional operation */
+/* maximum retries for a failed transactional operation */
#define BDB_MAX_RETRIES 10
+#define BDB_LL_PAGE_SIZE_DEFAULT 4096
+#define BDB_LL_PAGE_SIZE_MIN 4096
+#define BDB_LL_PAGE_SIZE_MAX 65536
+
+#define PAGE_SIZE_IN_RANGE(_page_size) \
+ ((_page_size >= BDB_LL_PAGE_SIZE_MIN) \
+ && (table->page_size <= BDB_LL_PAGE_SIZE_MAX))
+
typedef struct bctx_table bctx_table_t;
typedef struct bdb_ctx bctx_t;
typedef struct bdb_cache bdb_cache_t;
typedef struct bdb_private bdb_private_t;
-
+
struct bctx_table {
- uint64_t dbflags; /* flags to be used for opening each database */
- uint64_t cache; /* cache: can be either ON or OFF */
- gf_lock_t lock; /* used to lock the 'struct bctx_table *' */
- gf_lock_t checkpoint_lock; /* lock for checkpointing */
- struct list_head *b_hash; /* hash table of 'struct bdb_ctx' */
- struct list_head active; /* list of active 'struct bdb_ctx' */
- struct list_head b_lru; /* lru list of inactive 'struct bdb_ctx' */
- struct list_head purge;
- uint32_t lru_limit;
- uint32_t lru_size;
- uint32_t hash_size;
- DBTYPE access_mode; /* access mode for accessing the databases,
- * can be DB_HASH, DB_BTREE */
- DB_ENV *dbenv; /* DB_ENV under which every db operation
- * is carried over */
- int32_t transaction;
- xlator_t *this;
-
- uint64_t page_size; /* page-size of DB,
- * DB->set_pagesize(), should be set before DB->open */
+ /* flags to be used for opening each database */
+ uint64_t dbflags;
+
+ /* cache: can be either ON or OFF */
+ uint64_t cache;
+
+ /* used to lock the 'struct bctx_table *' */
+ gf_lock_t lock;
+
+ /* lock for checkpointing */
+ gf_lock_t checkpoint_lock;
+
+ /* hash table of 'struct bdb_ctx' */
+ struct list_head *b_hash;
+
+ /* list of active 'struct bdb_ctx' */
+ struct list_head active;
+
+ /* lru list of inactive 'struct bdb_ctx' */
+ struct list_head b_lru;
+ struct list_head purge;
+ uint32_t lru_limit;
+ uint32_t lru_size;
+ uint32_t hash_size;
+
+ /* access mode for accessing the databases, can be DB_HASH, DB_BTREE */
+ DBTYPE access_mode;
+
+ /* DB_ENV under which every db operation is carried over */
+ DB_ENV *dbenv;
+ int32_t transaction;
+ xlator_t *this;
+
+ /* page-size of DB, DB->set_pagesize(), should be set before DB->open */
+ uint64_t page_size;
};
struct bdb_ctx {
- /* controller members */
- struct list_head list; /* lru list of 'struct bdb_ctx's,
- * a bdb_ctx can exist in one of b_hash or lru lists */
- struct list_head b_hash; /* directory 'name' hashed list of 'struct bdb_ctx's */
+ /* controller members */
+
+ /* lru list of 'struct bdb_ctx's, a bdb_ctx can exist in one of
+ * b_hash or lru lists */
+ struct list_head list;
- struct bctx_table *table;
- int32_t ref; /* reference count */
- gf_lock_t lock; /* used to lock this 'struct bdb_ctx' */
+ /* directory 'name' hashed list of 'struct bdb_ctx's */
+ struct list_head b_hash;
- char *directory; /* directory path */
- DB *dbp; /* pointer to open database, that resides inside this directory */
- uint32_t cache; /* cache ON or OFF */
+ struct bctx_table *table;
+ int32_t ref; /* reference count */
+ gf_lock_t lock; /* used to lock this 'struct bdb_ctx' */
- /* per directory cache, bdb xlator's internal cache */
- struct list_head c_list; /* linked list of cached records */
- int32_t c_count; /* number of cached records */
+ char *directory; /* directory path */
- int32_t key_hash; /* index to hash table list, to which this ctx belongs */
- char *db_path; /* absolute path to db file */
+ /* pointer to open database, that resides inside this directory */
+ DB *dbp;
+ uint32_t cache; /* cache ON or OFF */
+
+ /* per directory cache, bdb xlator's internal cache */
+ struct list_head c_list; /* linked list of cached records */
+ int32_t c_count; /* number of cached records */
+
+ /* index to hash table list, to which this ctx belongs */
+ int32_t key_hash;
+ char *db_path; /* absolute path to db file */
};
struct bdb_fd {
- struct bdb_ctx *ctx; /* pointer to bdb_ctx of the parent directory */
- char *key; /* name of the file. NOTE: basename, not the complete path */
- int32_t flags; /* open flags */
+ /* pointer to bdb_ctx of the parent directory */
+ struct bdb_ctx *ctx;
+
+ /* name of the file. NOTE: basename, not the complete path */
+ char *key;
+ int32_t flags; /* open flags */
};
struct bdb_dir {
- struct bdb_ctx *ctx; /* pointer to bdb_ctx of this directory */
- DIR *dir; /* open directory pointer, as returned by opendir() */
- char offset[NAME_MAX]; /* FIXME: readdir offset, too crude. must go */
- char *path; /* path to this directory */
+ /* pointer to bdb_ctx of this directory */
+ struct bdb_ctx *ctx;
+
+ /* open directory pointer, as returned by opendir() */
+ DIR *dir;
+
+ /* FIXME: readdir offset, too crude. must go */
+ char offset[NAME_MAX];
+ char *path; /* path to this directory */
};
/* cache */
struct bdb_cache {
- struct list_head c_list; /* list of 'struct bdb_cache' under a 'struct bdb_ctx' */
- char *key; /* name of the file this cache holds. NOTE: basename of file */
- char *data; /* file content */
- size_t size; /* size of the file content that this cache holds */
+ /* list of 'struct bdb_cache' under a 'struct bdb_ctx' */
+ struct list_head c_list;
+
+ /* name of the file this cache holds. NOTE: basename of file */
+ char *key;
+ char *data; /* file content */
+
+ /* size of the file content that this cache holds */
+ size_t size;
};
struct bdb_private {
- inode_table_t *itable; /* pointer to inode table that we use */
- int32_t temp; /**/
- char is_stateless; /**/
- char *export_path; /* path to the export directory
- * (option directory <export-path>) */
- int32_t export_path_length; /* length of 'export_path' string */
-
- /* statistics */
- struct xlator_stats stats; /* Statistics, provides activity of the server */
-
- struct timeval prev_fetch_time;
- struct timeval init_time;
- int32_t max_read; /* */
- int32_t max_write; /* */
- int64_t interval_read; /* Used to calculate the max_read value */
- int64_t interval_write; /* Used to calculate the max_write value */
- int64_t read_value; /* Total read, from init */
- int64_t write_value; /* Total write, from init */
-
- /* bdb xlator specific private data */
- uint64_t envflags; /* flags used for opening DB_ENV for this xlator */
- uint64_t dbflags; /* flags to be used for opening each database */
- uint64_t cache; /* cache: can be either ON or OFF */
- uint32_t transaction; /* transaction: can be either ON or OFF */
- uint32_t active;
- gf_lock_t active_lock;
- struct bctx_table *b_table;
- DBTYPE access_mode; /* access mode for accessing the databases,
- * can be DB_HASH, DB_BTREE
- * (option access-mode <mode>) */
- mode_t file_mode; /* mode for each and every file stored on bdb
- * (option file-mode <mode>) */
- mode_t dir_mode; /* mode for each and every directory stored on bdb
- * (option dir-mode <mode>) */
- mode_t symlink_mode; /* mode for each and every symlink stored on bdb */
- pthread_t checkpoint_thread; /* pthread_t object used for creating checkpoint
- * thread */
- int32_t checkpoint_timeout; /* time duration between two consecutive checkpoint
- * operations.
- * (option checkpoint-timeout <time-in-seconds>) */
- ino_t next_ino; /* inode number allocation counter */
- gf_lock_t ino_lock; /* lock to protect 'next_ino' */
- char *logdir; /* environment log directory
- * (option logdir <directory>) */
- char *errfile; /* errfile path, used by environment to
- * print detailed error log.
- * (option errfile <errfile-path>) */
- FILE *errfp; /* DB_ENV->set_errfile() expects us to fopen
- * the errfile before doing DB_ENV->set_errfile() */
- uint32_t txn_timeout; /* used by DB_ENV->set_timeout to set the timeout for
- * a transactionally encapsulated DB->operation() to
- * timeout before waiting for locks to be released.
- * (option transaction-timeout <time-in-milliseconds>)
- */
- uint32_t lock_timeout;
- uint32_t log_auto_remove; /* DB_AUTO_LOG_REMOVE flag for DB_ENV*/
- uint32_t log_region_max;
+ /* pointer to inode table that we use */
+ inode_table_t *itable;
+ int32_t temp; /**/
+ char is_stateless; /**/
+
+ /* path to the export directory
+ * (option directory <export-path>) */
+ char *export_path;
+
+ /* length of 'export_path' string */
+ int32_t export_path_length;
+
+ /* statistics */
+ /* Statistics, provides activity of the server */
+ struct xlator_stats stats;
+
+ struct timeval prev_fetch_time;
+ struct timeval init_time;
+ int32_t max_read; /* */
+ int32_t max_write; /* */
+
+ /* Used to calculate the max_read value */
+ int64_t interval_read;
+
+ /* Used to calculate the max_write value */
+ int64_t interval_write;
+ int64_t read_value; /* Total read, from init */
+ int64_t write_value; /* Total write, from init */
+
+ /* bdb xlator specific private data */
+
+ /* flags used for opening DB_ENV for this xlator */
+ uint64_t envflags;
+
+ /* flags to be used for opening each database */
+ uint64_t dbflags;
+
+ /* cache: can be either ON or OFF */
+ uint64_t cache;
+
+ /* transaction: can be either ON or OFF */
+ uint32_t transaction;
+ uint32_t active;
+ gf_lock_t active_lock;
+ struct bctx_table *b_table;
+
+ /* access mode for accessing the databases, can be DB_HASH, DB_BTREE
+ * (option access-mode <mode>) */
+ DBTYPE access_mode;
+
+ /* mode for each and every file stored on bdb
+ * (option file-mode <mode>) */
+ mode_t file_mode;
+
+ /* mode for each and every directory stored on bdb
+ * (option dir-mode <mode>) */
+ mode_t dir_mode;
+
+ /* mode for each and every symlink stored on bdb */
+ mode_t symlink_mode;
+
+ /* pthread_t object used for creating checkpoint thread */
+ pthread_t checkpoint_thread;
+
+ /* time duration between two consecutive checkpoint operations.
+ * (option checkpoint-interval <time-in-seconds>) */
+ uint32_t checkpoint_interval;
+
+ /* inode number allocation counter */
+ ino_t next_ino;
+
+ /* lock to protect 'next_ino' */
+ gf_lock_t ino_lock;
+
+ /* environment log directory (option logdir <directory>) */
+ char *logdir;
+
+ /* errfile path, used by environment to print detailed error log.
+ * (option errfile <errfile-path>) */
+ char *errfile;
+
+ /* DB_ENV->set_errfile() expects us to fopen
+ * the errfile before doing DB_ENV->set_errfile() */
+ FILE *errfp;
+
+ /* used by DB_ENV->set_timeout to set the timeout for
+ * a transactionally encapsulated DB->operation() to
+ * timeout before waiting for locks to be released.
+ * (option transaction-timeout <time-in-milliseconds>)
+ */
+ uint32_t txn_timeout;
+ uint32_t lock_timeout;
+
+ /* DB_AUTO_LOG_REMOVE flag for DB_ENV*/
+ uint32_t log_auto_remove;
+ uint32_t log_region_max;
};
-static inline int32_t
+static inline int32_t
bdb_txn_begin (DB_ENV *dbenv,
- DB_TXN **ptxnid)
+ DB_TXN **ptxnid)
{
- return dbenv->txn_begin (dbenv, NULL, ptxnid, 0);
+ return dbenv->txn_begin (dbenv, NULL, ptxnid, 0);
}
static inline int32_t
bdb_txn_abort (DB_TXN *txnid)
{
- return txnid->abort (txnid);
+ return txnid->abort (txnid);
}
static inline int32_t
bdb_txn_commit (DB_TXN *txnid)
{
- return txnid->commit (txnid, 0);
+ return txnid->commit (txnid, 0);
}
inline void *
@@ -348,53 +441,53 @@ bdb_extract_bfd (fd_t *fd, xlator_t *this);
void *
-bdb_db_stat (bctx_t *bctx,
- DB_TXN *txnid,
- uint32_t flags);
+bdb_db_stat (bctx_t *bctx,
+ DB_TXN *txnid,
+ uint32_t flags);
int32_t
bdb_db_get(struct bdb_ctx *bctx,
- DB_TXN *txnid,
- const char *key_string,
- char **buf,
- size_t size,
- off_t offset);
+ DB_TXN *txnid,
+ const char *key_string,
+ char **buf,
+ size_t size,
+ off_t offset);
#define BDB_TRUNCATE_RECORD 0xcafebabe
int32_t
bdb_db_put (struct bdb_ctx *bctx,
- DB_TXN *txnid,
- const char *key_string,
- const char *buf,
- size_t size,
- off_t offset,
- int32_t flags);
+ DB_TXN *txnid,
+ const char *key_string,
+ const char *buf,
+ size_t size,
+ off_t offset,
+ int32_t flags);
int32_t
bdb_db_del (struct bdb_ctx *bctx,
- DB_TXN *txnid,
- const char *path);
+ DB_TXN *txnid,
+ const char *path);
ino_t
bdb_inode_transform (ino_t parent,
- struct bdb_ctx *bctx);
+ struct bdb_ctx *bctx);
int32_t
bdb_cursor_open (struct bdb_ctx *bctx,
- DBC **cursorp);
+ DBC **cursorp);
int32_t
bdb_cursor_get (DBC *cursorp,
- DBT *key,
- DBT *value,
- int32_t flags);
+ DBT *key,
+ DBT *value,
+ int32_t flags);
int32_t
bdb_cursor_close (struct bdb_ctx *ctx,
- DBC *cursorp);
+ DBC *cursorp);
int32_t
@@ -405,17 +498,17 @@ dirent_size (struct dirent *entry);
int
bdb_db_init (xlator_t *this,
- dict_t *options);
+ dict_t *options);
void
bdb_dbs_from_dict_close (dict_t *this,
- char *key,
- data_t *value,
- void *data);
+ char *key,
+ data_t *value,
+ void *data);
bctx_t *
bctx_lookup (struct bctx_table *table,
- const char *path);
+ const char *path);
bctx_t *
bctx_parent
@@ -429,11 +522,11 @@ bctx_t *
bctx_ref (bctx_t *ctx);
bctx_t *
-bctx_rename (bctx_t *bctx,
- const char *db_newpath);
+bctx_rename (bctx_t *bctx,
+ const char *db_newpath);
int32_t
-bdb_db_rename (bctx_table_t *table,
- const char *tmp_db_newpath,
- const char *real_db_newpath);
+bdb_db_rename (bctx_table_t *table,
+ const char *tmp_db_newpath,
+ const char *real_db_newpath);
#endif /* _BDB_H */