summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2014-01-29 21:47:58 +0000
committerRobert Newson <rnewson@apache.org>2014-01-30 11:39:07 +0000
commite7fdc16a485ec9a9d3b6bb3555957e367ec55f11 (patch)
tree115b37a1c8182bd71cb11232f9adb429bfd8b13d
parent2d080449ae8f1b66bcb90e90dcc8e41022f4584c (diff)
downloadcouchdb-e7fdc16a485ec9a9d3b6bb3555957e367ec55f11.tar.gz
Throw cleaner error on MD5 mismatch during compaction
COUCHDB-2040
-rw-r--r--src/couchdb/couch_db_updater.erl17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/couchdb/couch_db_updater.erl b/src/couchdb/couch_db_updater.erl
index af7578e02..947669cb1 100644
--- a/src/couchdb/couch_db_updater.erl
+++ b/src/couchdb/couch_db_updater.erl
@@ -824,14 +824,16 @@ copy_doc_attachments(#db{updater_fd = SrcFd} = SrcDb, SrcSp, DestFd) ->
end,
% copy the bin values
NewBinInfos = lists:map(
- fun({Name, Type, BinSp, AttLen, RevPos, Md5}) ->
+ fun({Name, Type, BinSp, AttLen, RevPos, ExpectedMd5}) ->
% 010 UPGRADE CODE
- {NewBinSp, AttLen, AttLen, Md5, _IdentityMd5} =
+ {NewBinSp, AttLen, AttLen, ActualMd5, _IdentityMd5} =
couch_stream:copy_to_new_stream(SrcFd, BinSp, DestFd),
- {Name, Type, NewBinSp, AttLen, AttLen, RevPos, Md5, identity};
- ({Name, Type, BinSp, AttLen, DiskLen, RevPos, Md5, Enc1}) ->
- {NewBinSp, AttLen, _, Md5, _IdentityMd5} =
+ check_md5(ExpectedMd5, ActualMd5),
+ {Name, Type, NewBinSp, AttLen, AttLen, RevPos, ExpectedMd5, identity};
+ ({Name, Type, BinSp, AttLen, DiskLen, RevPos, ExpectedMd5, Enc1}) ->
+ {NewBinSp, AttLen, _, ActualMd5, _IdentityMd5} =
couch_stream:copy_to_new_stream(SrcFd, BinSp, DestFd),
+ check_md5(ExpectedMd5, ActualMd5),
Enc = case Enc1 of
true ->
% 0110 UPGRADE CODE
@@ -842,10 +844,13 @@ copy_doc_attachments(#db{updater_fd = SrcFd} = SrcDb, SrcSp, DestFd) ->
_ ->
Enc1
end,
- {Name, Type, NewBinSp, AttLen, DiskLen, RevPos, Md5, Enc}
+ {Name, Type, NewBinSp, AttLen, DiskLen, RevPos, ExpectedMd5, Enc}
end, BinInfos),
{BodyData, NewBinInfos}.
+check_md5(Md5, Md5) -> ok;
+check_md5(_, _) -> throw(md5_mismatch).
+
copy_docs(Db, #db{updater_fd = DestFd} = NewDb, InfoBySeq0, Retry) ->
% COUCHDB-968, make sure we prune duplicates during compaction
InfoBySeq = lists:usort(fun(#doc_info{id=A}, #doc_info{id=B}) -> A =< B end,