]> git.ozlabs.org Git - ccan/blobdiff - ccan/tdb2/free.c
tdb2: rework lock.c functions to return enum TDB_ERROR.
[ccan] / ccan / tdb2 / free.c
index ba14dfcd70747b8ad6789ba08487d30b91cbc6fc..bface0a319fb94504059160ed9247db493e16e9f 100644 (file)
@@ -1,7 +1,7 @@
- /* 
+ /*
    Trivial Database 2: free list/block handling
    Copyright (C) Rusty Russell 2010
    Trivial Database 2: free list/block handling
    Copyright (C) Rusty Russell 2010
-   
+
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
@@ -118,7 +118,7 @@ static int remove_from_list(struct tdb_context *tdb,
 
 #ifdef CCAN_TDB2_DEBUG
        if (tdb_read_off(tdb, off) != r_off) {
 
 #ifdef CCAN_TDB2_DEBUG
        if (tdb_read_off(tdb, off) != r_off) {
-               tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_DEBUG_FATAL,
+               tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
                         "remove_from_list: %llu bad prev in list %llu",
                         (long long)r_off, (long long)b_off);
                return -1;
                         "remove_from_list: %llu bad prev in list %llu",
                         (long long)r_off, (long long)b_off);
                return -1;
@@ -136,7 +136,7 @@ static int remove_from_list(struct tdb_context *tdb,
 
 #ifdef CCAN_TDB2_DEBUG
                if (tdb_read_off(tdb, off) & TDB_OFF_MASK != r_off) {
 
 #ifdef CCAN_TDB2_DEBUG
                if (tdb_read_off(tdb, off) & TDB_OFF_MASK != r_off) {
-                       tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_DEBUG_FATAL,
+                       tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
                                   "remove_from_list: %llu bad list %llu",
                                   (long long)r_off, (long long)b_off);
                        return -1;
                                   "remove_from_list: %llu bad list %llu",
                                   (long long)r_off, (long long)b_off);
                        return -1;
@@ -176,7 +176,7 @@ static int enqueue_in_free(struct tdb_context *tdb,
                                 new.next + offsetof(struct tdb_free_record,
                                                     magic_and_prev))
                    != magic) {
                                 new.next + offsetof(struct tdb_free_record,
                                                     magic_and_prev))
                    != magic) {
-                       tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_DEBUG_FATAL,
+                       tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
                                   "enqueue_in_free: %llu bad head"
                                   " prev %llu",
                                   (long long)new.next, (long long)b_off);
                                   "enqueue_in_free: %llu bad head"
                                   " prev %llu",
                                   (long long)new.next, (long long)b_off);
@@ -204,14 +204,18 @@ int add_free_record(struct tdb_context *tdb,
        tdb_off_t b_off;
        tdb_len_t len;
        int ret;
        tdb_off_t b_off;
        tdb_len_t len;
        int ret;
+       enum TDB_ERROR ecode;
 
        assert(len_with_header >= sizeof(struct tdb_free_record));
 
        len = len_with_header - sizeof(struct tdb_used_record);
 
        b_off = bucket_off(tdb->ftable_off, size_to_bucket(len));
 
        assert(len_with_header >= sizeof(struct tdb_free_record));
 
        len = len_with_header - sizeof(struct tdb_used_record);
 
        b_off = bucket_off(tdb->ftable_off, size_to_bucket(len));
-       if (tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) != 0)
+       ecode = tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT);
+       if (ecode != TDB_SUCCESS) {
+               tdb->ecode = ecode;
                return -1;
                return -1;
+       }
 
        ret = enqueue_in_free(tdb, b_off, off, len);
        tdb_unlock_free_bucket(tdb, b_off);
 
        ret = enqueue_in_free(tdb, b_off, off, len);
        tdb_unlock_free_bucket(tdb, b_off);
@@ -290,7 +294,8 @@ static int coalesce(struct tdb_context *tdb,
                tdb_access_release(tdb, r);
 
                /* We may be violating lock order here, so best effort. */
                tdb_access_release(tdb, r);
 
                /* We may be violating lock order here, so best effort. */
-               if (tdb_lock_free_bucket(tdb, nb_off, TDB_LOCK_NOWAIT) == -1) {
+               if (tdb_lock_free_bucket(tdb, nb_off, TDB_LOCK_NOWAIT)
+                   != TDB_SUCCESS) {
                        add_stat(tdb, alloc_coalesce_lockfail, 1);
                        break;
                }
                        add_stat(tdb, alloc_coalesce_lockfail, 1);
                        break;
                }
