DiskThreadsDiskFile.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 Disk IO Routines */
10 
11 #include "squid.h"
12 #include "comm.h"
13 #include "DiskIO/IORequestor.h"
14 #include "DiskIO/ReadRequest.h"
15 #include "DiskIO/WriteRequest.h"
16 #include "DiskThreadsDiskFile.h"
17 #include "fd.h"
18 #include "fs_io.h"
19 #include "Generic.h"
20 #include "globals.h"
21 #include "StatCounters.h"
22 #include "Store.h"
23 
24 #include <cerrno>
25 
26 /* === PUBLIC =========================================================== */
27 
29 
31 {
32  assert(aPath);
33  debugs(79, 3, "UFSFile::UFSFile: " << aPath);
34  path_ = xstrdup(aPath);
35 }
36 
38 {
40  doClose();
41 }
42 
43 void
45 {
46  ++statCounter.syscalls.disk.opens;
47 #if !ASYNC_OPEN
48 
49  fd = file_open(path_, flags);
50 
51  if (fd < 0) {
52  debugs(79, 3, "DiskThreadsDiskFile::open: got failure (" << errno << ")");
53  errorOccured = true;
54  return;
55  }
56 
57 #endif
58  ++Opening_FD;
59 
60  ioRequestor = callback;
61 
62  ++inProgressIOs;
63 
64 #if ASYNC_OPEN
65 
66  aioOpen(path_, flags, mode, DiskThreadsDiskFile::OpenDone, this);
67 
68 #else
69 
70  openDone(fd, nullptr, fd, 0);
71 
72 #endif
73 }
74 
75 void
77 {
78  debugs(79, 3, "DiskThreadsDiskFile::read: " << this << ", size " << request->len);
79  assert (fd > -1);
81  ++statCounter.syscalls.disk.reads;
82  ++inProgressIOs;
83 #if ASYNC_READ
84 
85  aioRead(fd, request->offset, request->len, ReadDone, new IoResult<ReadRequest>(this, request));
86 #else
87 
88  file_read(fd, request->buf, request->len, request->offset, ReadDone, new IoResult<ReadRequest>(this, request));
89 #endif
90 }
91 
92 void
94 {
95  ++statCounter.syscalls.disk.opens;
96 #if !ASYNC_CREATE
97 
98  int fd = file_open(path_, flags);
99 
100  if (fd < 0) {
101  debugs(79, 3, "DiskThreadsDiskFile::create: got failure (" << errno << ")");
102  errorOccured = true;
103  return;
104  }
105 
106 #endif
107  ++Opening_FD;
108 
109  ioRequestor = callback;
110 
111  ++inProgressIOs;
112 
113 #if ASYNC_CREATE
114 
115  aioOpen(path_, flags, mode, DiskThreadsDiskFile::OpenDone, this);
116 
117 #else
118 
119  openDone (fd, nullptr, fd, 0);
120 
121 #endif
122 }
123 
124 bool
126 {
127  return errorOccured;
128 }
129 
130 void
131 DiskThreadsDiskFile::OpenDone(int fd, void *cbdata, const char *buf, int aio_return, int aio_errno)
132 {
133  DiskThreadsDiskFile *myFile = static_cast<DiskThreadsDiskFile *>(cbdata);
134  myFile->openDone (fd, buf, aio_return, aio_errno);
135 }
136 
137 void
138 DiskThreadsDiskFile::openDone(int, const char *, int anFD, int errflag)
139 {
140  debugs(79, 3, "DiskThreadsDiskFile::openDone: FD " << anFD << ", errflag " << errflag);
141  --Opening_FD;
142 
143  fd = anFD;
144 
145  if (errflag || fd < 0) {
146  debugs(79, DBG_CRITICAL, MYNAME << xstrerr(errflag));
147  debugs(79, DBG_IMPORTANT, "\t" << path_);
148  errorOccured = true;
149  } else {
152  fd_open(fd, FD_FILE, path_);
153  }
154 
156  --inProgressIOs;
158 
159  debugs(79, 3, "DiskThreadsDiskFile::openDone: exiting");
160 }
161 
163 {
164  if (fd > -1) {
165  ++statCounter.syscalls.disk.closes;
166 #if ASYNC_CLOSE
167 
168  aioClose(fd);
169  fd_close(fd);
170 #else
171 
172  aioCancel(fd);
173  file_close(fd);
174 #endif
175 
177  fd = -1;
178  }
179 }
180 
181 void
183 {
184  debugs(79, 3, "DiskThreadsDiskFile::close: " << this << " closing for " << ioRequestor.getRaw());
185 
186  if (!ioInProgress()) {
187  doClose();
188  assert (ioRequestor != nullptr);
190  return;
191  } else {
192  debugs(79, DBG_CRITICAL, "DiskThreadsDiskFile::close: " <<
193  "did NOT close because ioInProgress() is true. now what?");
194  }
195 }
196 
197 bool
199 {
200  debugs(79, 3, "DiskThreadsDiskFile::canRead: fd is " << fd);
201  return fd > -1;
202 }
203 
204 void
206 {
207  debugs(79, 3, "DiskThreadsDiskFile::write: FD " << fd);
208  ++statCounter.syscalls.disk.writes;
209  ++inProgressIOs;
210 #if ASYNC_WRITE
211 
212  aioWrite(fd, writeRequest->offset, (char *)writeRequest->buf, writeRequest->len, WriteDone, new IoResult<WriteRequest>(this, writeRequest),
213  writeRequest->free_func);
214 #else
215 
216  file_write(fd, writeRequest->offset, (char *)writeRequest->buf, writeRequest->len, WriteDone, new IoResult<WriteRequest>(this, writeRequest),
217  writeRequest->free_func);
218 #endif
219 }
220 
221 bool
223 {
224  return fd > -1;
225 }
226 
227 bool
229 {
230  return inProgressIOs > 0;
231 }
232 
233 /* === STATIC =========================================================== */
234 
235 #if ASYNC_READ
236 void
237 DiskThreadsDiskFile::ReadDone(int fd, void *my_data, const char *buf, int len, int errflag)
238 #else
239 void
240 DiskThreadsDiskFile::ReadDone(int fd, const char *buf, int len, int errflag, void *my_data)
241 #endif
242 {
243  IoResult<ReadRequest> * result = static_cast<IoResult<ReadRequest> *>(my_data);
244  assert (result);
245  result->file->readDone(fd, buf, len, errflag, result->request);
246  delete result;
247 }
248 
249 void
250 DiskThreadsDiskFile::readDone(int rvfd, const char *buf, int len, int errflag, const RefCount<ReadRequest> &request)
251 {
252  debugs(79, 3, "DiskThreadsDiskFile::readDone: FD " << rvfd);
253  assert (fd == rvfd);
254 
255  ssize_t rlen;
256 
257  if (errflag) {
258  debugs(79, 3, "DiskThreadsDiskFile::readDone: got failure (" << errflag << ")");
259  rlen = -1;
260  } else {
261  rlen = (ssize_t) len;
262  }
263 
264 #if ASYNC_READ
265  /* translate errflag from errno to Squid disk error */
266  errno = errflag;
267 
268  if (errflag)
269  errflag = DISK_ERROR;
270  else
271  errflag = DISK_OK;
272 
273 #else
274 
275  if (errflag == DISK_EOF)
276  errflag = DISK_OK; /* EOF is signalled by len == 0, not errors... */
277 
278 #endif
279 
280  --inProgressIOs;
281 
282  ioRequestor->readCompleted(buf, rlen, errflag, request);
283 }
284 
285 void
287 #if ASYNC_WRITE
288 WriteDone(int fd, void *my_data, const char *buf, int len, int errflag)
289 #else
290 WriteDone(int fd, int errflag, size_t len, void *my_data)
291 #endif
292 {
293  IoResult<WriteRequest> * result = static_cast<IoResult<WriteRequest> *>(my_data);
294  assert (result);
295  result->file->writeDone(fd, errflag, len, result->request);
296  delete result;
297 }
298 
299 void
300 DiskThreadsDiskFile::writeDone(int rvfd, int errflag, size_t len, RefCount<WriteRequest> request)
301 {
302  assert (rvfd == fd);
303  static int loop_detect = 0;
304 
305 #if ASYNC_WRITE
306  /* Translate from errno to Squid disk error */
307 
308  if (errflag)
309  errflag = errflag == ENOSPC ? DISK_NO_SPACE_LEFT : DISK_ERROR;
310  else
311  errflag = DISK_OK;
312 
313 #endif
314 
315  debugs(79, 3, "DiskThreadsDiskFile::writeDone: FD " << fd << ", len " << len << ", err=" << errflag);
316 
317  ++loop_detect;
318  assert(loop_detect < 10);
319 
320  --inProgressIOs;
321 
322  ioRequestor->writeCompleted(errflag, len, request);
323 
324  --loop_detect;
325 }
326 
328 template <class RT>
RefCount< RT > request
const char * xstrerr(int error)
Definition: xstrerror.cc:83
#define DBG_CRITICAL
Definition: Stream.h:37
void aioRead(int fd, off_t offset, size_t len, AIOCB *callback, void *callback_data)
Definition: async_io.cc:135
#define DISK_EOF
Definition: defines.h:29
void aioOpen(const char *path, int oflag, mode_t mode, AIOCB *callback, void *callback_data)
Definition: async_io.cc:29
DiskThreadsDiskFile(char const *path)
void commSetCloseOnExec(int)
Definition: minimal.cc:27
int Opening_FD
#define xstrdup
struct StatCounters::@119::@123 disk
Definition: cbdata.cc:37
void file_read(int fd, char *buf, int req_len, off_t offset, DRCB *handler, void *client_data)
Definition: fs_io.cc:425
C * getRaw() const
Definition: RefCount.h:89
void file_close(int fd)
Definition: fs_io.cc:93
void fd_open(const int fd, unsigned int, const char *description)
Definition: minimal.cc:15
int store_open_disk_fd
bool canWrite() const override
#define DISK_OK
Definition: defines.h:27
struct StatCounters::@119 syscalls
void aioClose(int fd)
Definition: async_io.cc:47
void aioWrite(int fd, off_t offset, char *bufp, size_t len, AIOCB *callback, void *callback_data, FREE *free_func)
Definition: async_io.cc:107
bool error() const override
static const cbdata_type CBDATA_UNKNOWN
Definition: cbdata.h:196
#define DISK_NO_SPACE_LEFT
Definition: defines.h:30
virtual void ioCompletedNotification()=0
int cbdata_type
Definition: cbdata.h:195
void aioCancel(int fd)
Definition: async_io.cc:66
bool canRead() const override
#define safe_free(x)
Definition: xalloc.h:73
#define assert(EX)
Definition: assert.h:17
void open(int flags, mode_t mode, RefCount< IORequestor > callback) override
void read(ReadRequest *) override
size_t len
Definition: ReadRequest.h:26
void create(int flags, mode_t mode, RefCount< IORequestor > callback) override
FREE * free_func
Definition: WriteRequest.h:28
void writeDone(int fd, int errflag, size_t len, RefCount< WriteRequest > request)
virtual void writeCompleted(int errflag, size_t len, RefCount< WriteRequest >)=0
char * buf
Definition: ReadRequest.h:24
RefCount< DiskThreadsDiskFile > file
void file_write(int fd, off_t file_offset, void const *ptr_to_buf, int len, DWCB *handle, void *handle_data, FREE *free_func)
Definition: fs_io.cc:314
const char * buf
Definition: WriteRequest.h:25
bool ioInProgress() const override
unsigned short mode_t
Definition: types.h:129
#define DBG_IMPORTANT
Definition: Stream.h:38
#define MYNAME
Definition: Stream.h:219
virtual void closeCompleted()=0
void fd_close(const int fd)
Definition: minimal.cc:21
#define DISK_ERROR
Definition: defines.h:28
void readDone(int fd, const char *buf, int len, int errflag, const RefCount< ReadRequest > &request)
int file_open(const char *path, int mode)
Definition: fs_io.cc:65
void openDone(int fd, const char *buf, int aio_return, int aio_errno)
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
off_t offset
Definition: ReadRequest.h:25
@ FD_FILE
Definition: enums.h:15
CBDATA_CLASS_INIT(DiskThreadsDiskFile)
virtual void readCompleted(const char *buf, int len, int errflag, RefCount< ReadRequest >)=0
RefCount< IORequestor > ioRequestor
StatCounters statCounter
Definition: StatCounters.cc:12
void write(WriteRequest *) override

 

Introduction

Documentation

Support

Miscellaneous