]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / DiskIO / DiskThreads / DiskThreadsDiskFile.cc
CommitLineData
b9ae18aa 1/*
f70aedc4 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
b9ae18aa 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
b9ae18aa 7 */
8
bbc27441
AJ
9/* DEBUG: section 79 Disk IO Routines */
10
582c2af2 11#include "squid.h"
b9ae18aa 12#include "DiskIO/IORequestor.h"
13#include "DiskIO/ReadRequest.h"
14#include "DiskIO/WriteRequest.h"
602d9612 15#include "DiskThreadsDiskFile.h"
c4ad1349 16#include "fd.h"
b3f7fd88 17#include "fs_io.h"
582c2af2
FC
18#include "Generic.h"
19#include "globals.h"
e4f1fdae 20#include "StatCounters.h"
582c2af2 21#include "Store.h"
b9ae18aa 22
1a30fdf5 23#include <cerrno>
21d845b1 24
b9ae18aa 25/* === PUBLIC =========================================================== */
26
27CBDATA_CLASS_INIT(DiskThreadsDiskFile);
b9ae18aa 28
43b6575c 29DiskThreadsDiskFile::DiskThreadsDiskFile(char const *aPath)
b9ae18aa 30{
86c63190 31 assert(aPath);
bf8fe701 32 debugs(79, 3, "UFSFile::UFSFile: " << aPath);
86c63190 33 path_ = xstrdup(aPath);
b9ae18aa 34}
35
36DiskThreadsDiskFile::~DiskThreadsDiskFile()
37{
86c63190 38 safe_free(path_);
b9ae18aa 39 doClose();
40}
41
42void
63be0a78 43DiskThreadsDiskFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
b9ae18aa 44{
e4f1fdae 45 ++statCounter.syscalls.disk.opens;
b9ae18aa 46#if !ASYNC_OPEN
47
48 fd = file_open(path_, flags);
49
50 if (fd < 0) {
bf8fe701 51 debugs(79, 3, "DiskThreadsDiskFile::open: got failure (" << errno << ")");
b9ae18aa 52 errorOccured = true;
53 return;
54 }
55
56#endif
cb4185f1 57 ++Opening_FD;
b9ae18aa 58
59 ioRequestor = callback;
60
61 ++inProgressIOs;
62
63#if ASYNC_OPEN
64
65 aioOpen(path_, flags, mode, DiskThreadsDiskFile::OpenDone, this);
66
67#else
68
69 openDone(fd, NULL, fd, 0);
70
71#endif
72}
73
74void
75DiskThreadsDiskFile::read(ReadRequest * request)
76{
77 debugs(79, 3, "DiskThreadsDiskFile::read: " << this << ", size " << request->len);
78 assert (fd > -1);
79 assert (ioRequestor.getRaw());
e4f1fdae 80 ++statCounter.syscalls.disk.reads;
b9ae18aa 81 ++inProgressIOs;
82#if ASYNC_READ
83
84 aioRead(fd, request->offset, request->len, ReadDone, new IoResult<ReadRequest>(this, request));
85#else
86
87 file_read(fd, request->buf, request->len, request->offset, ReadDone, new IoResult<ReadRequest>(this, request));
88#endif
89}
90
91void
63be0a78 92DiskThreadsDiskFile::create(int flags, mode_t mode, RefCount<IORequestor> callback)
b9ae18aa 93{
e4f1fdae 94 ++statCounter.syscalls.disk.opens;
b9ae18aa 95#if !ASYNC_CREATE
96
97 int fd = file_open(path_, flags);
98
99 if (fd < 0) {
bf8fe701 100 debugs(79, 3, "DiskThreadsDiskFile::create: got failure (" << errno << ")");
b9ae18aa 101 errorOccured = true;
102 return;
103 }
104
105#endif
cb4185f1 106 ++Opening_FD;
b9ae18aa 107
108 ioRequestor = callback;
109
110 ++inProgressIOs;
111
112#if ASYNC_CREATE
113
114 aioOpen(path_, flags, mode, DiskThreadsDiskFile::OpenDone, this);
115
116#else
117
118 openDone (fd, NULL, fd, 0);
119
120#endif
121}
122
123bool
124DiskThreadsDiskFile::error() const
125{
126 return errorOccured;
127}
128
129void
130DiskThreadsDiskFile::OpenDone(int fd, void *cbdata, const char *buf, int aio_return, int aio_errno)
131{
132 DiskThreadsDiskFile *myFile = static_cast<DiskThreadsDiskFile *>(cbdata);
133 myFile->openDone (fd, buf, aio_return, aio_errno);
134}
135
136void
ced8def3 137DiskThreadsDiskFile::openDone(int, const char *, int anFD, int errflag)
b9ae18aa 138{
bf8fe701 139 debugs(79, 3, "DiskThreadsDiskFile::openDone: FD " << anFD << ", errflag " << errflag);
5e263176 140 --Opening_FD;
b9ae18aa 141
142 fd = anFD;
143
144 if (errflag || fd < 0) {
b69e9ffa 145 debugs(79, DBG_CRITICAL, MYNAME << xstrerr(errflag));
e0236918 146 debugs(79, DBG_IMPORTANT, "\t" << path_);
b9ae18aa 147 errorOccured = true;
148 } else {
cb4185f1 149 ++store_open_disk_fd;
b9ae18aa 150 commSetCloseOnExec(fd);
151 fd_open(fd, FD_FILE, path_);
152 }
153
b9ae18aa 154 IORequestor::Pointer t = ioRequestor;
155 --inProgressIOs;
156 t->ioCompletedNotification();
ac97716e 157
bf8fe701 158 debugs(79, 3, "DiskThreadsDiskFile::openDone: exiting");
b9ae18aa 159}
160
161void DiskThreadsDiskFile::doClose()
162{
163 if (fd > -1) {
e4f1fdae 164 ++statCounter.syscalls.disk.closes;
d06925a4 165#if ASYNC_CLOSE
166
b9ae18aa 167 aioClose(fd);
168 fd_close(fd);
d06925a4 169#else
170
171 aioCancel(fd);
172 file_close(fd);
173#endif
174
5e263176 175 --store_open_disk_fd;
b9ae18aa 176 fd = -1;
177 }
178}
179
180void
63be0a78 181DiskThreadsDiskFile::close()
b9ae18aa 182{
bf8fe701 183 debugs(79, 3, "DiskThreadsDiskFile::close: " << this << " closing for " << ioRequestor.getRaw());
b9ae18aa 184
185 if (!ioInProgress()) {
186 doClose();
ac97716e 187 assert (ioRequestor != NULL);
b9ae18aa 188 ioRequestor->closeCompleted();
ac97716e 189 return;
190 } else {
fa84c01d 191 debugs(79, DBG_CRITICAL, HERE << "DiskThreadsDiskFile::close: " <<
ac97716e 192 "did NOT close because ioInProgress() is true. now what?");
b9ae18aa 193 }
194}
195
196bool
197DiskThreadsDiskFile::canRead() const
198{
bf8fe701 199 debugs(79, 3, "DiskThreadsDiskFile::canRead: fd is " << fd);
b9ae18aa 200 return fd > -1;
201}
202
203void
204DiskThreadsDiskFile::write(WriteRequest * writeRequest)
205{
bf8fe701 206 debugs(79, 3, "DiskThreadsDiskFile::write: FD " << fd);
e4f1fdae 207 ++statCounter.syscalls.disk.writes;
b9ae18aa 208 ++inProgressIOs;
209#if ASYNC_WRITE
210
211 aioWrite(fd, writeRequest->offset, (char *)writeRequest->buf, writeRequest->len, WriteDone, new IoResult<WriteRequest>(this, writeRequest),
212 writeRequest->free_func);
213#else
214
215 file_write(fd, writeRequest->offset, (char *)writeRequest->buf, writeRequest->len, WriteDone, new IoResult<WriteRequest>(this, writeRequest),
216 writeRequest->free_func);
217#endif
218}
219
220bool
221DiskThreadsDiskFile::canWrite() const
222{
223 return fd > -1;
224}
225
226bool
63be0a78 227DiskThreadsDiskFile::ioInProgress() const
b9ae18aa 228{
229 return inProgressIOs > 0;
230}
231
232/* === STATIC =========================================================== */
233
234#if ASYNC_READ
235void
236DiskThreadsDiskFile::ReadDone(int fd, void *my_data, const char *buf, int len, int errflag)
237#else
238void
239DiskThreadsDiskFile::ReadDone(int fd, const char *buf, int len, int errflag, void *my_data)
240#endif
241{
242 IoResult<ReadRequest> * result = static_cast<IoResult<ReadRequest> *>(my_data);
243 assert (result);
244 result->file->readDone(fd, buf, len, errflag, result->request);
245 delete result;
246}
247
248void
63be0a78 249DiskThreadsDiskFile::readDone(int rvfd, const char *buf, int len, int errflag, RefCount<ReadRequest> request)
b9ae18aa 250{
bf8fe701 251 debugs(79, 3, "DiskThreadsDiskFile::readDone: FD " << rvfd);
b9ae18aa 252 assert (fd == rvfd);
253
254 ssize_t rlen;
255
256 if (errflag) {
bf8fe701 257 debugs(79, 3, "DiskThreadsDiskFile::readDone: got failure (" << errflag << ")");
b9ae18aa 258 rlen = -1;
259 } else {
260 rlen = (ssize_t) len;
261 }
262
263#if ASYNC_READ
264 /* translate errflag from errno to Squid disk error */
265 errno = errflag;
266
267 if (errflag)
268 errflag = DISK_ERROR;
269 else
270 errflag = DISK_OK;
271
272#else
273
274 if (errflag == DISK_EOF)
f53969cc 275 errflag = DISK_OK; /* EOF is signalled by len == 0, not errors... */
b9ae18aa 276
277#endif
278
279 --inProgressIOs;
280
281 ioRequestor->readCompleted(buf, rlen, errflag, request);
282}
283
284void
285DiskThreadsDiskFile::
286#if ASYNC_WRITE
a37ea9a1 287WriteDone(int fd, void *my_data, const char *buf, int len, int errflag)
b9ae18aa 288#else
289WriteDone(int fd, int errflag, size_t len, void *my_data)
290#endif
291{
292 IoResult<WriteRequest> * result = static_cast<IoResult<WriteRequest> *>(my_data);
293 assert (result);
294 result->file->writeDone(fd, errflag, len, result->request);
295 delete result;
296}
297
298void
63be0a78 299DiskThreadsDiskFile::writeDone(int rvfd, int errflag, size_t len, RefCount<WriteRequest> request)
b9ae18aa 300{
301 assert (rvfd == fd);
302 static int loop_detect = 0;
b9ae18aa 303
304#if ASYNC_WRITE
305 /* Translate from errno to Squid disk error */
b9ae18aa 306
307 if (errflag)
a37ea9a1 308 errflag = errflag == ENOSPC ? DISK_NO_SPACE_LEFT : DISK_ERROR;
b9ae18aa 309 else
310 errflag = DISK_OK;
311
312#endif
313
4a7a3d56 314 debugs(79, 3, "DiskThreadsDiskFile::writeDone: FD " << fd << ", len " << len << ", err=" << errflag);
a37ea9a1 315
7f56277d
AJ
316 ++loop_detect;
317 assert(loop_detect < 10);
b9ae18aa 318
319 --inProgressIOs;
320
321 ioRequestor->writeCompleted(errflag, len, request);
322
323 --loop_detect;
324}
325
d6d0eb11 326/** \cond AUTODOCS_IGNORE */
b9ae18aa 327template <class RT>
328cbdata_type IoResult<RT>::CBDATA_IoResult = CBDATA_UNKNOWN;
d85b8894 329/** \endcond */
f53969cc 330