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