Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
eblob (0.23.11-pagecache) unstable; urgency=medium

* Try to handle potential Linux pagecache bug

-- Anton Kortunov <toshik@yandex-team.ru> Thu, 24 Dec 2015 20:34:00 +0300

eblob (0.23.11) unstable; urgency=low

* iterate: verify checksum for entries while iterating a blob
Expand Down
32 changes: 31 additions & 1 deletion library/blob.c
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,7 @@ static int eblob_mark_entry_removed(struct eblob_backend *b,
struct eblob_key *key, struct eblob_ram_control *old)
{
int err;
struct eblob_disk_control old_dc;
struct eblob_disk_control old_dc, blob_dc;
int64_t record_size = 0;

/* Add entry to list of removed entries */
Expand Down Expand Up @@ -1096,6 +1096,22 @@ static int eblob_mark_entry_removed(struct eblob_backend *b,
goto err;
}

/* Sanity: Check that blob on-disk header is not corrupted */
err = __eblob_read_ll(old->bctl->data_ctl.fd, &blob_dc, sizeof(blob_dc), old->data_offset);
if (err) {
EBLOB_WARNX(b->cfg.log, EBLOB_LOG_ERROR, "%s: __eblob_read_ll: FAILED: data, fd: %d, err: %d",
eblob_dump_id(key->id), old->bctl->index_ctl.fd, err);
goto err;
}

if (memcmp(&blob_dc.key, key, sizeof(key)) != 0) {
EBLOB_WARNX(b->cfg.log, EBLOB_LOG_ERROR, "keys mismatch: in-memory: %s, blob on-disk: %s",
eblob_dump_id_len(key->id, EBLOB_ID_SIZE),
eblob_dump_id_len(blob_dc.key.id, EBLOB_ID_SIZE));
err = -EINVAL;
goto err;
}

eblob_convert_disk_control(&old_dc);
/* size of the place occupied by the record in the index and the blob */
record_size = old_dc.disk_size + sizeof(struct eblob_disk_control);
Expand Down Expand Up @@ -1215,6 +1231,20 @@ static int eblob_commit_disk(struct eblob_backend *b, struct eblob_key *key,
goto err_out_exit;
}

/***************************************************************************
* ACHTUNG *
* Check for potential linux pagecache bug *
* Try to read few bites before header to fill page cache. *
***************************************************************************/
uint64_t tmp;
if (wc->ctl_data_offset > 8) {
err = __eblob_read_ll(wc->data_fd, &tmp, sizeof(tmp), wc->ctl_data_offset - 8);
if (err) {
eblob_dump_wc(b, key, wc, "eblob_commit_disk: ERROR sanity check failed", err);
goto err_out_exit;
}
}

err = __eblob_write_ll(wc->data_fd, &dc, sizeof(dc), wc->ctl_data_offset);
if (err) {
eblob_dump_wc(b, key, wc, "eblob_commit_disk: ERROR-write-data", err);
Expand Down