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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors