GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/cache_tiered.cc
Date: 2024-04-21 02:33:16
Exec Total Coverage
Lines: 79 127 62.2%
Branches: 47 114 41.2%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4 #include "cvmfs_config.h"
5 #include "cache_tiered.h"
6
7 #include <errno.h>
8
9 #include <string>
10 #include <vector>
11
12 #include "quota.h"
13 #include "util/platform.h"
14 #include "util/posix.h"
15
16
17 std::string TieredCacheManager::Describe() {
18 return "Tiered Cache\n"
19 " - upper layer: " + upper_->Describe() +
20 " - lower layer: " + lower_->Describe();
21 }
22
23
24 bool TieredCacheManager::DoFreeState(void *data) {
25 SavedState *state = reinterpret_cast<SavedState *>(data);
26 upper_->FreeState(-1, state->state_upper);
27 lower_->FreeState(-1, state->state_lower);
28 delete state;
29 return true;
30 }
31
32
33 int TieredCacheManager::DoRestoreState(void *data) {
34 SavedState *state = reinterpret_cast<SavedState *>(data);
35 int new_root_fd = upper_->RestoreState(-1, state->state_upper);
36 // The lower cache layer does not keep the root catalog open
37 int retval = lower_->RestoreState(-1, state->state_lower);
38 assert(retval == -1);
39 return new_root_fd;
40 }
41
42
43 void *TieredCacheManager::DoSaveState() {
44 SavedState *state = new SavedState();
45 state->state_upper = upper_->SaveState(-1);
46 state->state_lower = lower_->SaveState(-1);
47 return state;
48 }
49
50
51 6 int TieredCacheManager::Open(const LabeledObject &object) {
52
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 int fd = upper_->Open(object);
53
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
6 if ((fd >= 0) || (fd != -ENOENT)) {return fd;}
54
55
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 int fd2 = lower_->Open(object);
56
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 if (fd2 < 0) {return fd;} // NOTE: use error code from upper.
57
58 // Lower cache hit; upper cache miss. Copy object into the upper cache.
59
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 int64_t size = lower_->GetSize(fd2);
60
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (size < 0) {
61 lower_->Close(fd2);
62 return fd;
63 }
64
65
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 void *txn = alloca(upper_->SizeOfTxn());
66
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 if (upper_->StartTxn(object.id, size, txn) < 0) {
67 lower_->Close(fd2);
68 return fd;
69 }
70
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 upper_->CtrlTxn(object.label, 0, txn);
71
72 1 std::vector<char> m_buffer;
73
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 m_buffer.resize(kCopyBufferSize);
74 1 uint64_t remaining = size;
75 1 uint64_t offset = 0;
76
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 while (remaining > 0) {
77 1 unsigned nbytes = remaining > kCopyBufferSize ? kCopyBufferSize : remaining;
78
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 int64_t result = lower_->Pread(fd2, &m_buffer[0], nbytes, offset);
79 // The file we are reading is supposed to be exactly `size` bytes.
80
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if ((result < 0) || (result != nbytes)) {
81 lower_->Close(fd2);
82 upper_->AbortTxn(txn);
83 return fd;
84 }
85
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 result = upper_->Write(&m_buffer[0], nbytes, txn);
86
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (result < 0) {
87 lower_->Close(fd2);
88 upper_->AbortTxn(txn);
89 return fd;
90 }
91 1 offset += nbytes;
92 1 remaining -= nbytes;
93 }
94
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lower_->Close(fd2);
95
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 int fd_return = upper_->OpenFromTxn(txn);
96
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (fd_return < 0) {
97 upper_->AbortTxn(txn);
98 return fd;
99 }
100
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 if (upper_->CommitTxn(txn) < 0) {
101 upper_->Close(fd_return);
102 return fd;
103 }
104 1 return fd_return;
105 1 }
106
107
108 3 int TieredCacheManager::StartTxn(const shash::Any &id, uint64_t size, void *txn)
109 {
110 3 int upper_result = upper_->StartTxn(id, size, txn);
111
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
3 if (lower_readonly_ || (upper_result < 0)) {
112 2 return upper_result;
113 }
114
115 1 void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
116 1 int lower_result = lower_->StartTxn(id, size, txn2);
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (lower_result < 0) {
118 upper_->AbortTxn(txn);
119 }
120 1 return lower_result;
121 }
122
123
124 9 CacheManager *TieredCacheManager::Create(
125 CacheManager *upper_cache,
126 CacheManager *lower_cache)
127 {
128 TieredCacheManager *cache_mgr =
129
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 new TieredCacheManager(upper_cache, lower_cache);
130
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 delete cache_mgr->quota_mgr_;
131 9 cache_mgr->quota_mgr_ = upper_cache->quota_mgr();
132
133 9 return cache_mgr;
134 }
135
136
137 2 void TieredCacheManager::CtrlTxn(const Label &label, const int flags, void *txn)
138 {
139 2 upper_->CtrlTxn(label, flags, txn);
140
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (!lower_readonly_) {
141 1 void *txn2 = static_cast<char*>(txn) + upper_->SizeOfTxn();
142 1 lower_->CtrlTxn(label, flags, txn2);
143 }
144 2 }
145
146
147 2 int64_t TieredCacheManager::Write(const void *buf, uint64_t size, void *txn) {
148 2 int upper_result = upper_->Write(buf, size, txn);
149
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
2 if (lower_readonly_ || (upper_result < 0)) { return upper_result; }
150
151 1 void *txn2 = static_cast<char*>(txn) + upper_->SizeOfTxn();
152 1 return lower_->Write(buf, size, txn2);
153 }
154
155
156 1 int TieredCacheManager::Reset(void *txn) {
157 1 int upper_result = upper_->Reset(txn);
158
159 1 int lower_result = upper_result;
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!lower_readonly_) {
161 void *txn2 = static_cast<char*>(txn) + upper_->SizeOfTxn();
162 lower_result = lower_->Reset(txn2);
163 }
164
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 return (upper_result < 0) ? upper_result : lower_result;
166 }
167
168
169 1 int TieredCacheManager::AbortTxn(void *txn) {
170 1 int upper_result = upper_->AbortTxn(txn);
171
172 1 int lower_result = upper_result;
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!lower_readonly_) {
174 void *txn2 = static_cast<char*>(txn) + upper_->SizeOfTxn();
175 lower_result = lower_->AbortTxn(txn2);
176 }
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 return (upper_result < 0) ? upper_result : lower_result;
179 }
180
181
182 2 int TieredCacheManager::CommitTxn(void *txn) {
183 2 int upper_result = upper_->CommitTxn(txn);
184
185 2 int lower_result = upper_result;
186
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (!lower_readonly_) {
187 1 void *txn2 = static_cast<char*>(txn) + upper_->SizeOfTxn();
188 1 lower_result = lower_->CommitTxn(txn2);
189 }
190
191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 return (upper_result < 0) ? upper_result : lower_result;
192 }
193
194
195 8 manifest::Breadcrumb TieredCacheManager::LoadBreadcrumb(const std::string &fqrn)
196 {
197 8 manifest::Breadcrumb breadcrumb = upper_->LoadBreadcrumb(fqrn);
198
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (!breadcrumb.IsValid())
199 8 breadcrumb = lower_->LoadBreadcrumb(fqrn);
200 8 return breadcrumb;
201 }
202
203
204 bool TieredCacheManager::StoreBreadcrumb(const manifest::Manifest &manifest) {
205 bool upper_success = upper_->StoreBreadcrumb(manifest);
206 bool lower_success = true;
207 if (!lower_readonly_)
208 lower_success = lower_->StoreBreadcrumb(manifest);
209 return upper_success && lower_success;
210 }
211
212
213 void TieredCacheManager::Spawn() {
214 upper_->Spawn();
215 lower_->Spawn();
216 }
217
218
219 36 TieredCacheManager::~TieredCacheManager() {
220 18 quota_mgr_ = NULL; // gets deleted by upper
221
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 delete upper_;
222
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 delete lower_;
223 36 }
224