xrootd
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 <utility>
42 #include <cinttypes>
43 #include <cstdio>
44 
46 {
47 public:
48  typedef std::pair<off_t,off_t> Sizes_t;
49 
50  XrdOssCsiPages(const std::string &fn, std::unique_ptr<XrdOssCsiTagstore> ts, bool wh, bool am, bool dpe, bool dlw, const char *);
52 
53  int Open(const char *path, off_t dsize, int flags, XrdOucEnv &envP);
54  int Close();
55 
56  int UpdateRange(XrdOssDF *, const void *, off_t, size_t, XrdOssCsiRangeGuard&);
57  int VerifyRange(XrdOssDF *, const void *, off_t, size_t, XrdOssCsiRangeGuard&);
58  void Flush();
59  int Fsync();
60 
62 
63  int FetchRange(XrdOssDF *, const void *, off_t, size_t, uint32_t *, uint64_t, XrdOssCsiRangeGuard&);
64  int StoreRange(XrdOssDF *, const void *, off_t, size_t, uint32_t *, uint64_t, XrdOssCsiRangeGuard&);
65  void LockTrackinglen(XrdOssCsiRangeGuard &, off_t, off_t, bool);
66 
67  bool IsReadOnly() const { return rdonly_; }
68  int truncate(XrdOssDF *, off_t, XrdOssCsiRangeGuard&);
69  int TrackedSizesGet(Sizes_t &, bool);
70  int LockResetSizes(XrdOssDF *, off_t);
71  void TrackedSizeRelease();
72  int VerificationStatus();
73 
74  static void pgDoCalc(const void *, off_t, size_t, uint32_t *);
75  static int pgWritePrelockCheck(const void *, off_t, size_t, const uint32_t *, uint64_t);
76 
77 protected:
78  ssize_t apply_sequential_aligned_modify(const void *, off_t, size_t, const uint32_t *, bool, bool, uint32_t, uint32_t);
79  std::unique_ptr<XrdOssCsiTagstore> ts_;
86  bool rdonly_;
89 
92 
93  // fn_ is the associated data filename when the page object is made.
94  // if renamed while the page object exists fn_ is not updated
95  const std::string fn_;
96  const std::string tident_;
97  const char *tident;
98 
99  // used by the loosewrite checks
102 
103  int LockSetTrackedSize(off_t);
104  int LockTruncateSize(off_t,bool);
105  int LockMakeUnverified();
106 
107  int UpdateRangeAligned(const void *, off_t, size_t, const Sizes_t &);
108  int UpdateRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &);
109  int UpdateRangeHoleUntilPage(XrdOssDF *, off_t, const Sizes_t &);
110  int VerifyRangeAligned(const void *, off_t, size_t, const Sizes_t &);
111  int VerifyRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &);
112  int FetchRangeAligned(const void *, off_t, size_t, const Sizes_t &, uint32_t *, uint64_t);
113  int FetchRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &, uint32_t *, uint64_t);
114  int FetchRangeUnaligned_preblock(XrdOssDF *, const void *, off_t, size_t, off_t, uint32_t *, uint32_t *, uint64_t);
115  int FetchRangeUnaligned_postblock(XrdOssDF *, const void *, off_t, size_t, off_t, uint32_t *, uint32_t *, size_t, uint64_t);
116  int StoreRangeAligned(const void *, off_t, size_t, const Sizes_t &, uint32_t *);
117  int StoreRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &, const uint32_t *);
118  int StoreRangeUnaligned_preblock(XrdOssDF *, const void *, size_t, off_t, off_t, const uint32_t *, uint32_t &);
119  int StoreRangeUnaligned_postblock(XrdOssDF *, const void *, size_t, off_t, off_t, const uint32_t *, uint32_t &);
120 
121 
122  static ssize_t fullread(XrdOssDF *fd, void *buff, const off_t off , const size_t sz)
123  {
124  ssize_t rret = maxread(fd, buff, off, sz);
125  if (rret<0) return rret;
126  if (static_cast<size_t>(rret) != sz) return -EDOM;
127  return rret;
128  }
129 
130  // keep calling read until EOF, an error or the number of bytes read is between tg and sz.
131  static ssize_t maxread(XrdOssDF *fd, void *buff, const off_t off , const size_t sz, size_t tg=0)
132  {
133  size_t toread = sz, nread = 0;
134  uint8_t *p = (uint8_t*)buff;
135  tg = tg ? tg : sz;
136  while(toread>0 && nread<tg)
137  {
138  const ssize_t rret = fd->Read(&p[nread], off+nread, toread);
139  if (rret<0) return rret;
140  if (rret==0) break;
141  toread -= rret;
142  nread += rret;
143  }
144  return nread;
145  }
146 
147  std::string CRCMismatchError(size_t blen, off_t pgnum, uint32_t got, uint32_t expected)
148  {
149  char buf[256],buf2[256];
150  snprintf(buf, sizeof(buf),
151  "bad crc32c/0x%04" PRIx32 " checksum in file ",
152  (uint32_t)blen);
153  snprintf(buf2, sizeof(buf2),
154  " at offset 0x%" PRIx64 ", got 0x%08" PRIx32 ", expected 0x%08" PRIx32,
155  (uint64_t)(pgnum*XrdSys::PageSize),
156  got, expected);
157  return buf + fn_ + buf2;
158  }
159 
160  std::string ByteMismatchError(size_t blen, off_t off, uint8_t user, uint8_t page)
161  {
162  char buf[256],buf2[256];
163  snprintf(buf, sizeof(buf),
164  "unexpected byte mismatch between user-buffer and page/0x%04" PRIx32 " in file ",
165  (uint32_t)blen);
166  snprintf(buf2, sizeof(buf2),
167  " at offset 0x%" PRIx64 ", user-byte 0x%02" PRIx8 ", page-byte 0x%02" PRIx8,
168  (uint64_t)off,
169  user, page);
170  return buf + fn_ + buf2;
171  }
172 
173  std::string PageReadError(size_t blen, off_t pgnum, int ret)
174  {
175  char buf[256],buf2[256];
176  snprintf(buf, sizeof(buf),
177  "error %d while reading page/0x%04" PRIx32 " in file ",
178  ret, (uint32_t)blen);
179  snprintf(buf2, sizeof(buf2),
180  " at offset 0x%" PRIx64,
181  (uint64_t)(pgnum*XrdSys::PageSize));
182  return buf + fn_ + buf2;
183  }
184 
185  std::string TagsReadError(off_t start, size_t n, int ret)
186  {
187  char buf[256];
188  snprintf(buf, sizeof(buf),
189  "error %d while reading crc32c values for pages [0x%" PRIx64":0x%" PRIx64 "] for file ",
190  ret, (uint64_t)start, (uint64_t)(start + n - 1));
191  return buf + fn_;
192  }
193 
194  std::string TagsWriteError(off_t start, size_t n, int ret)
195  {
196  char buf[256];
197  snprintf(buf, sizeof(buf),
198  "error %d while writing crc32c values for pages [0x%" PRIx64":0x%" PRIx64 "] for file ",
199  ret, (uint64_t)start, (uint64_t)(start + n - 1));
200  return buf + fn_;
201  }
202 
203  static const size_t stsize_ = 1024;
204 };
205 
206 #endif
std::string CRCMismatchError(size_t blen, off_t pgnum, uint32_t got, uint32_t expected)
Definition: XrdOssCsiPages.hh:147
bool checklastpg_
Definition: XrdOssCsiPages.hh:101
off_t lastpgforloose_
Definition: XrdOssCsiPages.hh:100
int StoreRangeAligned(const void *, off_t, size_t, const Sizes_t &, uint32_t *)
bool writeHoles_
Definition: XrdOssCsiPages.hh:82
std::string PageReadError(size_t blen, off_t pgnum, int ret)
Definition: XrdOssCsiPages.hh:173
const std::string tident_
Definition: XrdOssCsiPages.hh:96
XrdSysCondVar tscond_
Definition: XrdOssCsiPages.hh:90
int LockResetSizes(XrdOssDF *, off_t)
void TrackedSizeRelease()
int Open(const char *path, off_t dsize, int flags, XrdOucEnv &envP)
std::string TagsWriteError(off_t start, size_t n, int ret)
Definition: XrdOssCsiPages.hh:194
int UpdateRangeHoleUntilPage(XrdOssDF *, off_t, const Sizes_t &)
void LockTrackinglen(XrdOssCsiRangeGuard &, off_t, off_t, bool)
int StoreRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &, const uint32_t *)
static const size_t stsize_
Definition: XrdOssCsiPages.hh:203
const std::string fn_
Definition: XrdOssCsiPages.hh:95
bool tsforupdate_
Definition: XrdOssCsiPages.hh:91
bool rdonly_
Definition: XrdOssCsiPages.hh:86
Definition: XrdOssCsiRanges.hh:100
int VerificationStatus()
Definition: XrdSysPthread.hh:164
int FetchRange(XrdOssDF *, const void *, off_t, size_t, uint32_t *, uint64_t, XrdOssCsiRangeGuard &)
bool hasMissingTags_
Definition: XrdOssCsiPages.hh:85
int FetchRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &, uint32_t *, uint64_t)
const bool loosewriteConfigured_
Definition: XrdOssCsiPages.hh:87
int FetchRangeUnaligned_preblock(XrdOssDF *, const void *, off_t, size_t, off_t, uint32_t *, uint32_t *, uint64_t)
static int pgWritePrelockCheck(const void *, off_t, size_t, const uint32_t *, uint64_t)
Definition: XrdSysPthread.hh:78
int StoreRangeUnaligned_preblock(XrdOssDF *, const void *, size_t, off_t, off_t, const uint32_t *, uint32_t &)
static const int PageSize
Definition: XrdSysPageSize.hh:36
int LockMakeUnverified()
std::pair< off_t, off_t > Sizes_t
Definition: XrdOssCsiPages.hh:48
int FetchRangeAligned(const void *, off_t, size_t, const Sizes_t &, uint32_t *, uint64_t)
Definition: XrdOucEnv.hh:41
Definition: XrdOssCsiPages.hh:45
const char * tident
Definition: XrdOssCsiPages.hh:97
int UpdateRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &)
int LockTruncateSize(off_t, bool)
j template void())
Definition: XrdOucJson.hh:4121
~XrdOssCsiPages()
Definition: XrdOssCsiPages.hh:51
void BasicConsistencyCheck(XrdOssDF *)
Definition: XrdOssCsiRanges.hh:57
XrdOssCsiRanges ranges_
Definition: XrdOssCsiPages.hh:81
std::unique_ptr< XrdOssCsiTagstore > ts_
Definition: XrdOssCsiPages.hh:79
int UpdateRangeAligned(const void *, off_t, size_t, const Sizes_t &)
virtual ssize_t Read(off_t offset, size_t size)
Definition: XrdOss.hh:281
bool allowMissingTags_
Definition: XrdOssCsiPages.hh:83
bool loosewrite_
Definition: XrdOssCsiPages.hh:88
int FetchRangeUnaligned_postblock(XrdOssDF *, const void *, off_t, size_t, off_t, uint32_t *, uint32_t *, size_t, uint64_t)
int StoreRange(XrdOssDF *, const void *, off_t, size_t, uint32_t *, uint64_t, XrdOssCsiRangeGuard &)
int UpdateRange(XrdOssDF *, const void *, off_t, size_t, XrdOssCsiRangeGuard &)
int TrackedSizesGet(Sizes_t &, bool)
std::string ByteMismatchError(size_t blen, off_t off, uint8_t user, uint8_t page)
Definition: XrdOssCsiPages.hh:160
int VerifyRangeAligned(const void *, off_t, size_t, const Sizes_t &)
Definition: XrdOss.hh:62
int truncate(XrdOssDF *, off_t, XrdOssCsiRangeGuard &)
int StoreRangeUnaligned_postblock(XrdOssDF *, const void *, size_t, off_t, off_t, const uint32_t *, uint32_t &)
std::string TagsReadError(off_t start, size_t n, int ret)
Definition: XrdOssCsiPages.hh:185
int LockSetTrackedSize(off_t)
int VerifyRange(XrdOssDF *, const void *, off_t, size_t, XrdOssCsiRangeGuard &)
static void pgDoCalc(const void *, off_t, size_t, uint32_t *)
XrdSysMutex rangeaddmtx_
Definition: XrdOssCsiPages.hh:80
bool disablePgExtend_
Definition: XrdOssCsiPages.hh:84
bool IsReadOnly() const
Definition: XrdOssCsiPages.hh:67
int VerifyRangeUnaligned(XrdOssDF *, const void *, off_t, size_t, const Sizes_t &)
static ssize_t maxread(XrdOssDF *fd, void *buff, const off_t off, const size_t sz, size_t tg=0)
Definition: XrdOssCsiPages.hh:131
static ssize_t fullread(XrdOssDF *fd, void *buff, const off_t off, const size_t sz)
Definition: XrdOssCsiPages.hh:122
XrdOssCsiPages(const std::string &fn, std::unique_ptr< XrdOssCsiTagstore > ts, bool wh, bool am, bool dpe, bool dlw, const char *)
ssize_t apply_sequential_aligned_modify(const void *, off_t, size_t, const uint32_t *, bool, bool, uint32_t, uint32_t)