Squid Web Cache master
Loading...
Searching...
No Matches
DiskdFile.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 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
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);
62 if (!buf) {
63 errorOccured = true;
65 ioRequestor = nullptr;
66 return;
67 }
68
70 ioAway();
71 int x = IO->send(_MQD_OPEN,
72 id,
73 this,
74 strlen(buf) + 1,
75 mode,
76 shm_offset,
77 nullptr);
78
79 if (x < 0) {
81 errorOccured = true;
82 // IO->shm.put (shm_offset);
84 ioRequestor = nullptr;
85 }
86
88}
89
90void
92{
93 debugs(79, 3, "DiskdFile::create: " << this << " creating for " << callback.getRaw());
94 assert (ioRequestor.getRaw() == nullptr);
95 ioRequestor = callback;
96 assert (callback.getRaw());
97 mode = flags;
98 ssize_t shm_offset;
99 char *buf = (char *)IO->shm.get(&shm_offset);
100 if (!buf) {
101 errorOccured = true;
102 notifyClient();
103 ioRequestor = nullptr;
104 return;
105 }
106
108 ioAway();
109 int x = IO->send(_MQD_CREATE,
110 id,
111 this,
112 strlen(buf) + 1,
113 mode,
114 shm_offset,
115 nullptr);
116
117 if (x < 0) {
118 int xerrno = errno;
119 ioCompleted();
120 errorOccured = true;
121 // IO->shm.put (shm_offset);
122 debugs(79, DBG_IMPORTANT, "storeDiskdSend CREATE: " << xstrerr(xerrno));
123 notifyClient();
124 ioRequestor = nullptr;
125 return;
126 }
127
129}
130
131void
133{
134 assert (ioRequestor.getRaw() != nullptr);
135 ssize_t shm_offset;
136 char *rbuf = (char *)IO->shm.get(&shm_offset);
137 if (!rbuf) {
138 errorOccured = true;
139 notifyClient();
140 ioRequestor = nullptr;
141 return;
142 }
143 ioAway();
144 int x = IO->send(_MQD_READ,
145 id,
146 this,
147 aRead->len,
148 aRead->offset,
149 shm_offset,
150 aRead);
151
152 if (x < 0) {
153 int xerrno = errno;
154 ioCompleted();
155 errorOccured = true;
156 // IO->shm.put (shm_offset);
157 debugs(79, DBG_IMPORTANT, "storeDiskdSend READ: " << xstrerr(xerrno));
158 notifyClient();
159 ioRequestor = nullptr;
160 return;
161 }
162
164}
165
166void
168{
169 debugs(79, 3, "DiskdFile::close: " << this << " closing for " << ioRequestor.getRaw());
171 ioAway();
172 int x = IO->send(_MQD_CLOSE,
173 id,
174 this,
175 0,
176 0,
177 -1,
178 nullptr);
179
180 if (x < 0) {
181 int xerrno = errno;
182 ioCompleted();
183 errorOccured = true;
184 debugs(79, DBG_IMPORTANT, "storeDiskdSend CLOSE: " << xstrerr(xerrno));
185 notifyClient();
186 ioRequestor = nullptr;
187 return;
188 }
189
191}
192
193bool
195{
196 return errorOccured;
197}
198
199bool
201{
202 return !error();
203}
204
205bool
207{
208 if (!ioRequestor.getRaw()) {
209 debugs(79, 3, "DiskdFile::canNotifyClient: No ioRequestor to notify");
210 return false;
211 }
212
213 return true;
214}
215
216void
218{
219 if (!canNotifyClient()) {
220 return;
221 }
222
224}
225
226void
228{
229 assert (M->newstyle);
230
231 switch (M->mtype) {
232
233 case _MQD_OPEN:
234 openDone(M);
235 break;
236
237 case _MQD_CREATE:
238 createDone(M);
239 break;
240
241 case _MQD_CLOSE:
242 closeDone(M);
243 break;
244
245 case _MQD_READ:
246 readDone(M);
247 break;
248
249 case _MQD_WRITE:
250 writeDone(M);
251 break;
252
253 case _MQD_UNLINK:
254 assert (0);
255 break;
256
257 default:
258 assert(0);
259 break;
260 }
261}
262
263void
265{
267 debugs(79, 3, "storeDiskdOpenDone: status " << M->status);
268
269 if (M->status < 0) {
271 errorOccured = true;
272 } else {
274 }
275
276 ioCompleted();
277 notifyClient();
278}
279
280void
282{
284 debugs(79, 3, "storeDiskdCreateDone: status " << M->status);
285
286 if (M->status < 0) {
288 errorOccured = true;
289 } else {
291 }
292
293 ioCompleted();
294 notifyClient();
295}
296
297void
299{
300 debugs(79, 3, "DiskdFile::write: this " << (void *)this << ", buf " << (void *)aRequest->buf << ", off " << aRequest->offset << ", len " << aRequest->len);
301 ssize_t shm_offset;
302 char *sbuf = (char *)IO->shm.get(&shm_offset);
303 if (!sbuf) {
304 errorOccured = true;
305 if (aRequest->free_func)
306 aRequest->free_func(const_cast<char *>(aRequest->buf));
307 notifyClient();
308 ioRequestor = nullptr;
309 return;
310 }
311
312 memcpy(sbuf, aRequest->buf, aRequest->len);
313
314 if (aRequest->free_func)
315 aRequest->free_func(const_cast<char *>(aRequest->buf));
316
317 ioAway();
318
319 int x = IO->send(_MQD_WRITE,
320 id,
321 this,
322 aRequest->len,
323 aRequest->offset,
324 shm_offset,
325 aRequest);
326
327 if (x < 0) {
328 int xerrno = errno;
329 ioCompleted();
330 errorOccured = true;
331 debugs(79, DBG_IMPORTANT, "storeDiskdSend WRITE: " << xstrerr(xerrno));
332 // IO->shm.put (shm_offset);
333 notifyClient();
334 ioRequestor = nullptr;
335 return;
336 }
337
339}
340
341void
346
347void
352
353void
355{
357 debugs(79, 3, "DiskdFile::closeDone: status " << M->status);
358
359 if (M->status < 0) {
361 errorOccured = true;
362 } else {
364 }
365
366 ioCompleted();
367
368 if (canNotifyClient())
370
371 ioRequestor = nullptr;
372}
373
374void
376{
378 debugs(79, 3, "DiskdFile::readDone: status " << M->status);
379 assert (M->requestor);
380 ReadRequest::Pointer readRequest = dynamic_cast<ReadRequest *>(M->requestor);
381
382 /* remove the free protection */
383 if (readRequest != nullptr) {
384 const uint32_t lcount = readRequest->unlock();
385 if (lcount == 0)
386 debugs(79, DBG_IMPORTANT, "ERROR: invariant check failed: readRequest reference count is 0");
387 }
388
389 if (M->status < 0) {
391 ioCompleted();
392 errorOccured = true;
393 ioRequestor->readCompleted(nullptr, -1, DISK_ERROR, readRequest);
394 return;
395 }
396
398
399 ioCompleted();
400 ioRequestor->readCompleted (IO->shm.buf + M->shm_offset, M->status, DISK_OK, readRequest);
401}
402
403void
405{
407 debugs(79, 3, "storeDiskdWriteDone: status " << M->status);
408 assert (M->requestor);
409 WriteRequest::Pointer writeRequest = dynamic_cast<WriteRequest *>(M->requestor);
410
411 /* remove the free protection */
412 if (writeRequest != nullptr) {
413 const uint32_t lcount = writeRequest->unlock();
414 if (lcount == 0)
415 debugs(79, DBG_IMPORTANT, "ERROR: invariant check failed: writeRequest reference count is 0");
416 }
417
418 if (M->status < 0) {
419 errorOccured = true;
421 ioCompleted();
422 ioRequestor->writeCompleted (DISK_ERROR,0, writeRequest);
423 return;
424 }
425
427 ioCompleted();
428 ioRequestor->writeCompleted (DISK_OK,M->status, writeRequest);
429}
430
431bool
433{
434 return inProgressIOs != 0;
435}
436
StatCounters statCounter
#define assert(EX)
Definition assert.h:17
#define CBDATA_CLASS_INIT(type)
Definition cbdata.h:325
void closeDone(diomsg *)
Definition DiskdFile.cc:354
bool errorOccured
Definition DiskdFile.h:48
void open(int flags, mode_t aMode, RefCount< IORequestor > callback) override
Definition DiskdFile.cc:53
void ioCompleted()
Definition DiskdFile.cc:348
RefCount< IORequestor > ioRequestor
Definition DiskdFile.h:50
bool canNotifyClient() const
Definition DiskdFile.cc:206
void writeDone(diomsg *)
Definition DiskdFile.cc:404
void openDone(diomsg *)
Definition DiskdFile.cc:264
bool canRead() const override
Definition DiskdFile.cc:200
bool ioInProgress() const override
Definition DiskdFile.cc:432
void completed(diomsg *)
Definition DiskdFile.cc:227
DiskdIOStrategy * IO
Definition DiskdFile.h:49
char const * path_
Definition DiskdFile.h:47
bool error() const override
Definition DiskdFile.cc:194
void readDone(diomsg *)
Definition DiskdFile.cc:375
size_t inProgressIOs
Definition DiskdFile.h:61
void read(ReadRequest *) override
Definition DiskdFile.cc:132
void create(int flags, mode_t aMode, RefCount< IORequestor > callback) override
Definition DiskdFile.cc:91
void close() override
Definition DiskdFile.cc:167
~DiskdFile() override
Definition DiskdFile.cc:46
void write(WriteRequest *) override
Definition DiskdFile.cc:298
void notifyClient()
Definition DiskdFile.cc:217
void createDone(diomsg *)
Definition DiskdFile.cc:281
DiskdFile(char const *path, DiskdIOStrategy *)
Definition DiskdFile.cc:33
void ioAway()
Definition DiskdFile.cc:342
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
C * getRaw() const
Definition RefCount.h:89
void * get(ssize_t *)
struct StatCounters::@112 syscalls
struct StatCounters::@112::@116 disk
FREE * free_func
char const * buf
#define DBG_IMPORTANT
Definition Stream.h:38
#define debugs(SECTION, LEVEL, CONTENT)
Definition Stream.h:192
#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
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::@34 open
struct diskd_stats_t::@34 close
struct diskd_stats_t::@34 write
struct diskd_stats_t::@34 create
struct diskd_stats_t::@34 read
unsigned short mode_t
Definition types.h:129
#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