@@ -333,7 +338,7 @@ static int coalesce(struct tdb_context *tdb,
                goto err;
 
        if (frec_len(&rec) != data_len) {
                goto err;
 
        if (frec_len(&rec) != data_len) {
-               tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_DEBUG_FATAL,
+               tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
                           "coalesce: expected data len %zu not %zu",
                           (size_t)data_len, (size_t)frec_len(&rec));
                goto err;
                           "coalesce: expected data len %zu not %zu",
                           (size_t)data_len, (size_t)frec_len(&rec));
                goto err;
@@ -377,6 +382,7 @@ static tdb_off_t lock_and_alloc(struct tdb_context *tdb,
        struct tdb_free_record best = { 0 };
        double multiplier;
        size_t size = adjust_size(keylen, datalen);
        struct tdb_free_record best = { 0 };
        double multiplier;
        size_t size = adjust_size(keylen, datalen);
+       enum TDB_ERROR ecode;
 
        add_stat(tdb, allocs, 1);
 again:
 
        add_stat(tdb, allocs, 1);
 again:
@@ -384,7 +390,9 @@ again:
 
        /* FIXME: Try non-blocking wait first, to measure contention. */
        /* Lock this bucket. */
 
        /* FIXME: Try non-blocking wait first, to measure contention. */
        /* Lock this bucket. */
-       if (tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == -1) {
+       ecode = tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT);
+       if (ecode != TDB_SUCCESS) {
+               tdb->ecode = ecode;
                return TDB_OFF_ERR;
        }
 
                return TDB_OFF_ERR;
        }
 
@@ -414,7 +422,7 @@ again:
 
                if (frec_magic(r) != TDB_FREE_MAGIC) {
                        tdb_access_release(tdb, r);
 
                if (frec_magic(r) != TDB_FREE_MAGIC) {
                        tdb_access_release(tdb, r);
-                       tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_DEBUG_FATAL,
+                       tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
                                 "lock_and_alloc: %llu non-free 0x%llx",
                                 (long long)off, (long long)r->magic_and_prev);
                        goto unlock_err;
                                 "lock_and_alloc: %llu non-free 0x%llx",
                                 (long long)off, (long long)r->magic_and_prev);
                        goto unlock_err;
@@ -567,7 +575,7 @@ int set_header(struct tdb_context *tdb,
        if (rec_key_length(rec) != keylen
            || rec_data_length(rec) != datalen
            || rec_extra_padding(rec) != actuallen - (keylen + datalen)) {
        if (rec_key_length(rec) != keylen
            || rec_data_length(rec) != datalen
            || rec_extra_padding(rec) != actuallen - (keylen + datalen)) {
-               tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_ERROR,
+               tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR,
                         "Could not encode k=%llu,d=%llu,a=%llu",
                         (long long)keylen, (long long)datalen,
                         (long long)actuallen);
                         "Could not encode k=%llu,d=%llu,a=%llu",
                         (long long)keylen, (long long)datalen,
                         (long long)actuallen);
@@ -581,6 +589,7 @@ static int tdb_expand(struct tdb_context *tdb, tdb_len_t size)
 {
        uint64_t old_size;
        tdb_len_t wanted;
 {
        uint64_t old_size;
        tdb_len_t wanted;
+       enum TDB_ERROR ecode;
 
        /* We need room for the record header too. */
        wanted = sizeof(struct tdb_used_record) + size;
 
        /* We need room for the record header too. */
        wanted = sizeof(struct tdb_used_record) + size;
@@ -588,7 +597,7 @@ static int tdb_expand(struct tdb_context *tdb, tdb_len_t size)
        /* Need to hold a hash lock to expand DB: transactions rely on it. */
        if (!(tdb->flags & TDB_NOLOCK)
            && !tdb->allrecord_lock.count && !tdb_has_hash_locks(tdb)) {
        /* Need to hold a hash lock to expand DB: transactions rely on it. */
        if (!(tdb->flags & TDB_NOLOCK)
            && !tdb->allrecord_lock.count && !tdb_has_hash_locks(tdb)) {
-               tdb_logerr(tdb, TDB_ERR_LOCK, TDB_DEBUG_ERROR,
+               tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR,
                           "tdb_expand: must hold lock during expand");
                return -1;
        }
                           "tdb_expand: must hold lock during expand");
                return -1;
        }
@@ -602,8 +611,11 @@ static int tdb_expand(struct tdb_context *tdb, tdb_len_t size)
        wanted = adjust_size(0, wanted);
 
        /* Only one person can expand file at a time. */
        wanted = adjust_size(0, wanted);
 
        /* Only one person can expand file at a time. */
-       if (tdb_lock_expand(tdb, F_WRLCK) != 0)
+       ecode = tdb_lock_expand(tdb, F_WRLCK);
+       if (ecode != TDB_SUCCESS) {
+               tdb->ecode = ecode;
                return -1;
                return -1;
+       }
 
        /* Someone else may have expanded the file, so retry. */
        old_size = tdb->map_size;
 
        /* Someone else may have expanded the file, so retry. */
        old_size = tdb->map_size;