]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / src / DiskIO / DiskThreads / DiskThreadsDiskFile.cc
CommitLineData
b9ae18aa 1/*
262a0e14 2 * $Id$
b9ae18aa 3 *
4 * DEBUG: section 79 Disk IO Routines
5 * AUTHOR: Robert Collins
6 *
7 * SQUID Web Proxy Cache http://www.squid-cache.org/
8 * ----------------------------------------------------------
9 *
10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
26ac0430 23 *
b9ae18aa 24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
26ac0430 28 *
b9ae18aa 29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
32 *
33 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
34 */
35
36
f7f3304a 37#include "squid-old.h"
b9ae18aa 38#include "DiskThreadsDiskFile.h"
39#include "Store.h"
b9ae18aa 40#include "Generic.h"
41#include "DiskIO/IORequestor.h"
42#include "DiskIO/ReadRequest.h"
43#include "DiskIO/WriteRequest.h"
e4f1fdae 44#include "StatCounters.h"
b9ae18aa 45
46/* === PUBLIC =========================================================== */
47
48CBDATA_CLASS_INIT(DiskThreadsDiskFile);
49void *
50DiskThreadsDiskFile::operator new (size_t)
51{
52 CBDATA_INIT_TYPE(DiskThreadsDiskFile);
53 DiskThreadsDiskFile *result = cbdataAlloc(DiskThreadsDiskFile);
e65c313f 54 /*
55 * We used to call squidaio_init() here, but if the first transaction
56 * is to unlink a file (e.g., if Squid starts up over the disk space
57 * limit) then "squidaio" won't be initialized yet.
58 */
d06925a4 59
aa625860 60 return result;
b9ae18aa 61}
62
63void
63be0a78 64DiskThreadsDiskFile::operator delete(void *address)
b9ae18aa 65{
66 DiskThreadsDiskFile *t = static_cast<DiskThreadsDiskFile *>(address);
aa625860 67 cbdataFree(t);
b9ae18aa 68}
69
63be0a78 70DiskThreadsDiskFile::DiskThreadsDiskFile(char const *aPath, DiskThreadsIOStrategy *anIO):fd(-1), errorOccured (false), IO(anIO),
b9ae18aa 71 inProgressIOs (0)
72{
73 assert (aPath);
bf8fe701 74 debugs(79, 3, "UFSFile::UFSFile: " << aPath);
b9ae18aa 75 path_ = xstrdup (aPath);
76}
77
78DiskThreadsDiskFile::~DiskThreadsDiskFile()
79{
80 safe_free (path_);
81 doClose();
82}
83
84void
63be0a78 85DiskThreadsDiskFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
b9ae18aa 86{
e4f1fdae 87 ++statCounter.syscalls.disk.opens;
b9ae18aa 88#if !ASYNC_OPEN
89
90 fd = file_open(path_, flags);
91
92 if (fd < 0) {
bf8fe701 93 debugs(79, 3, "DiskThreadsDiskFile::open: got failure (" << errno << ")");
b9ae18aa 94 errorOccured = true;
95 return;
96 }
97
98#endif
99 Opening_FD++;
100
101 ioRequestor = callback;
102
103 ++inProgressIOs;
104
105#if ASYNC_OPEN
106
107 aioOpen(path_, flags, mode, DiskThreadsDiskFile::OpenDone, this);
108
109#else
110
111 openDone(fd, NULL, fd, 0);
112
113#endif
114}
115
116void
117DiskThreadsDiskFile::read(ReadRequest * request)
118{
119 debugs(79, 3, "DiskThreadsDiskFile::read: " << this << ", size " << request->len);
120 assert (fd > -1);
121 assert (ioRequestor.getRaw());
e4f1fdae 122 ++statCounter.syscalls.disk.reads;
b9ae18aa 123 ++inProgressIOs;
124#if ASYNC_READ
125
126 aioRead(fd, request->offset, request->len, ReadDone, new IoResult<ReadRequest>(this, request));
127#else
128
129 file_read(fd, request->buf, request->len, request->offset, ReadDone, new IoResult<ReadRequest>(this, request));
130#endif
131}
132
133void
63be0a78 134DiskThreadsDiskFile::create(int flags, mode_t mode, RefCount<IORequestor> callback)
b9ae18aa 135{
e4f1fdae 136 ++statCounter.syscalls.disk.opens;
b9ae18aa 137#if !ASYNC_CREATE
138
139 int fd = file_open(path_, flags);
140
141 if (fd < 0) {
bf8fe701 142 debugs(79, 3, "DiskThreadsDiskFile::create: got failure (" << errno << ")");
b9ae18aa 143 errorOccured = true;
144 return;
145 }
146
147#endif
148 Opening_FD++;
149
150 ioRequestor = callback;
151
152 ++inProgressIOs;
153
154#if ASYNC_CREATE
155
156 aioOpen(path_, flags, mode, DiskThreadsDiskFile::OpenDone, this);
157
158#else
159
160 openDone (fd, NULL, fd, 0);
161
162#endif
163}
164
165bool
166DiskThreadsDiskFile::error() const
167{
168 return errorOccured;
169}
170
171void
172DiskThreadsDiskFile::OpenDone(int fd, void *cbdata, const char *buf, int aio_return, int aio_errno)
173{
174 DiskThreadsDiskFile *myFile = static_cast<DiskThreadsDiskFile *>(cbdata);
175 myFile->openDone (fd, buf, aio_return, aio_errno);
176}
177
178void
179DiskThreadsDiskFile::openDone(int unused, const char *unused2, int anFD, int errflag)
180{
bf8fe701 181 debugs(79, 3, "DiskThreadsDiskFile::openDone: FD " << anFD << ", errflag " << errflag);
b9ae18aa 182 Opening_FD--;
183
184 fd = anFD;
185
186 if (errflag || fd < 0) {
187 errno = errflag;
bf8fe701 188 debugs(79, 0, "DiskThreadsDiskFile::openDone: " << xstrerror());
189 debugs(79, 1, "\t" << path_);
b9ae18aa 190 errorOccured = true;
191 } else {
192 store_open_disk_fd++;
193 commSetCloseOnExec(fd);
194 fd_open(fd, FD_FILE, path_);
195 }
196
b9ae18aa 197 IORequestor::Pointer t = ioRequestor;
198 --inProgressIOs;
199 t->ioCompletedNotification();
ac97716e 200
bf8fe701 201 debugs(79, 3, "DiskThreadsDiskFile::openDone: exiting");
b9ae18aa 202}
203
204void DiskThreadsDiskFile::doClose()
205{
206 if (fd > -1) {
e4f1fdae 207 ++statCounter.syscalls.disk.closes;
d06925a4 208#if ASYNC_CLOSE
209
b9ae18aa 210 aioClose(fd);
211 fd_close(fd);
d06925a4 212#else
213
214 aioCancel(fd);
215 file_close(fd);
216#endif
217
b9ae18aa 218 store_open_disk_fd--;
219 fd = -1;
220 }
221}
222
223void
63be0a78 224DiskThreadsDiskFile::close()
b9ae18aa 225{
bf8fe701 226 debugs(79, 3, "DiskThreadsDiskFile::close: " << this << " closing for " << ioRequestor.getRaw());
b9ae18aa 227
228 if (!ioInProgress()) {
229 doClose();
ac97716e 230 assert (ioRequestor != NULL);
b9ae18aa 231 ioRequestor->closeCompleted();
ac97716e 232 return;
233 } else {
234 debugs(79,0,HERE << "DiskThreadsDiskFile::close: " <<
235 "did NOT close because ioInProgress() is true. now what?");
b9ae18aa 236 }
237}
238
239bool
240DiskThreadsDiskFile::canRead() const
241{
bf8fe701 242 debugs(79, 3, "DiskThreadsDiskFile::canRead: fd is " << fd);
b9ae18aa 243 return fd > -1;
244}
245
246void
247DiskThreadsDiskFile::write(WriteRequest * writeRequest)
248{
bf8fe701 249 debugs(79, 3, "DiskThreadsDiskFile::write: FD " << fd);
e4f1fdae 250 ++statCounter.syscalls.disk.writes;
b9ae18aa 251 ++inProgressIOs;
252#if ASYNC_WRITE
253
254 aioWrite(fd, writeRequest->offset, (char *)writeRequest->buf, writeRequest->len, WriteDone, new IoResult<WriteRequest>(this, writeRequest),
255 writeRequest->free_func);
256#else
257
258 file_write(fd, writeRequest->offset, (char *)writeRequest->buf, writeRequest->len, WriteDone, new IoResult<WriteRequest>(this, writeRequest),
259 writeRequest->free_func);
260#endif
261}
262
263bool
264DiskThreadsDiskFile::canWrite() const
265{
266 return fd > -1;
267}
268
269bool
63be0a78 270DiskThreadsDiskFile::ioInProgress() const
b9ae18aa 271{
272 return inProgressIOs > 0;
273}
274
275/* === STATIC =========================================================== */
276
277#if ASYNC_READ
278void
279DiskThreadsDiskFile::ReadDone(int fd, void *my_data, const char *buf, int len, int errflag)
280#else
281void
282DiskThreadsDiskFile::ReadDone(int fd, const char *buf, int len, int errflag, void *my_data)
283#endif
284{
285 IoResult<ReadRequest> * result = static_cast<IoResult<ReadRequest> *>(my_data);
286 assert (result);
287 result->file->readDone(fd, buf, len, errflag, result->request);
288 delete result;
289}
290
291void
63be0a78 292DiskThreadsDiskFile::readDone(int rvfd, const char *buf, int len, int errflag, RefCount<ReadRequest> request)
b9ae18aa 293{
bf8fe701 294 debugs(79, 3, "DiskThreadsDiskFile::readDone: FD " << rvfd);
b9ae18aa 295 assert (fd == rvfd);
296
297 ssize_t rlen;
298
299 if (errflag) {
bf8fe701 300 debugs(79, 3, "DiskThreadsDiskFile::readDone: got failure (" << errflag << ")");
b9ae18aa 301 rlen = -1;
302 } else {
303 rlen = (ssize_t) len;
304 }
305
306#if ASYNC_READ
307 /* translate errflag from errno to Squid disk error */
308 errno = errflag;
309
310 if (errflag)
311 errflag = DISK_ERROR;
312 else
313 errflag = DISK_OK;
314
315#else
316
317 if (errflag == DISK_EOF)
318 errflag = DISK_OK; /* EOF is signalled by len == 0, not errors... */
319
320#endif
321
322 --inProgressIOs;
323
324 ioRequestor->readCompleted(buf, rlen, errflag, request);
325}
326
327void
328DiskThreadsDiskFile::
329#if ASYNC_WRITE
a37ea9a1 330WriteDone(int fd, void *my_data, const char *buf, int len, int errflag)
b9ae18aa 331#else
332WriteDone(int fd, int errflag, size_t len, void *my_data)
333#endif
334{
335 IoResult<WriteRequest> * result = static_cast<IoResult<WriteRequest> *>(my_data);
336 assert (result);
337 result->file->writeDone(fd, errflag, len, result->request);
338 delete result;
339}
340
341void
63be0a78 342DiskThreadsDiskFile::writeDone(int rvfd, int errflag, size_t len, RefCount<WriteRequest> request)
b9ae18aa 343{
344 assert (rvfd == fd);
345 static int loop_detect = 0;
b9ae18aa 346
347#if ASYNC_WRITE
348 /* Translate from errno to Squid disk error */
b9ae18aa 349
350 if (errflag)
a37ea9a1 351 errflag = errflag == ENOSPC ? DISK_NO_SPACE_LEFT : DISK_ERROR;
b9ae18aa 352 else
353 errflag = DISK_OK;
354
355#endif
356
4a7a3d56 357 debugs(79, 3, "DiskThreadsDiskFile::writeDone: FD " << fd << ", len " << len << ", err=" << errflag);
a37ea9a1 358
b9ae18aa 359 assert(++loop_detect < 10);
360
361 --inProgressIOs;
362
363 ioRequestor->writeCompleted(errflag, len, request);
364
365 --loop_detect;
366}
367
d85b8894 368/** \cond AUTODOCS-IGNORE */
b9ae18aa 369template <class RT>
370cbdata_type IoResult<RT>::CBDATA_IoResult = CBDATA_UNKNOWN;
d85b8894 371/** \endcond */
b9ae18aa 372
373template<class RT>
374void *
63be0a78 375IoResult<RT>::operator new(size_t unused)
b9ae18aa 376{
377 CBDATA_INIT_TYPE(IoResult);
378 IoResult<RT> *result = cbdataAlloc(IoResult);
379 return result;
380}
381
382template <class RT>
383void
63be0a78 384IoResult<RT>::operator delete(void *address)
b9ae18aa 385{
386 cbdataFree(address);
387}