]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskDaemon/DiskdFile.cc
Removed CVS $ markers
[thirdparty/squid.git] / src / DiskIO / DiskDaemon / DiskdFile.cc
CommitLineData
b9ae18aa 1/*
b9ae18aa 2 * DEBUG: section 79 Squid-side DISKD I/O functions.
3 * AUTHOR: Duane Wessels
4 *
5 * SQUID Web Proxy Cache http://www.squid-cache.org/
6 * ----------------------------------------------------------
7 *
8 * Squid is the result of efforts by numerous individuals from
9 * the Internet community; see the CONTRIBUTORS file for full
10 * details. Many organizations have provided support for Squid's
11 * development; see the SPONSORS file for full details. Squid is
12 * Copyrighted (C) 2001 by the Regents of the University of
13 * California; see the COPYRIGHT file for full details. Squid
14 * incorporates software developed and/or copyrighted by other
15 * sources; see the CREDITS file for full details.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
26ac0430 21 *
b9ae18aa 22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26ac0430 26 *
b9ae18aa 27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
30 *
31 * CopyRight (c) 2003, Robert Collins <robertc@squid-cache.org>
32 */
33
582c2af2 34#include "squid.h"
b9ae18aa 35#include "DiskdFile.h"
36#include "ConfigOption.h"
37#include "diomsg.h"
b9ae18aa 38#include "DiskdIOStrategy.h"
39#include "DiskIO/IORequestor.h"
40#include "DiskIO/ReadRequest.h"
41#include "DiskIO/WriteRequest.h"
e4f1fdae 42#include "StatCounters.h"
3d41e53a
FC
43
44#include <sys/ipc.h>
45#include <sys/msg.h>
46#include <sys/shm.h>
47
b9ae18aa 48CBDATA_CLASS_INIT(DiskdFile);
49
50void *
63be0a78 51DiskdFile::operator new(size_t unused)
b9ae18aa 52{
53 CBDATA_INIT_TYPE(DiskdFile);
54 DiskdFile *result = cbdataAlloc(DiskdFile);
55 /* Mark result as being owned - we want the refcounter to do the delete
56 * call */
bf8fe701 57 debugs(79, 3, "diskdFile with base " << result << " allocating");
b9ae18aa 58 return result;
59}
60
61void
63be0a78 62DiskdFile::operator delete(void *address)
b9ae18aa 63{
b9ae18aa 64 DiskdFile *t = static_cast<DiskdFile *>(address);
bf8fe701 65 debugs(79, 3, "diskdFile with base " << t << " deleting");
aa625860 66 cbdataFree(t);
b9ae18aa 67}
68
63be0a78 69DiskdFile::DiskdFile(char const *aPath, DiskdIOStrategy *anIO) : errorOccured (false), IO(anIO),
b9ae18aa 70 inProgressIOs (0)
71{
72 assert (aPath);
bf8fe701 73 debugs(79, 3, "DiskdFile::DiskdFile: " << aPath);
b9ae18aa 74 path_ = xstrdup (aPath);
f207fe64
FC
75 id = diskd_stats.sio_id;
76 ++diskd_stats.sio_id;
b9ae18aa 77}
78
79DiskdFile::~DiskdFile()
80{
81 assert (inProgressIOs == 0);
82 safe_free (path_);
83}
84
85void
63be0a78 86DiskdFile::open(int flags, mode_t aMode, RefCount< IORequestor > callback)
b9ae18aa 87{
bf8fe701 88 debugs(79, 3, "DiskdFile::open: " << this << " opening for " << callback.getRaw());
b9ae18aa 89 assert (ioRequestor.getRaw() == NULL);
90 ioRequestor = callback;
91 assert (callback.getRaw());
92 mode = flags;
ee139403 93 ssize_t shm_offset;
b9ae18aa 94 char *buf = (char *)IO->shm.get(&shm_offset);
95 xstrncpy(buf, path_, SHMBUF_BLKSZ);
96 ioAway();
97 int x = IO->send(_MQD_OPEN,
98 id,
99 this,
100 strlen(buf) + 1,
101 mode,
102 shm_offset,
103 NULL);
104
105 if (x < 0) {
106 ioCompleted();
107 errorOccured = true;
108 // IO->shm.put (shm_offset);
109 ioRequestor->ioCompletedNotification();
110 ioRequestor = NULL;
111 }
112
cb4185f1 113 ++diskd_stats.open.ops;
b9ae18aa 114}
115
116void
63be0a78 117DiskdFile::create(int flags, mode_t aMode, RefCount< IORequestor > callback)
b9ae18aa 118{
bf8fe701 119 debugs(79, 3, "DiskdFile::create: " << this << " creating for " << callback.getRaw());
b9ae18aa 120 assert (ioRequestor.getRaw() == NULL);
121 ioRequestor = callback;
122 assert (callback.getRaw());
123 mode = flags;
ee139403 124 ssize_t shm_offset;
b9ae18aa 125 char *buf = (char *)IO->shm.get(&shm_offset);
126 xstrncpy(buf, path_, SHMBUF_BLKSZ);
127 ioAway();
128 int x = IO->send(_MQD_CREATE,
129 id,
130 this,
131 strlen(buf) + 1,
132 mode,
133 shm_offset,
134 NULL);
135
136 if (x < 0) {
137 ioCompleted();
138 errorOccured = true;
139 // IO->shm.put (shm_offset);
e0236918 140 debugs(79, DBG_IMPORTANT, "storeDiskdSend CREATE: " << xstrerror());
b9ae18aa 141 notifyClient();
142 ioRequestor = NULL;
143 return;
144 }
145
cb4185f1 146 ++diskd_stats.create.ops;
b9ae18aa 147}
148
149void
150DiskdFile::read(ReadRequest *aRead)
151{
152 assert (ioRequestor.getRaw() != NULL);
ee139403 153 ssize_t shm_offset;
b9ae18aa 154 char *rbuf = (char *)IO->shm.get(&shm_offset);
155 assert(rbuf);
156 ioAway();
157 int x = IO->send(_MQD_READ,
158 id,
159 this,
ee139403 160 aRead->len,
161 aRead->offset,
b9ae18aa 162 shm_offset,
163 aRead);
164
165 if (x < 0) {
166 ioCompleted();
167 errorOccured = true;
168 // IO->shm.put (shm_offset);
e0236918 169 debugs(79, DBG_IMPORTANT, "storeDiskdSend READ: " << xstrerror());
b9ae18aa 170 notifyClient();
171 ioRequestor = NULL;
172 return;
173 }
174
cb4185f1 175 ++diskd_stats.read.ops;
b9ae18aa 176}
177
178void
179DiskdFile::close()
180{
bf8fe701 181 debugs(79, 3, "DiskdFile::close: " << this << " closing for " << ioRequestor.getRaw());
b9ae18aa 182 assert (ioRequestor.getRaw());
183 ioAway();
184 int x = IO->send(_MQD_CLOSE,
185 id,
186 this,
187 0,
188 0,
189 -1,
190 NULL);
191
192 if (x < 0) {
193 ioCompleted();
194 errorOccured = true;
e0236918 195 debugs(79, DBG_IMPORTANT, "storeDiskdSend CLOSE: " << xstrerror());
b9ae18aa 196 notifyClient();
197 ioRequestor = NULL;
198 return;
199 }
200
cb4185f1 201 ++diskd_stats.close.ops;
b9ae18aa 202}
203
204bool
205DiskdFile::error() const
206{
207 return errorOccured;
208}
209
210bool
211DiskdFile::canRead() const
212{
213 return !error();
214}
215
216bool
217DiskdFile::canNotifyClient() const
218{
219 if (!ioRequestor.getRaw()) {
bf8fe701 220 debugs(79, 3, "DiskdFile::canNotifyClient: No ioRequestor to notify");
b9ae18aa 221 return false;
222 }
223
224 return true;
225}
226
227void
228DiskdFile::notifyClient()
229{
230 if (!canNotifyClient()) {
231 return;
232 }
233
234 ioRequestor->ioCompletedNotification();
235}
236
237void
238DiskdFile::completed(diomsg *M)
239{
240 assert (M->newstyle);
241
242 switch (M->mtype) {
243
244 case _MQD_OPEN:
245 openDone(M);
246 break;
247
248 case _MQD_CREATE:
249 createDone(M);
250 break;
251
252 case _MQD_CLOSE:
253 closeDone(M);
254 break;
255
256 case _MQD_READ:
257 readDone(M);
258 break;
259
260 case _MQD_WRITE:
261 writeDone(M);
262 break;
263
264 case _MQD_UNLINK:
265 assert (0);
266 break;
267
268 default:
269 assert(0);
270 break;
271 }
272}
273
274void
275DiskdFile::openDone(diomsg *M)
276{
e4f1fdae 277 ++statCounter.syscalls.disk.opens;
bf8fe701 278 debugs(79, 3, "storeDiskdOpenDone: status " << M->status);
b9ae18aa 279
280 if (M->status < 0) {
cb4185f1 281 ++diskd_stats.open.fail;
b9ae18aa 282 errorOccured = true;
283 } else {
cb4185f1 284 ++diskd_stats.open.success;
b9ae18aa 285 }
286
287 ioCompleted();
288 notifyClient();
289}
290
291void
292DiskdFile::createDone(diomsg *M)
293{
e4f1fdae 294 ++statCounter.syscalls.disk.opens;
bf8fe701 295 debugs(79, 3, "storeDiskdCreateDone: status " << M->status);
b9ae18aa 296
297 if (M->status < 0) {
cb4185f1 298 ++diskd_stats.create.fail;
b9ae18aa 299 errorOccured = true;
300 } else {
cb4185f1 301 ++diskd_stats.create.success;
b9ae18aa 302 }
303
304 ioCompleted();
305 notifyClient();
306}
307
308void
309DiskdFile::write(WriteRequest *aRequest)
310{
311 debugs(79, 3, "DiskdFile::write: this " << (void *)this << ", buf " << (void *)aRequest->buf << ", off " << aRequest->offset << ", len " << aRequest->len);
ee139403 312 ssize_t shm_offset;
b9ae18aa 313 char *sbuf = (char *)IO->shm.get(&shm_offset);
41d00cd3 314 memcpy(sbuf, aRequest->buf, aRequest->len);
b9ae18aa 315
316 if (aRequest->free_func)
317 aRequest->free_func(const_cast<char *>(aRequest->buf));
318
319 ioAway();
320
321 int x = IO->send(_MQD_WRITE,
322 id,
323 this,
ee139403 324 aRequest->len,
325 aRequest->offset,
b9ae18aa 326 shm_offset,
327 aRequest);
328
329 if (x < 0) {
3d0ac046 330 ioCompleted();
b9ae18aa 331 errorOccured = true;
e0236918 332 debugs(79, DBG_IMPORTANT, "storeDiskdSend WRITE: " << xstrerror());
b9ae18aa 333 // IO->shm.put (shm_offset);
334 notifyClient();
335 ioRequestor = NULL;
336 return;
337 }
338
cb4185f1 339 ++diskd_stats.write.ops;
b9ae18aa 340}
341
342void
343DiskdFile::ioAway()
344{
345 ++inProgressIOs;
346}
347
348void
349DiskdFile::ioCompleted()
350{
351 --inProgressIOs;
352}
353
354void
355DiskdFile::closeDone(diomsg * M)
356{
e4f1fdae 357 ++statCounter.syscalls.disk.closes;
bf8fe701 358 debugs(79, 3, "DiskdFile::closeDone: status " << M->status);
b9ae18aa 359
360 if (M->status < 0) {
cb4185f1 361 ++diskd_stats.close.fail;
b9ae18aa 362 errorOccured = true;
363 } else {
cb4185f1 364 ++diskd_stats.close.success;
b9ae18aa 365 }
366
367 ioCompleted();
368
369 if (canNotifyClient())
370 ioRequestor->closeCompleted();
371
372 ioRequestor = NULL;
373}
374
375void
376DiskdFile::readDone(diomsg * M)
377{
e4f1fdae 378 ++statCounter.syscalls.disk.reads;
bf8fe701 379 debugs(79, 3, "DiskdFile::readDone: status " << M->status);
b9ae18aa 380 assert (M->requestor);
381 ReadRequest::Pointer readRequest = dynamic_cast<ReadRequest *>(M->requestor);
382 /* remove the free protection */
383 readRequest->RefCountDereference();
384
385 if (M->status < 0) {
cb4185f1 386 ++diskd_stats.read.fail;
b9ae18aa 387 ioCompleted();
388 errorOccured = true;
389 ioRequestor->readCompleted(NULL, -1, DISK_ERROR, readRequest);
390 return;
391 }
392
cb4185f1 393 ++diskd_stats.read.success;
b9ae18aa 394
395 ioCompleted();
396 ioRequestor->readCompleted (IO->shm.buf + M->shm_offset, M->status, DISK_OK, readRequest);
397}
398
399void
400DiskdFile::writeDone(diomsg *M)
401{
e4f1fdae 402 ++statCounter.syscalls.disk.writes;
bf8fe701 403 debugs(79, 3, "storeDiskdWriteDone: status " << M->status);
b9ae18aa 404 assert (M->requestor);
405 WriteRequest::Pointer writeRequest = dynamic_cast<WriteRequest *>(M->requestor);
406 /* remove the free protection */
407 writeRequest->RefCountDereference();
408
409 if (M->status < 0) {
410 errorOccured = true;
cb4185f1 411 ++diskd_stats.write.fail;
b9ae18aa 412 ioCompleted();
413 ioRequestor->writeCompleted (DISK_ERROR,0, writeRequest);
414 return;
415 }
416
cb4185f1 417 ++diskd_stats.write.success;
b9ae18aa 418 ioCompleted();
419 ioRequestor->writeCompleted (DISK_OK,M->status, writeRequest);
420}
421
422bool
423DiskdFile::ioInProgress()const
424{
425 return inProgressIOs != 0;
426}