]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskDaemon/DiskdFile.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / DiskIO / DiskDaemon / DiskdFile.cc
CommitLineData
b9ae18aa 1/*
bde978a6 2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
b9ae18aa 3 *
bbc27441
AJ
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.
b9ae18aa 7 */
8
bbc27441
AJ
9/* DEBUG: section 79 Squid-side DISKD I/O functions. */
10
582c2af2 11#include "squid.h"
b9ae18aa 12#include "ConfigOption.h"
13#include "diomsg.h"
602d9612 14#include "DiskdFile.h"
b9ae18aa 15#include "DiskdIOStrategy.h"
16#include "DiskIO/IORequestor.h"
17#include "DiskIO/ReadRequest.h"
18#include "DiskIO/WriteRequest.h"
e4f1fdae 19#include "StatCounters.h"
3d41e53a 20
d440d5a4 21#if HAVE_SYS_IPC_H
3d41e53a 22#include <sys/ipc.h>
d440d5a4
AJ
23#endif
24#if HAVE_SYS_MSG_H
3d41e53a 25#include <sys/msg.h>
d440d5a4
AJ
26#endif
27#if HAVE_SYS_SHM_H
3d41e53a 28#include <sys/shm.h>
d440d5a4 29#endif
3d41e53a 30
b9ae18aa 31CBDATA_CLASS_INIT(DiskdFile);
32
e19994df 33DiskdFile::DiskdFile(char const *aPath, DiskdIOStrategy *anIO) :
f53969cc
SM
34 errorOccured(false),
35 IO(anIO),
36 mode(0),
37 inProgressIOs(0)
b9ae18aa 38{
86c63190 39 assert(aPath);
bf8fe701 40 debugs(79, 3, "DiskdFile::DiskdFile: " << aPath);
86c63190 41 path_ = xstrdup(aPath);
f207fe64
FC
42 id = diskd_stats.sio_id;
43 ++diskd_stats.sio_id;
b9ae18aa 44}
45
46DiskdFile::~DiskdFile()
47{
86c63190 48 assert(inProgressIOs == 0);
b9ae18aa 49 safe_free (path_);
50}
51
52void
ced8def3 53DiskdFile::open(int flags, mode_t, RefCount<IORequestor> callback)
b9ae18aa 54{
bf8fe701 55 debugs(79, 3, "DiskdFile::open: " << this << " opening for " << callback.getRaw());
86c63190 56 assert(ioRequestor.getRaw() == NULL);
b9ae18aa 57 ioRequestor = callback;
86c63190 58 assert(callback.getRaw());
b9ae18aa 59 mode = flags;
ee139403 60 ssize_t shm_offset;
b9ae18aa 61 char *buf = (char *)IO->shm.get(&shm_offset);
62 xstrncpy(buf, path_, SHMBUF_BLKSZ);
63 ioAway();
64 int x = IO->send(_MQD_OPEN,
65 id,
66 this,
67 strlen(buf) + 1,
68 mode,
69 shm_offset,
70 NULL);
71
72 if (x < 0) {
73 ioCompleted();
74 errorOccured = true;
75 // IO->shm.put (shm_offset);
76 ioRequestor->ioCompletedNotification();
77 ioRequestor = NULL;
78 }
79
cb4185f1 80 ++diskd_stats.open.ops;
b9ae18aa 81}
82
83void
ced8def3 84DiskdFile::create(int flags, mode_t, RefCount<IORequestor> callback)
b9ae18aa 85{
bf8fe701 86 debugs(79, 3, "DiskdFile::create: " << this << " creating for " << callback.getRaw());
b9ae18aa 87 assert (ioRequestor.getRaw() == NULL);
88 ioRequestor = callback;
89 assert (callback.getRaw());
90 mode = flags;
ee139403 91 ssize_t shm_offset;
b9ae18aa 92 char *buf = (char *)IO->shm.get(&shm_offset);
93 xstrncpy(buf, path_, SHMBUF_BLKSZ);
94 ioAway();
95 int x = IO->send(_MQD_CREATE,
96 id,
97 this,
98 strlen(buf) + 1,
99 mode,
100 shm_offset,
101 NULL);
102
103 if (x < 0) {
104 ioCompleted();
105 errorOccured = true;
106 // IO->shm.put (shm_offset);
e0236918 107 debugs(79, DBG_IMPORTANT, "storeDiskdSend CREATE: " << xstrerror());
b9ae18aa 108 notifyClient();
109 ioRequestor = NULL;
110 return;
111 }
112
cb4185f1 113 ++diskd_stats.create.ops;
b9ae18aa 114}
115
116void
117DiskdFile::read(ReadRequest *aRead)
118{
119 assert (ioRequestor.getRaw() != NULL);
ee139403 120 ssize_t shm_offset;
b9ae18aa 121 char *rbuf = (char *)IO->shm.get(&shm_offset);
122 assert(rbuf);
123 ioAway();
124 int x = IO->send(_MQD_READ,
125 id,
126 this,
ee139403 127 aRead->len,
128 aRead->offset,
b9ae18aa 129 shm_offset,
130 aRead);
131
132 if (x < 0) {
133 ioCompleted();
134 errorOccured = true;
135 // IO->shm.put (shm_offset);
e0236918 136 debugs(79, DBG_IMPORTANT, "storeDiskdSend READ: " << xstrerror());
b9ae18aa 137 notifyClient();
138 ioRequestor = NULL;
139 return;
140 }
141
cb4185f1 142 ++diskd_stats.read.ops;
b9ae18aa 143}
144
145void
146DiskdFile::close()
147{
bf8fe701 148 debugs(79, 3, "DiskdFile::close: " << this << " closing for " << ioRequestor.getRaw());
b9ae18aa 149 assert (ioRequestor.getRaw());
150 ioAway();
151 int x = IO->send(_MQD_CLOSE,
152 id,
153 this,
154 0,
155 0,
156 -1,
157 NULL);
158
159 if (x < 0) {
160 ioCompleted();
161 errorOccured = true;
e0236918 162 debugs(79, DBG_IMPORTANT, "storeDiskdSend CLOSE: " << xstrerror());
b9ae18aa 163 notifyClient();
164 ioRequestor = NULL;
165 return;
166 }
167
cb4185f1 168 ++diskd_stats.close.ops;
b9ae18aa 169}
170
171bool
172DiskdFile::error() const
173{
174 return errorOccured;
175}
176
177bool
178DiskdFile::canRead() const
179{
180 return !error();
181}
182
183bool
184DiskdFile::canNotifyClient() const
185{
186 if (!ioRequestor.getRaw()) {
bf8fe701 187 debugs(79, 3, "DiskdFile::canNotifyClient: No ioRequestor to notify");
b9ae18aa 188 return false;
189 }
190
191 return true;
192}
193
194void
195DiskdFile::notifyClient()
196{
197 if (!canNotifyClient()) {
198 return;
199 }
200
201 ioRequestor->ioCompletedNotification();
202}
203
204void
205DiskdFile::completed(diomsg *M)
206{
207 assert (M->newstyle);
208
209 switch (M->mtype) {
210
211 case _MQD_OPEN:
212 openDone(M);
213 break;
214
215 case _MQD_CREATE:
216 createDone(M);
217 break;
218
219 case _MQD_CLOSE:
220 closeDone(M);
221 break;
222
223 case _MQD_READ:
224 readDone(M);
225 break;
226
227 case _MQD_WRITE:
228 writeDone(M);
229 break;
230
231 case _MQD_UNLINK:
232 assert (0);
233 break;
234
235 default:
236 assert(0);
237 break;
238 }
239}
240
241void
242DiskdFile::openDone(diomsg *M)
243{
e4f1fdae 244 ++statCounter.syscalls.disk.opens;
bf8fe701 245 debugs(79, 3, "storeDiskdOpenDone: status " << M->status);
b9ae18aa 246
247 if (M->status < 0) {
cb4185f1 248 ++diskd_stats.open.fail;
b9ae18aa 249 errorOccured = true;
250 } else {
cb4185f1 251 ++diskd_stats.open.success;
b9ae18aa 252 }
253
254 ioCompleted();
255 notifyClient();
256}
257
258void
259DiskdFile::createDone(diomsg *M)
260{
e4f1fdae 261 ++statCounter.syscalls.disk.opens;
bf8fe701 262 debugs(79, 3, "storeDiskdCreateDone: status " << M->status);
b9ae18aa 263
264 if (M->status < 0) {
cb4185f1 265 ++diskd_stats.create.fail;
b9ae18aa 266 errorOccured = true;
267 } else {
cb4185f1 268 ++diskd_stats.create.success;
b9ae18aa 269 }
270
271 ioCompleted();
272 notifyClient();
273}
274
275void
276DiskdFile::write(WriteRequest *aRequest)
277{
278 debugs(79, 3, "DiskdFile::write: this " << (void *)this << ", buf " << (void *)aRequest->buf << ", off " << aRequest->offset << ", len " << aRequest->len);
ee139403 279 ssize_t shm_offset;
b9ae18aa 280 char *sbuf = (char *)IO->shm.get(&shm_offset);
41d00cd3 281 memcpy(sbuf, aRequest->buf, aRequest->len);
b9ae18aa 282
283 if (aRequest->free_func)
284 aRequest->free_func(const_cast<char *>(aRequest->buf));
285
286 ioAway();
287
288 int x = IO->send(_MQD_WRITE,
289 id,
290 this,
ee139403 291 aRequest->len,
292 aRequest->offset,
b9ae18aa 293 shm_offset,
294 aRequest);
295
296 if (x < 0) {
3d0ac046 297 ioCompleted();
b9ae18aa 298 errorOccured = true;
e0236918 299 debugs(79, DBG_IMPORTANT, "storeDiskdSend WRITE: " << xstrerror());
b9ae18aa 300 // IO->shm.put (shm_offset);
301 notifyClient();
302 ioRequestor = NULL;
303 return;
304 }
305
cb4185f1 306 ++diskd_stats.write.ops;
b9ae18aa 307}
308
309void
310DiskdFile::ioAway()
311{
312 ++inProgressIOs;
313}
314
315void
316DiskdFile::ioCompleted()
317{
318 --inProgressIOs;
319}
320
321void
322DiskdFile::closeDone(diomsg * M)
323{
e4f1fdae 324 ++statCounter.syscalls.disk.closes;
bf8fe701 325 debugs(79, 3, "DiskdFile::closeDone: status " << M->status);
b9ae18aa 326
327 if (M->status < 0) {
cb4185f1 328 ++diskd_stats.close.fail;
b9ae18aa 329 errorOccured = true;
330 } else {
cb4185f1 331 ++diskd_stats.close.success;
b9ae18aa 332 }
333
334 ioCompleted();
335
336 if (canNotifyClient())
337 ioRequestor->closeCompleted();
338
339 ioRequestor = NULL;
340}
341
342void
343DiskdFile::readDone(diomsg * M)
344{
e4f1fdae 345 ++statCounter.syscalls.disk.reads;
bf8fe701 346 debugs(79, 3, "DiskdFile::readDone: status " << M->status);
b9ae18aa 347 assert (M->requestor);
348 ReadRequest::Pointer readRequest = dynamic_cast<ReadRequest *>(M->requestor);
e19994df 349
b9ae18aa 350 /* remove the free protection */
e19994df
TH
351 if (readRequest != NULL)
352 readRequest->unlock();
b9ae18aa 353
354 if (M->status < 0) {
cb4185f1 355 ++diskd_stats.read.fail;
b9ae18aa 356 ioCompleted();
357 errorOccured = true;
358 ioRequestor->readCompleted(NULL, -1, DISK_ERROR, readRequest);
359 return;
360 }
361
cb4185f1 362 ++diskd_stats.read.success;
b9ae18aa 363
364 ioCompleted();
365 ioRequestor->readCompleted (IO->shm.buf + M->shm_offset, M->status, DISK_OK, readRequest);
366}
367
368void
369DiskdFile::writeDone(diomsg *M)
370{
e4f1fdae 371 ++statCounter.syscalls.disk.writes;
bf8fe701 372 debugs(79, 3, "storeDiskdWriteDone: status " << M->status);
b9ae18aa 373 assert (M->requestor);
374 WriteRequest::Pointer writeRequest = dynamic_cast<WriteRequest *>(M->requestor);
375 /* remove the free protection */
e19994df
TH
376 if (writeRequest != NULL)
377 writeRequest->unlock();
b9ae18aa 378
379 if (M->status < 0) {
380 errorOccured = true;
cb4185f1 381 ++diskd_stats.write.fail;
b9ae18aa 382 ioCompleted();
383 ioRequestor->writeCompleted (DISK_ERROR,0, writeRequest);
384 return;
385 }
386
cb4185f1 387 ++diskd_stats.write.success;
b9ae18aa 388 ioCompleted();
389 ioRequestor->writeCompleted (DISK_OK,M->status, writeRequest);
390}
391
392bool
393DiskdFile::ioInProgress()const
394{
395 return inProgressIOs != 0;
396}
f53969cc 397