Skip to content

Commit d70ae25

Browse files
committed
Fix bug where CRC is not correctly calculated during append
wday-contrib 2767
1 parent 67b1f10 commit d70ae25

3 files changed

Lines changed: 29 additions & 7 deletions

File tree

src/bitcask.app.src

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{application, bitcask, [
22
{description, "Yet another key/value storage engine"},
3-
{vsn, "3.0.1"},
3+
{vsn, "3.0.2"},
44
{modules, []},
55
{registered, []},
66
{applications, [kernel, stdlib]},

src/bitcask.erl

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3282,7 +3282,8 @@ hintfile_test_() ->
32823282
{timeout, 60, fun test_missing_hintfile/0},
32833283
{timeout, 60, fun test_corrupt_hintfile/0},
32843284
{timeout, 60, fun test_ensure_valid_through_chunks/0},
3285-
{timeout, 60, fun test_put_with_missing_hintfile/0}
3285+
{timeout, 60, fun test_put_with_missing_hintfile/0},
3286+
{timeout, 60, fun test_read_crc_with_metadata/0}
32863287
].
32873288

32883289
setup_hintfile(Name) ->
@@ -3394,6 +3395,26 @@ test_put_with_missing_hintfile() ->
33943395
meck:unload(meta_getter_counter),
33953396
bitcask:close(B1).
33963397

3398+
%% Test that read_crc works correctly with hint files containing metadata
3399+
test_read_crc_with_metadata() ->
3400+
{Dir, FS, HintFile, _Objects, MetaGetter} = setup_hintfile("read_crc_meta"),
3401+
3402+
?assert(bitcask_fileops:is_file(HintFile)),
3403+
3404+
bitcask_fileops:close_hintfile(FS),
3405+
case bitcask_fileops:open_file(bitcask_fileops:filename(FS), append) of
3406+
{ok, FS2} ->
3407+
%% CRC is read, if hintfd is undefined then it failed.
3408+
?assertNotEqual(undefined, FS2#filestate.hintfd),
3409+
bitcask_fileops:close_hintfile(FS2);
3410+
{error, enoent} ->
3411+
?assert(false, "Hintfile was deleted due to CRC read failure - this indicates the bug")
3412+
end,
3413+
3414+
meck:unload(meta_getter_counter),
3415+
B1 = bitcask:open(Dir, [read_write, {meta_getter, MetaGetter}]),
3416+
bitcask:close(B1).
3417+
33973418
write_until_hint_bytes(B1, MaxBytes) ->
33983419
write_until_hint_bytes_loop(B1, MaxBytes, {0, 0}).
33993420

@@ -4360,7 +4381,7 @@ duplicate_keys_tests_() ->
43604381

43614382
load_key_duplicate_test() ->
43624383
{ok, KeyDir} = bitcask_nifs:keydir_new(),
4363-
4384+
43644385
Key = <<"duplicate_key">>,
43654386
Meta = <<"meta">>,
43664387
FileId1 = 1000,
@@ -4369,17 +4390,17 @@ load_key_duplicate_test() ->
43694390
Timestamp2 = 2000, % Newer timestamp
43704391
Offset = 0,
43714392
TotalSz = 100,
4372-
4393+
43734394
Args1 = {Key, Meta, Timestamp1, {Offset, TotalSz}},
43744395
Args2 = {Key, Meta, Timestamp2, {Offset, TotalSz}},
4375-
4396+
43764397
LoadResultNewer = load_key(FileId2, KeyDir, fun(X) -> X end, Args2),
43774398
LoadResultOlder = load_key(FileId1, KeyDir, fun(X) -> X end, Args1),
4378-
4399+
43794400
%% Both load_key calls should return ok, even if keydir_put returns already_exists
43804401
?assertEqual(ok, LoadResultNewer),
43814402
?assertEqual(ok, LoadResultOlder),
4382-
4403+
43834404
%% Verify we have the latest value
43844405
Entry = bitcask_nifs:keydir_get(KeyDir, Key),
43854406
?assertEqual(FileId2, Entry#bitcask_entry.file_id),

src/bitcask_fileops.erl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ read_crc(Fd) ->
552552
case bitcask_io:file_read(Fd, ?HINT_RECORD_SZ) of
553553
{ok, <<0:?TSTAMPFIELD,
554554
0:?KEYSIZEFIELD,
555+
0:?METASIZEFIELD,
555556
ExpectCRC:?TOTALSIZEFIELD,
556557
_TombInt:?TOMBSTONEFIELD_V2,
557558
(?MAXOFFSET_V2):?OFFSETFIELD_V2>>} ->

0 commit comments

Comments
 (0)