]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskDaemon/DiskdFile.cc
Bug 3610: peername_regex ACL
[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
f7f3304a 36#include "squid-old.h"
b9ae18aa 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"
e4f1fdae 50#include "StatCounters.h"
b9ae18aa 51CBDATA_CLASS_INIT(DiskdFile);
52
53void *
63be0a78 54DiskdFile::operator new(size_t unused)
b9ae18aa 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 */
bf8fe701 60 debugs(79, 3, "diskdFile with base " << result << " allocating");
b9ae18aa 61 return result;
62}
63
64void
63be0a78 65DiskdFile::operator delete(void *address)
b9ae18aa 66{
b9ae18aa 67 DiskdFile *t = static_cast<DiskdFile *>(address);
bf8fe701 68 debugs(79, 3, "diskdFile with base " << t << " deleting");
aa625860 69 cbdataFree(t);
b9ae18aa 70}
71
63be0a78 72DiskdFile::DiskdFile(char const *aPath, DiskdIOStrategy *anIO) : errorOccured (false), IO(anIO),
b9ae18aa 73 inProgressIOs (0)
74{
75 assert (aPath);
bf8fe701 76 debugs(79, 3, "DiskdFile::DiskdFile: " << aPath);
b9ae18aa 77 path_ = xstrdup (aPath);
f207fe64
FC
78 id = diskd_stats.sio_id;
79 ++diskd_stats.sio_id;
b9ae18aa 80}
81
82DiskdFile::~DiskdFile()
83{
84 assert (inProgressIOs == 0);
85 safe_free (path_);
86}
87
88void
63be0a78 89DiskdFile::open(int flags, mode_t aMode, RefCount< IORequestor > callback)
b9ae18aa 90{
bf8fe701 91 debugs(79, 3, "DiskdFile::open: " << this << " opening for " << callback.getRaw());
b9ae18aa 92 assert (ioRequestor.getRaw() == NULL);
93 ioRequestor = callback;
94 assert (callback.getRaw());
95 mode = flags;
ee139403 96 ssize_t shm_offset;
b9ae18aa 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
cb4185f1 116 ++diskd_stats.open.ops;
b9ae18aa 117}
118
119void
63be0a78 120DiskdFile::create(int flags, mode_t aMode, RefCount< IORequestor > callback)
b9ae18aa 121{
bf8fe701 122 debugs(79, 3, "DiskdFile::create: " << this << " creating for " << callback.getRaw());
b9ae18aa 123 assert (ioRequestor.getRaw() == NULL);
124 ioRequestor = callback;
125 assert (callback.getRaw());
126 mode = flags;
ee139403 127 ssize_t shm_offset;
b9ae18aa 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);
e0236918 143 debugs(79, DBG_IMPORTANT, "storeDiskdSend CREATE: " << xstrerror());
b9ae18aa 144 notifyClient();
145 ioRequestor = NULL;
146 return;
147 }
148
cb4185f1 149 ++diskd_stats.create.ops;
b9ae18aa 150}
151
152void
153DiskdFile::read(ReadRequest *aRead)
154{
155 assert (ioRequestor.getRaw() != NULL);
ee139403 156 ssize_t shm_offset;
b9ae18aa 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,
ee139403 163 aRead->len,
164 aRead->offset,
b9ae18aa 165 shm_offset,
166 aRead);
167
168 if (x < 0) {
169 ioCompleted();
170 errorOccured = true;
171 // IO->shm.put (shm_offset);
e0236918 172 debugs(79, DBG_IMPORTANT, "storeDiskdSend READ: " << xstrerror());
b9ae18aa 173 notifyClient();
174 ioRequestor = NULL;
175 return;
176 }
177
cb4185f1 178 ++diskd_stats.read.ops;
b9ae18aa 179}
180
181void
182DiskdFile::close()
183{
bf8fe701 184 debugs(79, 3, "DiskdFile::close: " << this << " closing for " << ioRequestor.getRaw());
b9ae18aa 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;
e0236918 198 debugs(79, DBG_IMPORTANT, "storeDiskdSend CLOSE: " << xstrerror());
b9ae18aa 199 notifyClient();
200 ioRequestor = NULL;
201 return;
202 }
203
cb4185f1 204 ++diskd_stats.close.ops;
b9ae18aa 205}
206
207bool
208DiskdFile::error() const
209{
210 return errorOccured;
211}
212
213bool
214DiskdFile::canRead() const
215{
216 return !error();
217}
218
219bool
220DiskdFile::canNotifyClient() const
221{
222 if (!ioRequestor.getRaw()) {
bf8fe701 223 debugs(79, 3, "DiskdFile::canNotifyClient: No ioRequestor to notify");
b9ae18aa 224 return false;
225 }
226
227 return true;
228}
229
230void
231DiskdFile::notifyClient()
232{
233 if (!canNotifyClient()) {
234 return;
235 }
236
237 ioRequestor->ioCompletedNotification();
238}
239
240void
241DiskdFile::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
277void
278DiskdFile::openDone(diomsg *M)
279{
e4f1fdae 280 ++statCounter.syscalls.disk.opens;
bf8fe701 281 debugs(79, 3, "storeDiskdOpenDone: status " << M->status);
b9ae18aa 282
283 if (M->status < 0) {
cb4185f1 284 ++diskd_stats.open.fail;
b9ae18aa 285 errorOccured = true;
286 } else {
cb4185f1 287 ++diskd_stats.open.success;
b9ae18aa 288 }
289
290 ioCompleted();
291 notifyClient();
292}
293
294void
295DiskdFile::createDone(diomsg *M)
296{
e4f1fdae 297 ++statCounter.syscalls.disk.opens;
bf8fe701 298 debugs(79, 3, "storeDiskdCreateDone: status " << M->status);
b9ae18aa 299
300 if (M->status < 0) {
cb4185f1 301 ++diskd_stats.create.fail;
b9ae18aa 302 errorOccured = true;
303 } else {
cb4185f1 304 ++diskd_stats.create.success;
b9ae18aa 305 }
306
307 ioCompleted();
308 notifyClient();
309}
310
311void
312DiskdFile::write(WriteRequest *aRequest)
313{
314 debugs(79, 3, "DiskdFile::write: this " << (void *)this << ", buf " << (void *)aRequest->buf << ", off " << aRequest->offset << ", len " << aRequest->len);
ee139403 315 ssize_t shm_offset;
b9ae18aa 316 char *sbuf = (char *)IO->shm.get(&shm_offset);
41d00cd3 317 memcpy(sbuf, aRequest->buf, aRequest->len);
b9ae18aa 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,
ee139403 327 aRequest->len,
328 aRequest->offset,
b9ae18aa 329 shm_offset,
330 aRequest);
331
332 if (x < 0) {
3d0ac046 333 ioCompleted();
b9ae18aa 334 errorOccured = true;
e0236918 335 debugs(79, DBG_IMPORTANT, "storeDiskdSend WRITE: " << xstrerror());
b9ae18aa 336 // IO->shm.put (shm_offset);
337 notifyClient();
338 ioRequestor = NULL;
339 return;
340 }
341
cb4185f1 342 ++diskd_stats.write.ops;
b9ae18aa 343}
344
345void
346DiskdFile::ioAway()
347{
348 ++inProgressIOs;
349}
350
351void
352DiskdFile::ioCompleted()
353{
354 --inProgressIOs;
355}
356
357void
358DiskdFile::closeDone(diomsg * M)
359{
e4f1fdae 360 ++statCounter.syscalls.disk.closes;
bf8fe701 361 debugs(79, 3, "DiskdFile::closeDone: status " << M->status);
b9ae18aa 362
363 if (M->status < 0) {
cb4185f1 364 ++diskd_stats.close.fail;
b9ae18aa 365 errorOccured = true;
366 } else {
cb4185f1 367 ++diskd_stats.close.success;
b9ae18aa 368 }
369
370 ioCompleted();
371
372 if (canNotifyClient())
373 ioRequestor->closeCompleted();
374
375 ioRequestor = NULL;
376}
377
378void
379DiskdFile::readDone(diomsg * M)
380{
e4f1fdae 381 ++statCounter.syscalls.disk.reads;
bf8fe701 382 debugs(79, 3, "DiskdFile::readDone: status " << M->status);
b9ae18aa 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) {
cb4185f1 389 ++diskd_stats.read.fail;
b9ae18aa 390 ioCompleted();
391 errorOccured = true;
392 ioRequestor->readCompleted(NULL, -1, DISK_ERROR, readRequest);
393 return;
394 }
395
cb4185f1 396 ++diskd_stats.read.success;
b9ae18aa 397
398 ioCompleted();
399 ioRequestor->readCompleted (IO->shm.buf + M->shm_offset, M->status, DISK_OK, readRequest);
400}
401
402void
403DiskdFile::writeDone(diomsg *M)
404{
e4f1fdae 405 ++statCounter.syscalls.disk.writes;
bf8fe701 406 debugs(79, 3, "storeDiskdWriteDone: status " << M->status);
b9ae18aa 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;
cb4185f1 414 ++diskd_stats.write.fail;
b9ae18aa 415 ioCompleted();
416 ioRequestor->writeCompleted (DISK_ERROR,0, writeRequest);
417 return;
418 }
419
cb4185f1 420 ++diskd_stats.write.success;
b9ae18aa 421 ioCompleted();
422 ioRequestor->writeCompleted (DISK_OK,M->status, writeRequest);
423}
424
425bool
426DiskdFile::ioInProgress()const
427{
428 return inProgressIOs != 0;
429}