]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/DiskDaemon/DiskdFile.cc
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / DiskIO / DiskDaemon / DiskdFile.cc
CommitLineData
b9ae18aa 1/*
5b74111a 2 * Copyright (C) 1996-2018 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) {
b69e9ffa 104 int xerrno = errno;
b9ae18aa 105 ioCompleted();
106 errorOccured = true;
107 // IO->shm.put (shm_offset);
b69e9ffa 108 debugs(79, DBG_IMPORTANT, "storeDiskdSend CREATE: " << xstrerr(xerrno));
b9ae18aa 109 notifyClient();
110 ioRequestor = NULL;
111 return;
112 }
113
cb4185f1 114 ++diskd_stats.create.ops;
b9ae18aa 115}
116
117void
118DiskdFile::read(ReadRequest *aRead)
119{
120 assert (ioRequestor.getRaw() != NULL);
ee139403 121 ssize_t shm_offset;
b9ae18aa 122 char *rbuf = (char *)IO->shm.get(&shm_offset);
123 assert(rbuf);
124 ioAway();
125 int x = IO->send(_MQD_READ,
126 id,
127 this,
ee139403 128 aRead->len,
129 aRead->offset,
b9ae18aa 130 shm_offset,
131 aRead);
132
133 if (x < 0) {
b69e9ffa 134 int xerrno = errno;
b9ae18aa 135 ioCompleted();
136 errorOccured = true;
137 // IO->shm.put (shm_offset);
b69e9ffa 138 debugs(79, DBG_IMPORTANT, "storeDiskdSend READ: " << xstrerr(xerrno));
b9ae18aa 139 notifyClient();
140 ioRequestor = NULL;
141 return;
142 }
143
cb4185f1 144 ++diskd_stats.read.ops;
b9ae18aa 145}
146
147void
148DiskdFile::close()
149{
bf8fe701 150 debugs(79, 3, "DiskdFile::close: " << this << " closing for " << ioRequestor.getRaw());
b9ae18aa 151 assert (ioRequestor.getRaw());
152 ioAway();
153 int x = IO->send(_MQD_CLOSE,
154 id,
155 this,
156 0,
157 0,
158 -1,
159 NULL);
160
161 if (x < 0) {
b69e9ffa 162 int xerrno = errno;
b9ae18aa 163 ioCompleted();
164 errorOccured = true;
b69e9ffa 165 debugs(79, DBG_IMPORTANT, "storeDiskdSend CLOSE: " << xstrerr(xerrno));
b9ae18aa 166 notifyClient();
167 ioRequestor = NULL;
168 return;
169 }
170
cb4185f1 171 ++diskd_stats.close.ops;
b9ae18aa 172}
173
174bool
175DiskdFile::error() const
176{
177 return errorOccured;
178}
179
180bool
181DiskdFile::canRead() const
182{
183 return !error();
184}
185
186bool
187DiskdFile::canNotifyClient() const
188{
189 if (!ioRequestor.getRaw()) {
bf8fe701 190 debugs(79, 3, "DiskdFile::canNotifyClient: No ioRequestor to notify");
b9ae18aa 191 return false;
192 }
193
194 return true;
195}
196
197void
198DiskdFile::notifyClient()
199{
200 if (!canNotifyClient()) {
201 return;
202 }
203
204 ioRequestor->ioCompletedNotification();
205}
206
207void
208DiskdFile::completed(diomsg *M)
209{
210 assert (M->newstyle);
211
212 switch (M->mtype) {
213
214 case _MQD_OPEN:
215 openDone(M);
216 break;
217
218 case _MQD_CREATE:
219 createDone(M);
220 break;
221
222 case _MQD_CLOSE:
223 closeDone(M);
224 break;
225
226 case _MQD_READ:
227 readDone(M);
228 break;
229
230 case _MQD_WRITE:
231 writeDone(M);
232 break;
233
234 case _MQD_UNLINK:
235 assert (0);
236 break;
237
238 default:
239 assert(0);
240 break;
241 }
242}
243
244void
245DiskdFile::openDone(diomsg *M)
246{
e4f1fdae 247 ++statCounter.syscalls.disk.opens;
bf8fe701 248 debugs(79, 3, "storeDiskdOpenDone: status " << M->status);
b9ae18aa 249
250 if (M->status < 0) {
cb4185f1 251 ++diskd_stats.open.fail;
b9ae18aa 252 errorOccured = true;
253 } else {
cb4185f1 254 ++diskd_stats.open.success;
b9ae18aa 255 }
256
257 ioCompleted();
258 notifyClient();
259}
260
261void
262DiskdFile::createDone(diomsg *M)
263{
e4f1fdae 264 ++statCounter.syscalls.disk.opens;
bf8fe701 265 debugs(79, 3, "storeDiskdCreateDone: status " << M->status);
b9ae18aa 266
267 if (M->status < 0) {
cb4185f1 268 ++diskd_stats.create.fail;
b9ae18aa 269 errorOccured = true;
270 } else {
cb4185f1 271 ++diskd_stats.create.success;
b9ae18aa 272 }
273
274 ioCompleted();
275 notifyClient();
276}
277
278void
279DiskdFile::write(WriteRequest *aRequest)
280{
281 debugs(79, 3, "DiskdFile::write: this " << (void *)this << ", buf " << (void *)aRequest->buf << ", off " << aRequest->offset << ", len " << aRequest->len);
ee139403 282 ssize_t shm_offset;
b9ae18aa 283 char *sbuf = (char *)IO->shm.get(&shm_offset);
41d00cd3 284 memcpy(sbuf, aRequest->buf, aRequest->len);
b9ae18aa 285
286 if (aRequest->free_func)
287 aRequest->free_func(const_cast<char *>(aRequest->buf));
288
289 ioAway();
290
291 int x = IO->send(_MQD_WRITE,
292 id,
293 this,
ee139403 294 aRequest->len,
295 aRequest->offset,
b9ae18aa 296 shm_offset,
297 aRequest);
298
299 if (x < 0) {
b69e9ffa 300 int xerrno = errno;
3d0ac046 301 ioCompleted();
b9ae18aa 302 errorOccured = true;
b69e9ffa 303 debugs(79, DBG_IMPORTANT, "storeDiskdSend WRITE: " << xstrerr(xerrno));
b9ae18aa 304 // IO->shm.put (shm_offset);
305 notifyClient();
306 ioRequestor = NULL;
307 return;
308 }
309
cb4185f1 310 ++diskd_stats.write.ops;
b9ae18aa 311}
312
313void
314DiskdFile::ioAway()
315{
316 ++inProgressIOs;
317}
318
319void
320DiskdFile::ioCompleted()
321{
322 --inProgressIOs;
323}
324
325void
326DiskdFile::closeDone(diomsg * M)
327{
e4f1fdae 328 ++statCounter.syscalls.disk.closes;
bf8fe701 329 debugs(79, 3, "DiskdFile::closeDone: status " << M->status);
b9ae18aa 330
331 if (M->status < 0) {
cb4185f1 332 ++diskd_stats.close.fail;
b9ae18aa 333 errorOccured = true;
334 } else {
cb4185f1 335 ++diskd_stats.close.success;
b9ae18aa 336 }
337
338 ioCompleted();
339
340 if (canNotifyClient())
341 ioRequestor->closeCompleted();
342
343 ioRequestor = NULL;
344}
345
346void
347DiskdFile::readDone(diomsg * M)
348{
e4f1fdae 349 ++statCounter.syscalls.disk.reads;
bf8fe701 350 debugs(79, 3, "DiskdFile::readDone: status " << M->status);
b9ae18aa 351 assert (M->requestor);
352 ReadRequest::Pointer readRequest = dynamic_cast<ReadRequest *>(M->requestor);
e19994df 353
b9ae18aa 354 /* remove the free protection */
91663b86
FC
355 if (readRequest != NULL) {
356 const uint32_t lcount = readRequest->unlock();
357 if (lcount == 0)
f624e5da 358 debugs(79, DBG_IMPORTANT, "invariant check failed: readRequest reference count is 0");
91663b86 359 }
b9ae18aa 360
361 if (M->status < 0) {
cb4185f1 362 ++diskd_stats.read.fail;
b9ae18aa 363 ioCompleted();
364 errorOccured = true;
365 ioRequestor->readCompleted(NULL, -1, DISK_ERROR, readRequest);
366 return;
367 }
368
cb4185f1 369 ++diskd_stats.read.success;
b9ae18aa 370
371 ioCompleted();
372 ioRequestor->readCompleted (IO->shm.buf + M->shm_offset, M->status, DISK_OK, readRequest);
373}
374
375void
376DiskdFile::writeDone(diomsg *M)
377{
e4f1fdae 378 ++statCounter.syscalls.disk.writes;
bf8fe701 379 debugs(79, 3, "storeDiskdWriteDone: status " << M->status);
b9ae18aa 380 assert (M->requestor);
381 WriteRequest::Pointer writeRequest = dynamic_cast<WriteRequest *>(M->requestor);
f624e5da 382
b9ae18aa 383 /* remove the free protection */
f624e5da
FC
384 if (writeRequest != NULL) {
385 const uint32_t lcount = writeRequest->unlock();
386 if (lcount == 0)
387 debugs(79, DBG_IMPORTANT, "invariant check failed: writeRequest reference count is 0");
388 }
b9ae18aa 389
390 if (M->status < 0) {
391 errorOccured = true;
cb4185f1 392 ++diskd_stats.write.fail;
b9ae18aa 393 ioCompleted();
394 ioRequestor->writeCompleted (DISK_ERROR,0, writeRequest);
395 return;
396 }
397
cb4185f1 398 ++diskd_stats.write.success;
b9ae18aa 399 ioCompleted();
400 ioRequestor->writeCompleted (DISK_OK,M->status, writeRequest);
401}
402
403bool
404DiskdFile::ioInProgress()const
405{
406 return inProgressIOs != 0;
407}
f53969cc 408