CernVM-FS  2.11.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cache_tiered.cc
Go to the documentation of this file.
1 
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 
18  return "Tiered Cache\n"
19  " - upper layer: " + upper_->Describe() +
20  " - lower layer: " + lower_->Describe();
21 }
22 
23 
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 
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 
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 
52  int fd = upper_->Open(object);
53  if ((fd >= 0) || (fd != -ENOENT)) {return fd;}
54 
55  int fd2 = lower_->Open(object);
56  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  int64_t size = lower_->GetSize(fd2);
60  if (size < 0) {
61  lower_->Close(fd2);
62  return fd;
63  }
64 
65  void *txn = alloca(upper_->SizeOfTxn());
66  if (upper_->StartTxn(object.id, size, txn) < 0) {
67  lower_->Close(fd2);
68  return fd;
69  }
70  upper_->CtrlTxn(object.info, 0, txn);
71 
72  std::vector<char> m_buffer;
73  m_buffer.resize(kCopyBufferSize);
74  uint64_t remaining = size;
75  uint64_t offset = 0;
76  while (remaining > 0) {
77  unsigned nbytes = remaining > kCopyBufferSize ? kCopyBufferSize : remaining;
78  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  if ((result < 0) || (result != nbytes)) {
81  lower_->Close(fd2);
82  upper_->AbortTxn(txn);
83  return fd;
84  }
85  result = upper_->Write(&m_buffer[0], nbytes, txn);
86  if (result < 0) {
87  lower_->Close(fd2);
88  upper_->AbortTxn(txn);
89  return fd;
90  }
91  offset += nbytes;
92  remaining -= nbytes;
93  }
94  lower_->Close(fd2);
95  int fd_return = upper_->OpenFromTxn(txn);
96  if (fd_return < 0) {
97  upper_->AbortTxn(txn);
98  return fd;
99  }
100  if (upper_->CommitTxn(txn) < 0) {
101  upper_->Close(fd_return);
102  return fd;
103  }
104  return fd_return;
105 }
106 
107 
108 int TieredCacheManager::StartTxn(const shash::Any &id, uint64_t size, void *txn)
109 {
110  int upper_result = upper_->StartTxn(id, size, txn);
111  if (lower_readonly_ || (upper_result < 0)) {
112  return upper_result;
113  }
114 
115  void *txn2 = static_cast<char *>(txn) + upper_->SizeOfTxn();
116  int lower_result = lower_->StartTxn(id, size, txn2);
117  if (lower_result < 0) {
118  upper_->AbortTxn(txn);
119  }
120  return lower_result;
121 }
122 
123 
125  CacheManager *upper_cache,
126  CacheManager *lower_cache)
127 {
128  TieredCacheManager *cache_mgr =
129  new TieredCacheManager(upper_cache, lower_cache);
130  delete cache_mgr->quota_mgr_;
131  cache_mgr->quota_mgr_ = upper_cache->quota_mgr();
132 
133  return cache_mgr;
134 }
135 
136 
138  const ObjectInfo &object_info,
139  const int flags,
140  void *txn)
141 {
142  upper_->CtrlTxn(object_info, flags, txn);
143  if (!lower_readonly_) {
144  void *txn2 = static_cast<char*>(txn) + upper_->SizeOfTxn();
145  lower_->CtrlTxn(object_info, flags, txn2);
146  }
147 }
148 
149 
150 int64_t TieredCacheManager::Write(const void *buf, uint64_t size, void *txn) {
151  int upper_result = upper_->Write(buf, size, txn);
152  if (lower_readonly_ || (upper_result < 0)) { return upper_result; }
153 
154  void *txn2 = static_cast<char*>(txn) + upper_->SizeOfTxn();
155  return lower_->Write(buf, size, txn2);
156 }
157 
158 
160  int upper_result = upper_->Reset(txn);
161 
162  int lower_result = upper_result;
163  if (!lower_readonly_) {
164  void *txn2 = static_cast<char*>(txn) + upper_->SizeOfTxn();
165  lower_result = lower_->Reset(txn2);
166  }
167 
168  return (upper_result < 0) ? upper_result : lower_result;
169 }
170 
171 
173  int upper_result = upper_->AbortTxn(txn);
174 
175  int lower_result = upper_result;
176  if (!lower_readonly_) {
177  void *txn2 = static_cast<char*>(txn) + upper_->SizeOfTxn();
178  lower_result = lower_->AbortTxn(txn2);
179  }
180 
181  return (upper_result < 0) ? upper_result : lower_result;
182 }
183 
184 
186  int upper_result = upper_->CommitTxn(txn);
187 
188  int lower_result = upper_result;
189  if (!lower_readonly_) {
190  void *txn2 = static_cast<char*>(txn) + upper_->SizeOfTxn();
191  lower_result = lower_->CommitTxn(txn2);
192  }
193 
194  return (upper_result < 0) ? upper_result : lower_result;
195 }
196 
197 
199 {
200  manifest::Breadcrumb breadcrumb = upper_->LoadBreadcrumb(fqrn);
201  if (!breadcrumb.IsValid())
202  breadcrumb = lower_->LoadBreadcrumb(fqrn);
203  return breadcrumb;
204 }
205 
206 
208  bool upper_success = upper_->StoreBreadcrumb(manifest);
209  bool lower_success = true;
210  if (!lower_readonly_)
211  lower_success = lower_->StoreBreadcrumb(manifest);
212  return upper_success && lower_success;
213 }
214 
215 
217  upper_->Spawn();
218  lower_->Spawn();
219 }
220 
221 
223  quota_mgr_ = NULL; // gets deleted by upper
224  delete upper_;
225  delete lower_;
226 }
const manifest::Manifest * manifest() const
Definition: repository.h:125
virtual int64_t GetSize(int fd)=0
virtual int AbortTxn(void *txn)
int RestoreState(const int fd_progress, void *state)
Definition: cache.cc:194
virtual void Spawn()=0
virtual int Open(const BlessedObject &object)
Definition: cache_tiered.cc:51
virtual manifest::Breadcrumb LoadBreadcrumb(const std::string &)
Definition: cache.h:219
void * SaveState(const int fd_progress)
Definition: cache.cc:221
assert((mem||(size==0))&&"Out Of Memory")
virtual int AbortTxn(void *txn)=0
virtual bool StoreBreadcrumb(const manifest::Manifest &)
Definition: cache.h:222
virtual bool DoFreeState(void *data)
Definition: cache_tiered.cc:24
virtual int Open(const BlessedObject &object)=0
virtual void * DoSaveState()
Definition: cache_tiered.cc:43
virtual std::string Describe()
Definition: cache_tiered.cc:17
TieredCacheManager(CacheManager *upper_cache, CacheManager *lower_cache)
Definition: cache_tiered.h:84
virtual int Reset(void *txn)
static CacheManager * Create(CacheManager *upper_cache, CacheManager *lower_cache)
virtual int CommitTxn(void *txn)=0
virtual int OpenFromTxn(void *txn)=0
virtual int CommitTxn(void *txn)
virtual int DoRestoreState(void *data)
Definition: cache_tiered.cc:33
virtual int Close(int fd)=0
virtual int64_t Write(const void *buf, uint64_t size, void *txn)
virtual int Reset(void *txn)=0
void FreeState(const int fd_progress, void *state)
Definition: cache.cc:100
CacheManager * lower_
Definition: cache_tiered.h:89
virtual void CtrlTxn(const ObjectInfo &object_info, const int flags, void *txn)
CacheManager * upper_
Definition: cache_tiered.h:88
QuotaManager * quota_mgr()
Definition: cache.h:198
static const unsigned kCopyBufferSize
Definition: cache_tiered.h:75
virtual int StartTxn(const shash::Any &id, uint64_t size, void *txn)
QuotaManager * quota_mgr_
Definition: cache.h:237
virtual uint32_t SizeOfTxn()=0
bool IsValid() const
Definition: manifest.h:30
virtual manifest::Breadcrumb LoadBreadcrumb(const std::string &fqrn)
virtual ~TieredCacheManager()
virtual int StartTxn(const shash::Any &id, uint64_t size, void *txn)=0
virtual void Spawn()
static void size_t size
Definition: smalloc.h:47
virtual int64_t Pread(int fd, void *buf, uint64_t size, uint64_t offset)=0
virtual bool StoreBreadcrumb(const manifest::Manifest &manifest)
virtual std::string Describe()=0
virtual int64_t Write(const void *buf, uint64_t sz, void *txn)=0
virtual void CtrlTxn(const ObjectInfo &object_info, const int flags, void *txn)=0