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