]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/db/blob/blob_log_format.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / db / blob / blob_log_format.cc
CommitLineData
11fdf7f2
TL
1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
5//
11fdf7f2 6
20effc67 7#include "db/blob/blob_log_format.h"
11fdf7f2
TL
8
9#include "util/coding.h"
10#include "util/crc32c.h"
11
f67539c2 12namespace ROCKSDB_NAMESPACE {
11fdf7f2
TL
13
14void BlobLogHeader::EncodeTo(std::string* dst) {
15 assert(dst != nullptr);
16 dst->clear();
17 dst->reserve(BlobLogHeader::kSize);
18 PutFixed32(dst, kMagicNumber);
19 PutFixed32(dst, version);
20 PutFixed32(dst, column_family_id);
21 unsigned char flags = (has_ttl ? 1 : 0);
22 dst->push_back(flags);
23 dst->push_back(compression);
24 PutFixed64(dst, expiration_range.first);
25 PutFixed64(dst, expiration_range.second);
26}
27
28Status BlobLogHeader::DecodeFrom(Slice src) {
1e59de90 29 const char* kErrorMessage = "Error while decoding blob log header";
11fdf7f2
TL
30 if (src.size() != BlobLogHeader::kSize) {
31 return Status::Corruption(kErrorMessage,
32 "Unexpected blob file header size");
33 }
34 uint32_t magic_number;
35 unsigned char flags;
36 if (!GetFixed32(&src, &magic_number) || !GetFixed32(&src, &version) ||
37 !GetFixed32(&src, &column_family_id)) {
38 return Status::Corruption(
39 kErrorMessage,
40 "Error decoding magic number, version and column family id");
41 }
42 if (magic_number != kMagicNumber) {
43 return Status::Corruption(kErrorMessage, "Magic number mismatch");
44 }
45 if (version != kVersion1) {
46 return Status::Corruption(kErrorMessage, "Unknown header version");
47 }
48 flags = src.data()[0];
49 compression = static_cast<CompressionType>(src.data()[1]);
50 has_ttl = (flags & 1) == 1;
51 src.remove_prefix(2);
52 if (!GetFixed64(&src, &expiration_range.first) ||
53 !GetFixed64(&src, &expiration_range.second)) {
54 return Status::Corruption(kErrorMessage, "Error decoding expiration range");
55 }
56 return Status::OK();
57}
58
59void BlobLogFooter::EncodeTo(std::string* dst) {
60 assert(dst != nullptr);
61 dst->clear();
62 dst->reserve(BlobLogFooter::kSize);
63 PutFixed32(dst, kMagicNumber);
64 PutFixed64(dst, blob_count);
65 PutFixed64(dst, expiration_range.first);
66 PutFixed64(dst, expiration_range.second);
67 crc = crc32c::Value(dst->c_str(), dst->size());
68 crc = crc32c::Mask(crc);
69 PutFixed32(dst, crc);
70}
71
72Status BlobLogFooter::DecodeFrom(Slice src) {
1e59de90 73 const char* kErrorMessage = "Error while decoding blob log footer";
11fdf7f2
TL
74 if (src.size() != BlobLogFooter::kSize) {
75 return Status::Corruption(kErrorMessage,
76 "Unexpected blob file footer size");
77 }
78 uint32_t src_crc = 0;
79 src_crc = crc32c::Value(src.data(), BlobLogFooter::kSize - sizeof(uint32_t));
80 src_crc = crc32c::Mask(src_crc);
494da23a 81 uint32_t magic_number = 0;
11fdf7f2
TL
82 if (!GetFixed32(&src, &magic_number) || !GetFixed64(&src, &blob_count) ||
83 !GetFixed64(&src, &expiration_range.first) ||
84 !GetFixed64(&src, &expiration_range.second) || !GetFixed32(&src, &crc)) {
85 return Status::Corruption(kErrorMessage, "Error decoding content");
86 }
87 if (magic_number != kMagicNumber) {
88 return Status::Corruption(kErrorMessage, "Magic number mismatch");
89 }
90 if (src_crc != crc) {
91 return Status::Corruption(kErrorMessage, "CRC mismatch");
92 }
93 return Status::OK();
94}
95
96void BlobLogRecord::EncodeHeaderTo(std::string* dst) {
97 assert(dst != nullptr);
98 dst->clear();
99 dst->reserve(BlobLogRecord::kHeaderSize + key.size() + value.size());
100 PutFixed64(dst, key.size());
101 PutFixed64(dst, value.size());
102 PutFixed64(dst, expiration);
103 header_crc = crc32c::Value(dst->c_str(), dst->size());
104 header_crc = crc32c::Mask(header_crc);
105 PutFixed32(dst, header_crc);
106 blob_crc = crc32c::Value(key.data(), key.size());
107 blob_crc = crc32c::Extend(blob_crc, value.data(), value.size());
108 blob_crc = crc32c::Mask(blob_crc);
109 PutFixed32(dst, blob_crc);
110}
111
112Status BlobLogRecord::DecodeHeaderFrom(Slice src) {
1e59de90 113 const char* kErrorMessage = "Error while decoding blob record";
11fdf7f2
TL
114 if (src.size() != BlobLogRecord::kHeaderSize) {
115 return Status::Corruption(kErrorMessage,
116 "Unexpected blob record header size");
117 }
118 uint32_t src_crc = 0;
119 src_crc = crc32c::Value(src.data(), BlobLogRecord::kHeaderSize - 8);
120 src_crc = crc32c::Mask(src_crc);
121 if (!GetFixed64(&src, &key_size) || !GetFixed64(&src, &value_size) ||
122 !GetFixed64(&src, &expiration) || !GetFixed32(&src, &header_crc) ||
123 !GetFixed32(&src, &blob_crc)) {
124 return Status::Corruption(kErrorMessage, "Error decoding content");
125 }
126 if (src_crc != header_crc) {
127 return Status::Corruption(kErrorMessage, "Header CRC mismatch");
128 }
129 return Status::OK();
130}
131
132Status BlobLogRecord::CheckBlobCRC() const {
133 uint32_t expected_crc = 0;
134 expected_crc = crc32c::Value(key.data(), key.size());
135 expected_crc = crc32c::Extend(expected_crc, value.data(), value.size());
136 expected_crc = crc32c::Mask(expected_crc);
137 if (expected_crc != blob_crc) {
138 return Status::Corruption("Blob CRC mismatch");
139 }
140 return Status::OK();
141}
142
f67539c2 143} // namespace ROCKSDB_NAMESPACE