Directory: | cvmfs/ |
---|---|
File: | cvmfs/cache_tiered.cc |
Date: | 2025-02-02 02:34:22 |
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 | |||
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 |