From 1831b086d000520ee926f096ea8dbd629c80b437 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Tue, 10 Apr 2018 10:01:50 -0700 Subject: [PATCH] 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 Change-Id: Ie5cf273f8d6511548146a756a7b63c73fee12101 Reviewed-on: https://review.gerrithub.io/407232 Reviewed-by: Daniel Verkamp Tested-by: SPDK Automated Test System Reviewed-by: Ben Walker --- lib/blobfs/blobfs.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/blobfs/blobfs.c b/lib/blobfs/blobfs.c index dbeef66a3..edeeacfd9 100644 --- a/lib/blobfs/blobfs.c +++ b/lib/blobfs/blobfs.c @@ -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);