return off;
}
-/* Note: we unlock the current bucket if we coalesce or fail. */
-static tdb_bool_err coalesce(struct tdb_context *tdb,
- tdb_off_t off, tdb_off_t b_off,
- tdb_len_t data_len)
+/* Note: we unlock the current bucket if we coalesce (> 0) or fail (-ve). */
+static tdb_len_t coalesce(struct tdb_context *tdb,
+ tdb_off_t off, tdb_off_t b_off,
+ tdb_len_t data_len)
{
tdb_off_t end;
struct tdb_free_record rec;
/* Didn't find any adjacent free? */
if (end == off + sizeof(struct tdb_used_record) + data_len)
- return false;
+ return 0;
/* OK, expand initial record */
ecode = tdb_read_convert(tdb, off, &rec, sizeof(rec));
if (ecode != TDB_SUCCESS) {
return ecode;
}
- return true;
+ /* Return usable length. */
+ return end - off - sizeof(struct tdb_used_record);
err:
/* To unify error paths, we *always* unlock bucket on error. */
while (off) {
const struct tdb_free_record *r;
- tdb_len_t len;
+ tdb_len_t len, coal;
tdb_off_t next;
- int coal;
r = tdb_access_read(tdb, off, sizeof(*r), true);
if (TDB_PTR_IS_ERR(r)) {
/* Since we're going slow anyway, try coalescing here. */
coal = coalesce(tdb, off, b_off, len);
- if (coal == 1) {
- /* This has unlocked list, restart. */
- goto again;
- }
- if (coal < 0) {
+ if (TDB_OFF_IS_ERR(coal)) {
/* This has already unlocked on error. */
return coal;
}
+ if (coal > 0) {
+ /* This has unlocked list, restart. */
+ goto again;
+ }
off = next;
}
b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
/* Lock and coalesce. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
- ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) == 1);
+ ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024)
+ == 1024 + sizeof(struct tdb_used_record) + 2048);
ok1(tdb->file->allrecord_lock.count == 0 && tdb->file->num_lockrecs == 0);
ok1(free_record_length(tdb, layout->elem[1].base.off)
== 1024 + sizeof(struct tdb_used_record) + 2048);
b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
/* Lock and coalesce. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
- ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) == 1);
+ ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024)
+ == 1024 + sizeof(struct tdb_used_record) + 512);
ok1(tdb->file->allrecord_lock.count == 0 && tdb->file->num_lockrecs == 0);
ok1(free_record_length(tdb, layout->elem[1].base.off)
== 1024 + sizeof(struct tdb_used_record) + 512);
b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
/* Lock and coalesce. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
- ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) == 1);
+ ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) ==
+ 1024 + sizeof(struct tdb_used_record) + 512
+ + sizeof(struct tdb_used_record) + 256);
ok1(tdb->file->allrecord_lock.count == 0
&& tdb->file->num_lockrecs == 0);
ok1(free_record_length(tdb, layout->elem[1].base.off)