XRootD
Loading...
Searching...
No Matches
XrdOssCsiTagstoreFile.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d O s s C s i T a g s t o r e F i l e . c c */
4/* */
5/* (C) Copyright 2020 CERN. */
6/* */
7/* This file is part of the XRootD software suite. */
8/* */
9/* XRootD is free software: you can redistribute it and/or modify it under */
10/* the terms of the GNU Lesser General Public License as published by the */
11/* Free Software Foundation, either version 3 of the License, or (at your */
12/* option) any later version. */
13/* */
14/* In applying this licence, CERN does not waive the privileges and */
15/* immunities granted to it by virtue of its status as an Intergovernmental */
16/* Organization or submit itself to any jurisdiction. */
17/* */
18/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
19/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
20/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
21/* License for more details. */
22/* */
23/* You should have received a copy of the GNU Lesser General Public License */
24/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
25/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
26/* */
27/* The copyright holder's institutional names and contributor's names may not */
28/* be used to endorse or promote products derived from this software without */
29/* specific prior written permission of the institution or contributor. */
30/******************************************************************************/
31
32#include "XrdOssCsiTrace.hh"
34
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <unistd.h>
38
40
41int XrdOssCsiTagstoreFile::Open(const char *path, const off_t dsize, const int Oflag, XrdOucEnv &Env)
42{
43 EPNAME("TagstoreFile::Open");
44
45 const int ret = fd_->Open(path, Oflag, 0666, Env);
46 if (ret<0)
47 {
48 return ret;
49 }
50 isOpen = true;
51
52 struct guard_s
53 {
54 guard_s(XrdOssDF *fd, bool &isopen) : fd_(fd), isopen_(isopen) { }
55 ~guard_s() { if (fd_) { fd_->Close(); isopen_ = false; } }
56 void disarm() { fd_ = NULL; }
57
58 XrdOssDF *fd_;
59 bool &isopen_;
60 } fdguard(fd_.get(),isOpen);
61
62 const static int little = 1;
63 if (*(char const *)&little)
64 {
65 machineIsBige_ = false;
66 }
67 else
68 {
69 machineIsBige_ = true;
70 }
71
72 uint32_t magic;
73
74 const ssize_t mread = XrdOssCsiTagstoreFile::fullread(*fd_, header_, 0, 20);
75 bool mok = false;
76 if (mread >= 0)
77 {
78 memcpy(&magic, header_, 4);
79 if (magic == cmagic_)
80 {
81 fileIsBige_ = machineIsBige_;
82 mok = true;
83 }
84 else if (magic == bswap_32(cmagic_))
85 {
86 fileIsBige_ = !machineIsBige_;
87 mok = true;
88 }
89 }
90
91 if (!mok)
92 {
93 fileIsBige_ = machineIsBige_;
94 hflags_ = (dsize==0) ? XrdOssCsiTagstore::csVer : 0;
95 trackinglen_ = 0;
96 const int stret = MarshallAndWriteHeader();
97 if (stret<0) return stret;
98 }
99 else
100 {
101 memcpy(&trackinglen_, &header_[4], 8);
102 if (fileIsBige_ != machineIsBige_)
103 {
104 trackinglen_ = bswap_64(trackinglen_);
105 }
106 memcpy(&hflags_,&header_[12], 4);
107 if (fileIsBige_ != machineIsBige_)
108 {
109 hflags_ = bswap_32(hflags_);
110 }
111 const uint32_t cv = XrdOucCRC::Calc32C(header_, 16, 0U);
112 uint32_t rv;
113 memcpy(&rv, &header_[16], 4);
114 if (fileIsBige_ != machineIsBige_) rv = bswap_32(rv);
115 if (rv != cv)
116 {
117 return -EDOM;
118 }
119 }
120
121 if (trackinglen_ != dsize)
122 {
123 TRACE(Warn, "Tagfile disagrees with actual filelength for " << fn_ << " expected " << trackinglen_ << " actual " << dsize);
124 }
125
126 const int rsret = ResetSizes(dsize);
127 if (rsret<0) return rsret;
128
129 fdguard.disarm();
130 return 0;
131}
132
134{
135 EPNAME("ResetSizes");
136 if (!isOpen) return -EBADF;
137 actualsize_ = size;
138 struct stat sb;
139 const int ssret = fd_->Fstat(&sb);
140 if (ssret<0) return ssret;
141 const off_t expected_tagfile_size = 20LL + 4*((trackinglen_+XrdSys::PageSize-1)/XrdSys::PageSize);
142 // truncate can be relatively slow
143 if (expected_tagfile_size < sb.st_size)
144 {
145 TRACE(Warn, "Truncating tagfile to " << expected_tagfile_size <<
146 ", from current size " << sb.st_size << " for " << fn_);
147 const int tret = fd_->Ftruncate(expected_tagfile_size);
148 if (tret<0) return tret;
149 }
150 else if (expected_tagfile_size > sb.st_size)
151 {
152 off_t nb = 0;
153 if (sb.st_size>20) nb = (sb.st_size - 20)/4;
154 TRACE(Warn, "Reducing tracked size to " << (nb*XrdSys::PageSize) <<
155 " instead of " << trackinglen_ << ", because of short tagfile for " << fn_);
156 const int stret = WriteTrackedTagSize(nb*XrdSys::PageSize);
157 if (stret<0) return stret;
158 const int tret = fd_->Ftruncate(20LL + 4*nb);
159 if (tret<0) return tret;
160 }
161 return 0;
162}
163
165{
166 if (!isOpen) return -EBADF;
167 return fd_->Fsync();
168}
169
171{
172 if (!isOpen) return;
173 fd_->Flush();
174}
175
177{
178 if (!isOpen) return -EBADF;
179 isOpen = false;
180 return fd_->Close();
181}
182
183ssize_t XrdOssCsiTagstoreFile::WriteTags(const uint32_t *const buf, const off_t off, const size_t n)
184{
185 if (!isOpen) return -EBADF;
186 if (machineIsBige_ != fileIsBige_) return WriteTags_swap(buf, off, n);
187
188 const ssize_t nwritten = XrdOssCsiTagstoreFile::fullwrite(*fd_, buf, 20LL+4*off, 4*n);
189 if (nwritten<0) return nwritten;
190 return nwritten/4;
191}
192
193ssize_t XrdOssCsiTagstoreFile::ReadTags(uint32_t *const buf, const off_t off, const size_t n)
194{
195 if (!isOpen) return -EBADF;
196 if (machineIsBige_ != fileIsBige_) return ReadTags_swap(buf, off, n);
197
198 const ssize_t nread = XrdOssCsiTagstoreFile::fullread(*fd_, buf, 20LL+4*off, 4*n);
199 if (nread<0) return nread;
200 return nread/4;
201}
202
203int XrdOssCsiTagstoreFile::Truncate(const off_t size, bool datatoo)
204{
205 if (!isOpen)
206 {
207 return -EBADF;
208 }
209
210 // set tag file to correct length for value of size
211 const off_t expected_tagfile_size = 20LL + 4*((size+XrdSys::PageSize-1)/XrdSys::PageSize);
212 const int tret = fd_->Ftruncate(expected_tagfile_size);
213
214 // if failed to set the tagfile length return error before updating header
215 if (tret != XrdOssOK) return tret;
216
217 // truncating down to zero, so reset to content verified
218 if (datatoo && size==0) hflags_ |= XrdOssCsiTagstore::csVer;
219
220 int wtt = WriteTrackedTagSize(size);
221 if (wtt<0) return wtt;
222
223 if (datatoo) actualsize_ = size;
224 return 0;
225}
226
227ssize_t XrdOssCsiTagstoreFile::WriteTags_swap(const uint32_t *const buf, const off_t off, const size_t n)
228{
229 uint32_t b[1024];
230 const size_t bsz = sizeof(b)/sizeof(uint32_t);
231 size_t towrite = n;
232 size_t nwritten = 0;
233 while(towrite>0)
234 {
235 const size_t bs = std::min(towrite, bsz);
236 for(size_t i=0;i<bs;i++)
237 {
238 b[i] = bswap_32(buf[i+nwritten]);
239 }
240 const ssize_t wret = XrdOssCsiTagstoreFile::fullwrite(*fd_, b, 20LL+4*(nwritten+off), 4*bs);
241 if (wret<0) return wret;
242 towrite -= wret/4;
243 nwritten += wret/4;
244 }
245 return n;
246}
247
248ssize_t XrdOssCsiTagstoreFile::ReadTags_swap(uint32_t *const buf, const off_t off, const size_t n)
249{
250 uint32_t b[1024];
251 const size_t bsz = sizeof(b)/sizeof(uint32_t);
252 size_t toread = n;
253 size_t nread = 0;
254 while(toread>0)
255 {
256 const size_t bs = std::min(toread, bsz);
257 const ssize_t rret = XrdOssCsiTagstoreFile::fullread(*fd_, b, 20LL+4*(nread+off), 4*bs);
258 if (rret<0) return rret;
259 for(size_t i=0;i<bs;i++)
260 {
261 buf[i+nread] = bswap_32(b[i]);
262 }
263 toread -= rret/4;
264 nread += rret/4;
265 }
266 return n;
267}
#define EPNAME(x)
XrdOucTrace OssCsiTrace
#define XrdOssOK
Definition XrdOss.hh:50
#define stat(a, b)
Definition XrdPosix.hh:101
#define TRACE(act, x)
Definition XrdTrace.hh:63
virtual int Truncate(off_t, bool)
virtual int ResetSizes(const off_t size)
virtual ssize_t ReadTags(uint32_t *, off_t, size_t)
virtual ssize_t WriteTags(const uint32_t *, off_t, size_t)
static ssize_t fullread(XrdOssDF &fd, void *buff, const off_t off, const size_t sz)
virtual int Open(const char *, off_t, int, XrdOucEnv &)
static ssize_t fullwrite(XrdOssDF &fd, const void *buff, const off_t off, const size_t sz)
static const uint32_t csVer
static uint32_t Calc32C(const void *data, size_t count, uint32_t prevcs=0)
Definition XrdOucCRC.cc:190
static const int PageSize