DiskdFile.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9/* DEBUG: section 79 Squid-side DISKD I/O functions. */
10
11#include "squid.h"
12#include "ConfigOption.h"
13#include "diomsg.h"
14#include "DiskdFile.h"
15#include "DiskdIOStrategy.h"
16#include "DiskIO/IORequestor.h"
17#include "DiskIO/ReadRequest.h"
18#include "DiskIO/WriteRequest.h"
19#include "StatCounters.h"
20
21#if HAVE_SYS_IPC_H
22#include <sys/ipc.h>
23#endif
24#if HAVE_SYS_MSG_H
25#include <sys/msg.h>
26#endif
27#if HAVE_SYS_SHM_H
28#include <sys/shm.h>
29#endif
30
32
33DiskdFile::DiskdFile(char const *aPath, DiskdIOStrategy *anIO) :
34 errorOccured(false),
35 IO(anIO),
36 mode(0),
37 inProgressIOs(0)
38{
39 assert(aPath);
40 debugs(79, 3, "DiskdFile::DiskdFile: " << aPath);
41 path_ = xstrdup(aPath);
44}
45
47{
50}
51
52void
54{
55 debugs(79, 3, "DiskdFile::open: " << this << " opening for " << callback.getRaw());
56 assert(ioRequestor.getRaw() == nullptr);
57 ioRequestor = callback;
58 assert(callback.getRaw());
59 mode = flags;
60 ssize_t shm_offset;
61 char *buf = (char *)IO->shm.get(&shm_offset);
63 ioAway();
64 int x = IO->send(_MQD_OPEN,
65 id,
66 this,
67 strlen(buf) + 1,
68 mode,
69 shm_offset,
70 nullptr);
71
72 if (x < 0) {
74 errorOccured = true;
75 // IO->shm.put (shm_offset);
77 ioRequestor = nullptr;
78 }
79
81}
82
83void
85{
86 debugs(79, 3, "DiskdFile::create: " << this << " creating for " << callback.getRaw());
87 assert (ioRequestor.getRaw() == nullptr);
88 ioRequestor = callback;
89 assert (callback.getRaw());
90 mode = flags;
91 ssize_t shm_offset;
92 char *buf = (char *)IO->shm.get(&shm_offset);
94 ioAway();
95 int x = IO->send(_MQD_CREATE,
96 id,
97 this,
98 strlen(buf) + 1,
99 mode,
100 shm_offset,
101 nullptr);
102
103 if (x < 0) {
104 int xerrno = errno;
105 ioCompleted();
106 errorOccured = true;
107 // IO->shm.put (shm_offset);
108 debugs(79, DBG_IMPORTANT, "storeDiskdSend CREATE: " << xstrerr(xerrno));
109 notifyClient();
110 ioRequestor = nullptr;
111 return;
112 }
113
115}
116
117void
119{
120 assert (ioRequestor.getRaw() != nullptr);
121 ssize_t shm_offset;
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,
128 aRead->len,
129 aRead->offset,
130 shm_offset,
131 aRead);
132
133 if (x < 0) {
134 int xerrno = errno;
135 ioCompleted();
136 errorOccured = true;
137 // IO->shm.put (shm_offset);
138 debugs(79, DBG_IMPORTANT, "storeDiskdSend READ: " << xstrerr(xerrno));
139 notifyClient();
140 ioRequestor = nullptr;
141 return;
142 }
143
145}
146
147void
149{
150 debugs(79, 3, "DiskdFile::close: " << this << " closing for " << ioRequestor.getRaw());
152 ioAway();
153 int x = IO->send(_MQD_CLOSE,
154 id,
155 this,
156 0,
157 0,
158 -1,
159 nullptr);
160
161 if (x < 0) {
162 int xerrno = errno;
163 ioCompleted();
164 errorOccured = true;
165 debugs(79, DBG_IMPORTANT, "storeDiskdSend CLOSE: " << xstrerr(xerrno));
166 notifyClient();
167 ioRequestor = nullptr;
168 return;
169 }
170
172}
173
174bool
176{
177 return errorOccured;
178}
179
180bool
182{
183 return !error();
184}
185
186bool
188{
189 if (!ioRequestor.getRaw()) {
190 debugs(79, 3, "DiskdFile::canNotifyClient: No ioRequestor to notify");
191 return false;
192 }
193
194 return true;
195}
196
197void
199{
200 if (!canNotifyClient()) {
201 return;
202 }
203
205}
206
207void
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
246{
248 debugs(79, 3, "storeDiskdOpenDone: status " << M->status);
249
250 if (M->status < 0) {
252 errorOccured = true;
253 } else {
255 }
256
257 ioCompleted();
258 notifyClient();
259}
260
261void
263{
265 debugs(79, 3, "storeDiskdCreateDone: status " << M->status);
266
267 if (M->status < 0) {
269 errorOccured = true;
270 } else {
272 }
273
274 ioCompleted();
275 notifyClient();
276}
277
278void
280{
281 debugs(79, 3, "DiskdFile::write: this " << (void *)this << ", buf " << (void *)aRequest->buf << ", off " << aRequest->offset << ", len " << aRequest->len);
282 ssize_t shm_offset;
283 char *sbuf = (char *)IO->shm.get(&shm_offset);
284 memcpy(sbuf, aRequest->buf, aRequest->len);
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,
294 aRequest->len,
295 aRequest->offset,
296 shm_offset,
297 aRequest);
298
299 if (x < 0) {
300 int xerrno = errno;
301 ioCompleted();
302 errorOccured = true;
303 debugs(79, DBG_IMPORTANT, "storeDiskdSend WRITE: " << xstrerr(xerrno));
304 // IO->shm.put (shm_offset);
305 notifyClient();
306 ioRequestor = nullptr;
307 return;
308 }
309
311}
312
313void
315{
317}
318
319void
321{
323}
324
325void
327{
329 debugs(79, 3, "DiskdFile::closeDone: status " << M->status);
330
331 if (M->status < 0) {
333 errorOccured = true;
334 } else {
336 }
337
338 ioCompleted();
339
340 if (canNotifyClient())
342
343 ioRequestor = nullptr;
344}
345
346void
348{
350 debugs(79, 3, "DiskdFile::readDone: status " << M->status);
351 assert (M->requestor);
352 ReadRequest::Pointer readRequest = dynamic_cast<ReadRequest *>(M->requestor);
353
354 /* remove the free protection */
355 if (readRequest != nullptr) {
356 const uint32_t lcount = readRequest->unlock();
357 if (lcount == 0)
358 debugs(79, DBG_IMPORTANT, "ERROR: invariant check failed: readRequest reference count is 0");
359 }
360
361 if (M->status < 0) {
363 ioCompleted();
364 errorOccured = true;
365 ioRequestor->readCompleted(nullptr, -1, DISK_ERROR, readRequest);
366 return;
367 }
368
370
371 ioCompleted();
372 ioRequestor->readCompleted (IO->shm.buf + M->shm_offset, M->status, DISK_OK, readRequest);
373}
374
375void
377{
379 debugs(79, 3, "storeDiskdWriteDone: status " << M->status);
380 assert (M->requestor);
381 WriteRequest::Pointer writeRequest = dynamic_cast<WriteRequest *>(M->requestor);
382
383 /* remove the free protection */
384 if (writeRequest != nullptr) {
385 const uint32_t lcount = writeRequest->unlock();
386 if (lcount == 0)
387 debugs(79, DBG_IMPORTANT, "ERROR: invariant check failed: writeRequest reference count is 0");
388 }
389
390 if (M->status < 0) {
391 errorOccured = true;
393 ioCompleted();
394 ioRequestor->writeCompleted (DISK_ERROR,0, writeRequest);
395 return;
396 }
397
399 ioCompleted();
400 ioRequestor->writeCompleted (DISK_OK,M->status, writeRequest);
401}
402
403bool
405{
406 return inProgressIOs != 0;
407}
408
CBDATA_CLASS_INIT(DiskdFile)
#define false
Definition: GnuRegex.c:240
StatCounters statCounter
Definition: StatCounters.cc:12
#define assert(EX)
Definition: assert.h:19
void closeDone(diomsg *)
Definition: DiskdFile.cc:326
bool errorOccured
Definition: DiskdFile.h:48
int mode
Definition: DiskdFile.h:56
virtual bool error() const
Definition: DiskdFile.cc:175
void ioCompleted()
Definition: DiskdFile.cc:320
virtual void write(WriteRequest *)
Definition: DiskdFile.cc:279
virtual void read(ReadRequest *)
Definition: DiskdFile.cc:118
RefCount< IORequestor > ioRequestor
Definition: DiskdFile.h:50
virtual void close()
Definition: DiskdFile.cc:148
bool canNotifyClient() const
Definition: DiskdFile.cc:187
virtual void open(int flags, mode_t aMode, RefCount< IORequestor > callback)
Definition: DiskdFile.cc:53
void writeDone(diomsg *)
Definition: DiskdFile.cc:376
void openDone(diomsg *)
Definition: DiskdFile.cc:245
void completed(diomsg *)
Definition: DiskdFile.cc:208
DiskdIOStrategy * IO
Definition: DiskdFile.h:49
char const * path_
Definition: DiskdFile.h:47
~DiskdFile()
Definition: DiskdFile.cc:46
void readDone(diomsg *)
Definition: DiskdFile.cc:347
size_t inProgressIOs
Definition: DiskdFile.h:61
virtual void create(int flags, mode_t aMode, RefCount< IORequestor > callback)
Definition: DiskdFile.cc:84
virtual bool canRead() const
Definition: DiskdFile.cc:181
virtual bool ioInProgress() const
Definition: DiskdFile.cc:404
void notifyClient()
Definition: DiskdFile.cc:198
void createDone(diomsg *)
Definition: DiskdFile.cc:262
DiskdFile(char const *path, DiskdIOStrategy *)
Definition: DiskdFile.cc:33
void ioAway()
Definition: DiskdFile.cc:314
int send(int mtype, int id, DiskdFile *theFile, size_t size, off_t offset, ssize_t shm_offset, Lock *requestor)
SharedMemory shm
virtual void closeCompleted()=0
virtual void readCompleted(const char *buf, int len, int errflag, RefCount< ReadRequest >)=0
virtual void ioCompletedNotification()=0
virtual void writeCompleted(int errflag, size_t len, RefCount< WriteRequest >)=0
size_t len
Definition: ReadRequest.h:26
off_t offset
Definition: ReadRequest.h:25
C * getRaw() const
Definition: RefCount.h:80
void * get(ssize_t *)
struct StatCounters::@136 syscalls
struct StatCounters::@136::@140 disk
FREE * free_func
Definition: WriteRequest.h:28
char const * buf
Definition: WriteRequest.h:25
#define DBG_IMPORTANT
Definition: Stream.h:41
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
#define DISK_ERROR
Definition: defines.h:28
#define DISK_OK
Definition: defines.h:27
@ _MQD_UNLINK
Definition: diomsg.h:25
@ _MQD_CREATE
Definition: diomsg.h:21
@ _MQD_WRITE
Definition: diomsg.h:24
@ _MQD_CLOSE
Definition: diomsg.h:22
@ _MQD_OPEN
Definition: diomsg.h:20
@ _MQD_READ
Definition: diomsg.h:23
#define SHMBUF_BLKSZ
diskd_stats_t diskd_stats
#define xstrdup
Definition: diomsg.h:30
mtyp_t mtype
Definition: diomsg.h:31
int status
Definition: diomsg.h:38
Lock * requestor
Definition: diomsg.h:35
bool newstyle
Definition: diomsg.h:39
int shm_offset
Definition: diomsg.h:40
struct diskd_stats_t::@47 create
struct diskd_stats_t::@47 write
struct diskd_stats_t::@47 open
struct diskd_stats_t::@47 read
struct diskd_stats_t::@47 close
unsigned short mode_t
Definition: types.h:150
#define safe_free(x)
Definition: xalloc.h:73
const char * xstrerr(int error)
Definition: xstrerror.cc:83
char * xstrncpy(char *dst, const char *src, size_t n)
Definition: xstring.cc:37

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors