DiskdFile.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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 
33 DiskdFile::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);
42  id = diskd_stats.sio_id;
44 }
45 
47 {
48  assert(inProgressIOs == 0);
49  safe_free (path_);
50 }
51 
52 void
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) {
73  ioCompleted();
74  errorOccured = true;
75  // IO->shm.put (shm_offset);
77  ioRequestor = nullptr;
78  }
79 
81 }
82 
83 void
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 
117 void
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 
144  ++diskd_stats.read.ops;
145 }
146 
147 void
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 
174 bool
176 {
177  return errorOccured;
178 }
179 
180 bool
182 {
183  return !error();
184 }
185 
186 bool
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 
197 void
199 {
200  if (!canNotifyClient()) {
201  return;
202  }
203 
205 }
206 
207 void
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 
244 void
246 {
247  ++statCounter.syscalls.disk.opens;
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 
261 void
263 {
264  ++statCounter.syscalls.disk.opens;
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 
278 void
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 
313 void
315 {
316  ++inProgressIOs;
317 }
318 
319 void
321 {
322  --inProgressIOs;
323 }
324 
325 void
327 {
328  ++statCounter.syscalls.disk.closes;
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 
346 void
348 {
349  ++statCounter.syscalls.disk.reads;
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 
375 void
377 {
378  ++statCounter.syscalls.disk.writes;
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 
403 bool
405 {
406  return inProgressIOs != 0;
407 }
408 
const char * xstrerr(int error)
Definition: xstrerror.cc:83
RefCount< IORequestor > ioRequestor
Definition: DiskdFile.h:50
struct diskd_stats_t::@41 open
struct diskd_stats_t::@41 read
@ _MQD_CLOSE
Definition: diomsg.h:22
bool canNotifyClient() const
Definition: DiskdFile.cc:187
void openDone(diomsg *)
Definition: DiskdFile.cc:245
DiskdFile(char const *path, DiskdIOStrategy *)
Definition: DiskdFile.cc:33
#define SHMBUF_BLKSZ
const char * path_
Definition: DiskdFile.h:47
#define xstrdup
struct StatCounters::@119::@123 disk
@ _MQD_OPEN
Definition: diomsg.h:20
C * getRaw() const
Definition: RefCount.h:89
void ioCompleted()
Definition: DiskdFile.cc:320
void open(int flags, mode_t aMode, RefCount< IORequestor > callback) override
Definition: DiskdFile.cc:53
char * xstrncpy(char *dst, const char *src, size_t n)
Definition: xstring.cc:37
void close() override
Definition: DiskdFile.cc:148
void writeDone(diomsg *)
Definition: DiskdFile.cc:376
int status
Definition: diomsg.h:38
Lock * requestor
Definition: diomsg.h:35
#define DISK_OK
Definition: defines.h:27
SharedMemory shm
@ _MQD_UNLINK
Definition: diomsg.h:25
struct StatCounters::@119 syscalls
void ioAway()
Definition: DiskdFile.cc:314
virtual void ioCompletedNotification()=0
void closeDone(diomsg *)
Definition: DiskdFile.cc:326
void completed(diomsg *)
Definition: DiskdFile.cc:208
bool canRead() const override
Definition: DiskdFile.cc:181
@ _MQD_READ
Definition: diomsg.h:23
void * get(ssize_t *)
#define safe_free(x)
Definition: xalloc.h:73
#define assert(EX)
Definition: assert.h:17
diskd_stats_t diskd_stats
~DiskdFile() override
Definition: DiskdFile.cc:46
int mode
Definition: DiskdFile.h:56
size_t inProgressIOs
Definition: DiskdFile.h:61
size_t len
Definition: ReadRequest.h:26
void write(WriteRequest *) override
Definition: DiskdFile.cc:279
FREE * free_func
Definition: WriteRequest.h:28
CBDATA_CLASS_INIT(DiskdFile)
virtual void writeCompleted(int errflag, size_t len, RefCount< WriteRequest >)=0
int shm_offset
Definition: diomsg.h:40
int send(int mtype, int id, DiskdFile *theFile, size_t size, off_t offset, ssize_t shm_offset, Lock *requestor)
@ _MQD_CREATE
Definition: diomsg.h:21
struct diskd_stats_t::@41 create
const char * buf
Definition: WriteRequest.h:25
void read(ReadRequest *) override
Definition: DiskdFile.cc:118
Definition: diomsg.h:30
unsigned short mode_t
Definition: types.h:129
struct diskd_stats_t::@41 write
#define DBG_IMPORTANT
Definition: Stream.h:38
bool ioInProgress() const override
Definition: DiskdFile.cc:404
virtual void closeCompleted()=0
void readDone(diomsg *)
Definition: DiskdFile.cc:347
void create(int flags, mode_t aMode, RefCount< IORequestor > callback) override
Definition: DiskdFile.cc:84
#define DISK_ERROR
Definition: defines.h:28
@ _MQD_WRITE
Definition: diomsg.h:24
void createDone(diomsg *)
Definition: DiskdFile.cc:262
bool newstyle
Definition: diomsg.h:39
struct diskd_stats_t::@41 close
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
off_t offset
Definition: ReadRequest.h:25
mtyp_t mtype
Definition: diomsg.h:31
virtual void readCompleted(const char *buf, int len, int errflag, RefCount< ReadRequest >)=0
bool error() const override
Definition: DiskdFile.cc:175
bool errorOccured
Definition: DiskdFile.h:48
StatCounters statCounter
Definition: StatCounters.cc:12
DiskdIOStrategy * IO
Definition: DiskdFile.h:49
void notifyClient()
Definition: DiskdFile.cc:198

 

Introduction

Documentation

Support

Miscellaneous