summaryrefslogtreecommitdiffstats
path: root/xlators/storage/bdb/src/bdb-ll.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage/bdb/src/bdb-ll.c')
-rw-r--r--xlators/storage/bdb/src/bdb-ll.c175
1 files changed, 98 insertions, 77 deletions
diff --git a/xlators/storage/bdb/src/bdb-ll.c b/xlators/storage/bdb/src/bdb-ll.c
index 6c9aa56be22..04cdbfbb3cf 100644
--- a/xlators/storage/bdb/src/bdb-ll.c
+++ b/xlators/storage/bdb/src/bdb-ll.c
@@ -472,7 +472,7 @@ static int32_t
bdb_db_get (bctx_t *bctx,
DB_TXN *txnid,
const char *path,
- char **buf,
+ char *buf,
size_t size,
off_t offset)
{
@@ -480,6 +480,7 @@ bdb_db_get (bctx_t *bctx,
DBT key = {0,};
DBT value = {0,};
int32_t ret = -1;
+ size_t copy_size = 0;
char *key_string = NULL;
bdb_cache_t *bcache = NULL;
int32_t db_flags = 0;
@@ -494,104 +495,124 @@ bdb_db_get (bctx_t *bctx,
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->primary == NULL) {
- ret = bdb_db_open (bctx);
- storage = bctx->primary;
- } else {
- /* we are just fine, lets continue */
- storage = bctx->primary;
- } /* if(bctx->dbp==NULL)...else */
+ copy_size = ((bcache->size - offset) < size)?
+ (bcache->size - offset) : size;
+
+ memcpy (buf, (bcache->data + offset), copy_size);
+ ret = copy_size;
+ } else {
+ ret = bcache->size;
}
- UNLOCK (&bctx->lock);
+
+ goto out;
+ }
- GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
+ LOCK (&bctx->lock);
+ {
+ if (bctx->primary == NULL) {
+ ret = bdb_db_open (bctx);
+ storage = bctx->primary;
+ } else {
+ /* we are just fine, lets continue */
+ storage = bctx->primary;
+ } /* if(bctx->dbp==NULL)...else */
+ }
+ UNLOCK (&bctx->lock);
- key.data = (char *)key_string;
- key.size = strlen (key_string);
- key.flags = DB_DBT_USERMEM;
+ GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
- if (bctx->cache){
- /* we are called to return the size of the file */
- value.flags = DB_DBT_MALLOC;
+ key.data = (char *)key_string;
+ key.size = strlen (key_string);
+ key.flags = DB_DBT_USERMEM;
+
+ if (bctx->cache){
+ value.flags = DB_DBT_MALLOC;
+ } else {
+ if (size) {
+ value.flags = DB_DBT_MALLOC | DB_DBT_PARTIAL;
} else {
- if (size) {
- value.flags = DB_DBT_MALLOC | DB_DBT_PARTIAL;
- } else {
- value.flags = DB_DBT_MALLOC;
- }
- value.dlen = size;
- value.doff = offset;
+ 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);
+ 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,
- "_BDB_DB_GET %s - %s: ENOENT"
- "(specified key not found in database)",
- bctx->directory, key_string);
- ret = -1;
- need_break = 1;
- } else if (ret == DB_LOCK_DEADLOCK) {
- retries++;
- gf_log ("bdb-ll", GF_LOG_DEBUG,
- "_BDB_DB_GET %s - %s"
- "(deadlock detected, retrying for %d "
- "time)",
- bctx->directory, key_string, retries);
- } else if (ret == 0) {
- /* successfully read data, lets set everything
- * in place and return */
- if (buf) {
- *buf = CALLOC (1, value.size);
- GF_VALIDATE_OR_GOTO ("bdb-ll",
- *buf, out);
- memcpy (*buf, value.data, value.size);
- }
- ret = value.size;
- if (bctx->cache)
- bdb_cache_insert (bctx, &key, &value);
- free (value.data);
- need_break = 1;
+ if (ret == DB_NOTFOUND) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_GET %s - %s: ENOENT"
+ "(specified key not found in database)",
+ bctx->directory, key_string);
+ ret = -1;
+ need_break = 1;
+ } else if (ret == DB_LOCK_DEADLOCK) {
+ retries++;
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_GET %s - %s"
+ "(deadlock detected, retrying for %d "
+ "time)",
+ bctx->directory, key_string, retries);
+ } else if (ret == 0) {
+ /* successfully read data, lets set everything
+ * in place and return */
+ if (buf) {
+ copy_size = ((value.size - offset) < size) ?
+ (value.size - offset) : size;
+
+ memcpy (buf, (value.data + offset), copy_size);
+ ret = copy_size;
} else {
- gf_log ("bdb-ll", GF_LOG_DEBUG,
- "_BDB_DB_GET %s - %s: %s"
- "(failed to retrieve specified key from"
- " database)",
- bctx->directory, key_string,
- db_strerror (ret));
- ret = -1;
- need_break = 1;
+ ret = value.size;
}
- } while (!need_break);
- }
+ if (bctx->cache)
+ bdb_cache_insert (bctx, &key, &value);
+ free (value.data);
+ need_break = 1;
+ } else {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_GET %s - %s: %s"
+ "(failed to retrieve specified key from"
+ " database)",
+ bctx->directory, key_string,
+ db_strerror (ret));
+ ret = -1;
+ need_break = 1;
+ }
+ } while (!need_break);
+
out:
return ret;
}/* bdb_db_get */
/* TODO: handle errors here and log. propogate only the errno to caller */
int32_t
-bdb_db_fread (struct bdb_fd *bfd, char **buf, size_t size, off_t offset)
+bdb_db_fread (struct bdb_fd *bfd, char *buf, size_t size, off_t offset)
{
return bdb_db_get (bfd->ctx, NULL, bfd->key, buf, size, offset);
}
int32_t
-bdb_db_iread (struct bdb_ctx *bctx, const char *key, char **buf)
+bdb_db_iread (struct bdb_ctx *bctx, const char *key, char **bufp)
{
- return bdb_db_get (bctx, NULL, key, buf, 0, 0);
+ char *buf = NULL;
+ size_t size = 0;
+ int64_t ret = 0;
+
+ ret = bdb_db_get (bctx, NULL, key, NULL, 0, 0);
+ size = ret;
+
+ if (bufp) {
+ buf = calloc (size, sizeof (char));
+ *bufp = buf;
+ ret = bdb_db_get (bctx, NULL, key, buf, size, 0);
+ }
+
+ return ret;
}
/* bdb_storage_put - insert a key/value specified to the corresponding DB.