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