XRootD
XrdOssCsiPages.hh
Go to the documentation of this file.
1 #ifndef _XRDOSSCSIPAGES_H
2 #define _XRDOSSCSIPAGES_H
3 /******************************************************************************/
4 /* */
5 /* X r d O s s C s i P a g e s . h h */
6 /* */
7 /* (C) Copyright 2021 CERN. */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* In applying this licence, CERN does not waive the privileges and */
17 /* immunities granted to it by virtue of its status as an Intergovernmental */
18 /* Organization or submit itself to any jurisdiction. */
19 /* */
20 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
21 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
22 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
23 /* License for more details. */
24 /* */
25 /* You should have received a copy of the GNU Lesser General Public License */
26 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
27 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
28 /* */
29 /* The copyright holder's institutional names and contributor's names may not */
30 /* be used to endorse or promote products derived from this software without */
31 /* specific prior written permission of the institution or contributor. */
32 /******************************************************************************/
33 
34 #include "XrdSys/XrdSysPthread.hh"
35 #include "XrdSys/XrdSysPageSize.hh"
36 
37 #include "XrdOssCsiTagstore.hh"
38 #include "XrdOssCsiRanges.hh"
39 #include <memory>
40 #include <mutex>
41 #include <string>
42 #include <utility>
43 #include <cinttypes>
44 #include <cstdio>
45 
47 {
48 public:
49  typedef std::pair<off_t,off_t> Sizes_t;
50 
51  XrdOssCsiPages(const std::string &fn, std::unique_ptr<XrdOssCsiTagstore> ts, bool wh, bool am, bool dpe, bool dlw, const char *);
52  ~XrdOssCsiPages() { (void)Close(); }
53 
54  int Open(const char *path, off_t dsize, int flags, XrdOucEnv &envP);
55  int Close();
56 
57  int UpdateRange(XrdOssDF *, const void *, off_t, size_t, XrdOssCsiRangeGuard&);
58  int VerifyRange(XrdOssDF *, const void *, off_t, size_t, XrdOssCsiRangeGuard&);
59  void Flush();
60  int Fsync();
61 
63 
64  int FetchRange(XrdOssDF *, const void *, off_t, size_t, uint32_t *, uint64_t, XrdOssCsiRangeGuard&);
65  int StoreRange(XrdOssDF *, const void *, off_t, size_t, uint32_t *, uint64_t, XrdOssCsiRangeGuard&);
66  void LockTrackinglen(XrdOssCsiRangeGuard &, off_t, off_t, bool);
67 
68  bool IsReadOnly() const { return rdonly_; }
69  int truncate(XrdOssDF *, off_t, XrdOssCsiRangeGuard&);
70  int TrackedSizesGet(Sizes_t &, bool);
71  int LockResetSizes(XrdOssDF *, off_t);
72  void TrackedSizeRelease();
73  int VerificationStatus();
74 
75  static void pgDoCalc(const void *, off_t, size_t, uint32_t *);
76  static int pgWritePrelockCheck(const void *, off_t, size_t, const uint32_t *, uint64_t);
77 
78 protected:
79  ssize_t apply_sequential_aligned_modify(const void *, off_t, size_t, const uint32_t *, bool, bool, uint32_t, uint32_t);
80  std::unique_ptr<XrdOssCsiTagstore> ts_;
87  bool rdonly_;
90 
93 
94  // fn_ is the associated data filename when the page object is made.
95  // if renamed while the page object exists fn_ is not updated
96  const std::string fn_;
97  const std::string tident_;
98  const char *tident;
99 
100  // used by the loosewrite checks
103 
104  int LockSetTrackedSize(off_t);
105  int LockTruncateSize(off_t,bool);
106  int LockMakeUnverified();
107 
108  int UpdateRangeAligned(const void *, off_t, size_t, const Sizes_t &);
109  int UpdateRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &);
110  int UpdateRangeHoleUntilPage(XrdOssDF *, off_t, const Sizes_t &);
111  int VerifyRangeAligned(const void *, off_t, size_t, const Sizes_t &);
112  int VerifyRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &);
113  int FetchRangeAligned(const void *, off_t, size_t, const Sizes_t &, uint32_t *, uint64_t);
114  int FetchRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &, uint32_t *, uint64_t);
115  int FetchRangeUnaligned_preblock(XrdOssDF *, const void *, off_t, size_t, off_t, uint32_t *, uint32_t *, uint64_t);
116  int FetchRangeUnaligned_postblock(XrdOssDF *, const void *, off_t, size_t, off_t, uint32_t *, uint32_t *, size_t, uint64_t);
117  int StoreRangeAligned(const void *, off_t, size_t, const Sizes_t &, uint32_t *);
118  int StoreRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &, const uint32_t *);
119  int StoreRangeUnaligned_preblock(XrdOssDF *, const void *, size_t, off_t, off_t, const uint32_t *, uint32_t &);
120  int StoreRangeUnaligned_postblock(XrdOssDF *, const void *, size_t, off_t, off_t, const uint32_t *, uint32_t &);
121 
122 
123  static ssize_t fullread(XrdOssDF *fd, void *buff, const off_t off , const size_t sz)
124  {
125  ssize_t rret = maxread(fd, buff, off, sz);
126  if (rret<0) return rret;
127  if (static_cast<size_t>(rret) != sz) return -EDOM;
128  return rret;
129  }
130 
131  // keep calling read until EOF, an error or the number of bytes read is between tg and sz.
132  static ssize_t maxread(XrdOssDF *fd, void *buff, const off_t off , const size_t sz, size_t tg=0)
133  {
134  size_t toread = sz, nread = 0;
135  uint8_t *p = (uint8_t*)buff;
136  tg = tg ? tg : sz;
137  while(toread>0 && nread<tg)
138  {
139  const ssize_t rret = fd->Read(&p[nread], off+nread, toread);
140  if (rret<0) return rret;
141  if (rret==0) break;
142  toread -= rret;
143  nread += rret;
144  }
145  return nread;
146  }
147 
148  std::string CRCMismatchError(size_t blen, off_t pgnum, uint32_t got, uint32_t expected)
149  {
150  char buf[256],buf2[256];
151  snprintf(buf, sizeof(buf),
152  "bad crc32c/0x%04" PRIx32 " checksum in file ",
153  (uint32_t)blen);
154  snprintf(buf2, sizeof(buf2),
155  " at offset 0x%" PRIx64 ", got 0x%08" PRIx32 ", expected 0x%08" PRIx32,
156  (uint64_t)(pgnum*XrdSys::PageSize),
157  got, expected);
158  return buf + fn_ + buf2;
159  }
160 
161  std::string ByteMismatchError(size_t blen, off_t off, uint8_t user, uint8_t page)
162  {
163  char buf[256],buf2[256];
164  snprintf(buf, sizeof(buf),
165  "unexpected byte mismatch between user-buffer and page/0x%04" PRIx32 " in file ",
166  (uint32_t)blen);
167  snprintf(buf2, sizeof(buf2),
168  " at offset 0x%" PRIx64 ", user-byte 0x%02" PRIx8 ", page-byte 0x%02" PRIx8,
169  (uint64_t)off,
170  user, page);
171  return buf + fn_ + buf2;
172  }
173 
174  std::string PageReadError(size_t blen, off_t pgnum, int ret)
175  {
176  char buf[256],buf2[256];
177  snprintf(buf, sizeof(buf),
178  "error %d while reading page/0x%04" PRIx32 " in file ",
179  ret, (uint32_t)blen);
180  snprintf(buf2, sizeof(buf2),
181  " at offset 0x%" PRIx64,
182  (uint64_t)(pgnum*XrdSys::PageSize));
183  return buf + fn_ + buf2;
184  }
185 
186  std::string TagsReadError(off_t start, size_t n, int ret)
187  {
188  char buf[256];
189  snprintf(buf, sizeof(buf),
190  "error %d while reading crc32c values for pages [0x%" PRIx64":0x%" PRIx64 "] for file ",
191  ret, (uint64_t)start, (uint64_t)(start + n - 1));
192  return buf + fn_;
193  }
194 
195  std::string TagsWriteError(off_t start, size_t n, int ret)
196  {
197  char buf[256];
198  snprintf(buf, sizeof(buf),
199  "error %d while writing crc32c values for pages [0x%" PRIx64":0x%" PRIx64 "] for file ",
200  ret, (uint64_t)start, (uint64_t)(start + n - 1));
201  return buf + fn_;
202  }
203 
204  static const size_t stsize_ = 1024;
205 };
206 
207 #endif
XrdSysCondVar tscond_
int UpdateRangeAligned(const void *, off_t, size_t, const Sizes_t &)
int StoreRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &, const uint32_t *)
ssize_t apply_sequential_aligned_modify(const void *, off_t, size_t, const uint32_t *, bool, bool, uint32_t, uint32_t)
XrdOssCsiRanges ranges_
std::string ByteMismatchError(size_t blen, off_t off, uint8_t user, uint8_t page)
static ssize_t maxread(XrdOssDF *fd, void *buff, const off_t off, const size_t sz, size_t tg=0)
std::string TagsReadError(off_t start, size_t n, int ret)
std::unique_ptr< XrdOssCsiTagstore > ts_
int FetchRangeAligned(const void *, off_t, size_t, const Sizes_t &, uint32_t *, uint64_t)
int LockTruncateSize(off_t, bool)
XrdOssCsiPages(const std::string &fn, std::unique_ptr< XrdOssCsiTagstore > ts, bool wh, bool am, bool dpe, bool dlw, const char *)
int UpdateRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &)
const char * tident
std::string TagsWriteError(off_t start, size_t n, int ret)
int StoreRangeAligned(const void *, off_t, size_t, const Sizes_t &, uint32_t *)
void TrackedSizeRelease()
int FetchRangeUnaligned_preblock(XrdOssDF *, const void *, off_t, size_t, off_t, uint32_t *, uint32_t *, uint64_t)
int UpdateRangeHoleUntilPage(XrdOssDF *, off_t, const Sizes_t &)
const std::string tident_
static ssize_t fullread(XrdOssDF *fd, void *buff, const off_t off, const size_t sz)
std::pair< off_t, off_t > Sizes_t
int FetchRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &, uint32_t *, uint64_t)
int truncate(XrdOssDF *, off_t, XrdOssCsiRangeGuard &)
XrdSysMutex rangeaddmtx_
int FetchRangeUnaligned_postblock(XrdOssDF *, const void *, off_t, size_t, off_t, uint32_t *, uint32_t *, size_t, uint64_t)
int LockResetSizes(XrdOssDF *, off_t)
int VerifyRangeAligned(const void *, off_t, size_t, const Sizes_t &)
int VerifyRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &)
int LockSetTrackedSize(off_t)
int FetchRange(XrdOssDF *, const void *, off_t, size_t, uint32_t *, uint64_t, XrdOssCsiRangeGuard &)
std::string CRCMismatchError(size_t blen, off_t pgnum, uint32_t got, uint32_t expected)
void BasicConsistencyCheck(XrdOssDF *)
void LockTrackinglen(XrdOssCsiRangeGuard &, off_t, off_t, bool)
int StoreRangeUnaligned_preblock(XrdOssDF *, const void *, size_t, off_t, off_t, const uint32_t *, uint32_t &)
std::string PageReadError(size_t blen, off_t pgnum, int ret)
int Open(const char *path, off_t dsize, int flags, XrdOucEnv &envP)
int TrackedSizesGet(Sizes_t &, bool)
int StoreRangeUnaligned_postblock(XrdOssDF *, const void *, size_t, off_t, off_t, const uint32_t *, uint32_t &)
const bool loosewriteConfigured_
static int pgWritePrelockCheck(const void *, off_t, size_t, const uint32_t *, uint64_t)
const std::string fn_
int StoreRange(XrdOssDF *, const void *, off_t, size_t, uint32_t *, uint64_t, XrdOssCsiRangeGuard &)
static const size_t stsize_
int UpdateRange(XrdOssDF *, const void *, off_t, size_t, XrdOssCsiRangeGuard &)
static void pgDoCalc(const void *, off_t, size_t, uint32_t *)
bool IsReadOnly() const
int VerifyRange(XrdOssDF *, const void *, off_t, size_t, XrdOssCsiRangeGuard &)
virtual ssize_t Read(off_t offset, size_t size)
Definition: XrdOss.hh:281
XrdOucEnv * envP
Definition: XrdPss.cc:109
static const int PageSize