blobfs: sync length if append occurs after cache eviction

Intermittent failures with the RocksDB tests pointed to
corruption in the MANIFEST file.  Further debug showed that
the MANIFEST file would be corrupted when its cache was
evicted.  Blobfs was partly handling append after cache
eviction - it would write the data to the correct position
within the blob.  But the sync path would not write the
updated file length xattr when the cache had been evicted.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: Ie5cf273f8d6511548146a756a7b63c73fee12101

Reviewed-on: https://review.gerrithub.io/407232
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Jim Harris 2018-04-10 10:01:50 -07:00 committed by Daniel Verkamp
parent bb5f94f838
commit 1831b086d0

View File

@ -1929,7 +1929,23 @@ __file_flush(void *_args)
* progress we will flush more data after that is completed.
*/
__free_args(args);
if (next == NULL) {
/*
* For cases where a file's cache was evicted, and then the
* file was later appended, we will write the data directly
* to disk and bypass cache. So just update length_flushed
* here to reflect that all data was already written to disk.
*/
file->length_flushed = file->append_pos;
}
pthread_spin_unlock(&file->lock);
if (next == NULL) {
/*
* There is no data to flush, but we still need to check for any
* outstanding sync requests to make sure metadata gets updated.
*/
__check_sync_reqs(file);
}
return;
}
@ -2307,7 +2323,7 @@ _file_sync(struct spdk_file *file, struct spdk_fs_channel *channel,
BLOBFS_TRACE(file, "offset=%jx\n", file->append_pos);
pthread_spin_lock(&file->lock);
if (file->append_pos <= file->length_flushed || file->last == NULL) {
if (file->append_pos <= file->length_flushed) {
BLOBFS_TRACE(file, "done - no data to flush\n");
pthread_spin_unlock(&file->lock);
cb_fn(cb_arg, 0);