]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/DiskDaemon/DiskdFile.cc
Merged Postfix-Prefix branch: refactor inc/decrement operators from postfix to prefix...
[thirdparty/squid.git] / src / DiskIO / DiskDaemon / DiskdFile.cc
1 /*
2 * $Id$
3 *
4 * DEBUG: section 79 Squid-side DISKD I/O functions.
5 * AUTHOR: Duane Wessels
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.
23 *
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.
28 *
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 #include "squid-old.h"
37
38 #include <sys/ipc.h>
39 #include <sys/msg.h>
40 #include <sys/shm.h>
41
42 #include "DiskdFile.h"
43 #include "ConfigOption.h"
44 #include "diomsg.h"
45
46 #include "DiskdIOStrategy.h"
47 #include "DiskIO/IORequestor.h"
48 #include "DiskIO/ReadRequest.h"
49 #include "DiskIO/WriteRequest.h"
50 #include "StatCounters.h"
51 CBDATA_CLASS_INIT(DiskdFile);
52
53 void *
54 DiskdFile::operator new(size_t unused)
55 {
56 CBDATA_INIT_TYPE(DiskdFile);
57 DiskdFile *result = cbdataAlloc(DiskdFile);
58 /* Mark result as being owned - we want the refcounter to do the delete
59 * call */
60 debugs(79, 3, "diskdFile with base " << result << " allocating");
61 return result;
62 }
63
64 void
65 DiskdFile::operator delete(void *address)
66 {
67 DiskdFile *t = static_cast<DiskdFile *>(address);
68 debugs(79, 3, "diskdFile with base " << t << " deleting");
69 cbdataFree(t);
70 }
71
72 DiskdFile::DiskdFile(char const *aPath, DiskdIOStrategy *anIO) : errorOccured (false), IO(anIO),
73 inProgressIOs (0)
74 {
75 assert (aPath);
76 debugs(79, 3, "DiskdFile::DiskdFile: " << aPath);
77 path_ = xstrdup (aPath);
78 id = diskd_stats.sio_id;
79 ++diskd_stats.sio_id;
80 }
81
82 DiskdFile::~DiskdFile()
83 {
84 assert (inProgressIOs == 0);
85 safe_free (path_);
86 }
87
88 void
89 DiskdFile::open(int flags, mode_t aMode, RefCount< IORequestor > callback)
90 {
91 debugs(79, 3, "DiskdFile::open: " << this << " opening for " << callback.getRaw());
92 assert (ioRequestor.getRaw() == NULL);
93 ioRequestor = callback;
94 assert (callback.getRaw());
95 mode = flags;
96 ssize_t shm_offset;
97 char *buf = (char *)IO->shm.get(&shm_offset);
98 xstrncpy(buf, path_, SHMBUF_BLKSZ);
99 ioAway();
100 int x = IO->send(_MQD_OPEN,
101 id,
102 this,
103 strlen(buf) + 1,
104 mode,
105 shm_offset,
106 NULL);
107
108 if (x < 0) {
109 ioCompleted();
110 errorOccured = true;
111 // IO->shm.put (shm_offset);
112 ioRequestor->ioCompletedNotification();
113 ioRequestor = NULL;
114 }
115
116 ++diskd_stats.open.ops;
117 }
118
119 void
120 DiskdFile::create(int flags, mode_t aMode, RefCount< IORequestor > callback)
121 {
122 debugs(79, 3, "DiskdFile::create: " << this << " creating for " << callback.getRaw());
123 assert (ioRequestor.getRaw() == NULL);
124 ioRequestor = callback;
125 assert (callback.getRaw());
126 mode = flags;
127 ssize_t shm_offset;
128 char *buf = (char *)IO->shm.get(&shm_offset);
129 xstrncpy(buf, path_, SHMBUF_BLKSZ);
130 ioAway();
131 int x = IO->send(_MQD_CREATE,
132 id,
133 this,
134 strlen(buf) + 1,
135 mode,
136 shm_offset,
137 NULL);
138
139 if (x < 0) {
140 ioCompleted();
141 errorOccured = true;
142 // IO->shm.put (shm_offset);
143 debugs(79, 1, "storeDiskdSend CREATE: " << xstrerror());
144 notifyClient();
145 ioRequestor = NULL;
146 return;
147 }
148
149 ++diskd_stats.create.ops;
150 }
151
152 void
153 DiskdFile::read(ReadRequest *aRead)
154 {
155 assert (ioRequestor.getRaw() != NULL);
156 ssize_t shm_offset;
157 char *rbuf = (char *)IO->shm.get(&shm_offset);
158 assert(rbuf);
159 ioAway();
160 int x = IO->send(_MQD_READ,
161 id,
162 this,
163 aRead->len,
164 aRead->offset,
165 shm_offset,
166 aRead);
167
168 if (x < 0) {
169 ioCompleted();
170 errorOccured = true;
171 // IO->shm.put (shm_offset);
172 debugs(79, 1, "storeDiskdSend READ: " << xstrerror());
173 notifyClient();
174 ioRequestor = NULL;
175 return;
176 }
177
178 ++diskd_stats.read.ops;
179 }
180
181 void
182 DiskdFile::close()
183 {
184 debugs(79, 3, "DiskdFile::close: " << this << " closing for " << ioRequestor.getRaw());
185 assert (ioRequestor.getRaw());
186 ioAway();
187 int x = IO->send(_MQD_CLOSE,
188 id,
189 this,
190 0,
191 0,
192 -1,
193 NULL);
194
195 if (x < 0) {
196 ioCompleted();
197 errorOccured = true;
198 debugs(79, 1, "storeDiskdSend CLOSE: " << xstrerror());
199 notifyClient();
200 ioRequestor = NULL;
201 return;
202 }
203
204 ++diskd_stats.close.ops;
205 }
206
207 bool
208 DiskdFile::error() const
209 {
210 return errorOccured;
211 }
212
213 bool
214 DiskdFile::canRead() const
215 {
216 return !error();
217 }
218
219 bool
220 DiskdFile::canNotifyClient() const
221 {
222 if (!ioRequestor.getRaw()) {
223 debugs(79, 3, "DiskdFile::canNotifyClient: No ioRequestor to notify");
224 return false;
225 }
226
227 return true;
228 }
229
230 void
231 DiskdFile::notifyClient()
232 {
233 if (!canNotifyClient()) {
234 return;
235 }
236
237 ioRequestor->ioCompletedNotification();
238 }
239
240 void
241 DiskdFile::completed(diomsg *M)
242 {
243 assert (M->newstyle);
244
245 switch (M->mtype) {
246
247 case _MQD_OPEN:
248 openDone(M);
249 break;
250
251 case _MQD_CREATE:
252 createDone(M);
253 break;
254
255 case _MQD_CLOSE:
256 closeDone(M);
257 break;
258
259 case _MQD_READ:
260 readDone(M);
261 break;
262
263 case _MQD_WRITE:
264 writeDone(M);
265 break;
266
267 case _MQD_UNLINK:
268 assert (0);
269 break;
270
271 default:
272 assert(0);
273 break;
274 }
275 }
276
277 void
278 DiskdFile::openDone(diomsg *M)
279 {
280 ++statCounter.syscalls.disk.opens;
281 debugs(79, 3, "storeDiskdOpenDone: status " << M->status);
282
283 if (M->status < 0) {
284 ++diskd_stats.open.fail;
285 errorOccured = true;
286 } else {
287 ++diskd_stats.open.success;
288 }
289
290 ioCompleted();
291 notifyClient();
292 }
293
294 void
295 DiskdFile::createDone(diomsg *M)
296 {
297 ++statCounter.syscalls.disk.opens;
298 debugs(79, 3, "storeDiskdCreateDone: status " << M->status);
299
300 if (M->status < 0) {
301 ++diskd_stats.create.fail;
302 errorOccured = true;
303 } else {
304 ++diskd_stats.create.success;
305 }
306
307 ioCompleted();
308 notifyClient();
309 }
310
311 void
312 DiskdFile::write(WriteRequest *aRequest)
313 {
314 debugs(79, 3, "DiskdFile::write: this " << (void *)this << ", buf " << (void *)aRequest->buf << ", off " << aRequest->offset << ", len " << aRequest->len);
315 ssize_t shm_offset;
316 char *sbuf = (char *)IO->shm.get(&shm_offset);
317 memcpy(sbuf, aRequest->buf, aRequest->len);
318
319 if (aRequest->free_func)
320 aRequest->free_func(const_cast<char *>(aRequest->buf));
321
322 ioAway();
323
324 int x = IO->send(_MQD_WRITE,
325 id,
326 this,
327 aRequest->len,
328 aRequest->offset,
329 shm_offset,
330 aRequest);
331
332 if (x < 0) {
333 ioCompleted();
334 errorOccured = true;
335 debugs(79, 1, "storeDiskdSend WRITE: " << xstrerror());
336 // IO->shm.put (shm_offset);
337 notifyClient();
338 ioRequestor = NULL;
339 return;
340 }
341
342 ++diskd_stats.write.ops;
343 }
344
345 void
346 DiskdFile::ioAway()
347 {
348 ++inProgressIOs;
349 }
350
351 void
352 DiskdFile::ioCompleted()
353 {
354 --inProgressIOs;
355 }
356
357 void
358 DiskdFile::closeDone(diomsg * M)
359 {
360 ++statCounter.syscalls.disk.closes;
361 debugs(79, 3, "DiskdFile::closeDone: status " << M->status);
362
363 if (M->status < 0) {
364 ++diskd_stats.close.fail;
365 errorOccured = true;
366 } else {
367 ++diskd_stats.close.success;
368 }
369
370 ioCompleted();
371
372 if (canNotifyClient())
373 ioRequestor->closeCompleted();
374
375 ioRequestor = NULL;
376 }
377
378 void
379 DiskdFile::readDone(diomsg * M)
380 {
381 ++statCounter.syscalls.disk.reads;
382 debugs(79, 3, "DiskdFile::readDone: status " << M->status);
383 assert (M->requestor);
384 ReadRequest::Pointer readRequest = dynamic_cast<ReadRequest *>(M->requestor);
385 /* remove the free protection */
386 readRequest->RefCountDereference();
387
388 if (M->status < 0) {
389 ++diskd_stats.read.fail;
390 ioCompleted();
391 errorOccured = true;
392 ioRequestor->readCompleted(NULL, -1, DISK_ERROR, readRequest);
393 return;
394 }
395
396 ++diskd_stats.read.success;
397
398 ioCompleted();
399 ioRequestor->readCompleted (IO->shm.buf + M->shm_offset, M->status, DISK_OK, readRequest);
400 }
401
402 void
403 DiskdFile::writeDone(diomsg *M)
404 {
405 ++statCounter.syscalls.disk.writes;
406 debugs(79, 3, "storeDiskdWriteDone: status " << M->status);
407 assert (M->requestor);
408 WriteRequest::Pointer writeRequest = dynamic_cast<WriteRequest *>(M->requestor);
409 /* remove the free protection */
410 writeRequest->RefCountDereference();
411
412 if (M->status < 0) {
413 errorOccured = true;
414 ++diskd_stats.write.fail;
415 ioCompleted();
416 ioRequestor->writeCompleted (DISK_ERROR,0, writeRequest);
417 return;
418 }
419
420 ++diskd_stats.write.success;
421 ioCompleted();
422 ioRequestor->writeCompleted (DISK_OK,M->status, writeRequest);
423 }
424
425 bool
426 DiskdFile::ioInProgress()const
427 {
428 return inProgressIOs != 0;
429 }