]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/Blocking/BlockingFile.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / DiskIO / Blocking / BlockingFile.cc
1 /*
2 * Copyright (C) 1996-2021 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 47 Store Directory Routines */
10
11 #include "squid.h"
12 #include "BlockingFile.h"
13 #include "Debug.h"
14 #include "defines.h"
15 #include "DiskIO/IORequestor.h"
16 #include "DiskIO/ReadRequest.h"
17 #include "DiskIO/WriteRequest.h"
18 #include "fs_io.h"
19 #include "globals.h"
20
21 #include <cerrno>
22
23 CBDATA_CLASS_INIT(BlockingFile);
24
25 BlockingFile::BlockingFile(char const *aPath) : fd(-1), closed(true), error_(false)
26 {
27 assert(aPath);
28 debugs(79, 3, "BlockingFile::BlockingFile: " << aPath);
29 path_ = xstrdup(aPath);
30 }
31
32 BlockingFile::~BlockingFile()
33 {
34 safe_free(path_);
35 doClose();
36 }
37
38 void
39 BlockingFile::open(int flags, mode_t, RefCount<IORequestor> callback)
40 {
41 /* Simulate async calls */
42 fd = file_open(path_, flags);
43 ioRequestor = callback;
44
45 if (fd < 0) {
46 debugs(79, 3, "BlockingFile::open: got failure (" << errno << ")");
47 error(true);
48 } else {
49 closed = false;
50 ++store_open_disk_fd;
51 debugs(79, 3, "BlockingFile::open: opened FD " << fd);
52 }
53
54 callback->ioCompletedNotification();
55 }
56
57 /**
58 * Alias for BlockingFile::open(...)
59 \copydoc BlockingFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
60 */
61 void
62 BlockingFile::create(int flags, mode_t mode, RefCount<IORequestor> callback)
63 {
64 /* We use the same logic path for open */
65 open(flags, mode, callback);
66 }
67
68 void BlockingFile::doClose()
69 {
70 if (fd > -1) {
71 closed = true;
72 file_close(fd);
73 --store_open_disk_fd;
74 fd = -1;
75 }
76 }
77
78 void
79 BlockingFile::close()
80 {
81 debugs(79, 3, "BlockingFile::close: " << this << " closing for " << ioRequestor.getRaw());
82 doClose();
83 assert (ioRequestor.getRaw());
84 ioRequestor->closeCompleted();
85 }
86
87 bool
88 BlockingFile::canRead() const
89 {
90 return fd > -1;
91 }
92
93 bool
94 BlockingFile::error() const
95 {
96 if ((fd < 0 && !closed) || error_)
97 return true;
98
99 return false;
100 }
101
102 void BlockingFile::error(bool const &aBool)
103 {
104 error_ = aBool;
105 }
106
107 void
108 BlockingFile::read(ReadRequest *aRequest)
109 {
110 assert (fd > -1);
111 assert (ioRequestor.getRaw());
112 readRequest = aRequest;
113 debugs(79, 3, HERE << aRequest->len << " for FD " << fd << " at " << aRequest->offset);
114 file_read(fd, aRequest->buf, aRequest->len, aRequest->offset, ReadDone, this);
115 }
116
117 void
118 BlockingFile::ReadDone(int fd, const char *buf, int len, int errflag, void *my_data)
119 {
120 BlockingFile *myFile = static_cast<BlockingFile *>(my_data);
121 assert (myFile);
122 myFile->readDone (fd, buf, len, errflag);
123 }
124
125 void
126 BlockingFile::write(WriteRequest *aRequest)
127 {
128 debugs(79, 3, HERE << aRequest->len << " for FD " << fd << " at " << aRequest->offset);
129 writeRequest = aRequest;
130 file_write(fd,
131 aRequest->offset,
132 (char *)aRequest->buf,
133 aRequest->len,
134 WriteDone,
135 this,
136 aRequest->free_func);
137 }
138
139 bool
140 BlockingFile::ioInProgress() const
141 {
142 /** \retval false IO is never pending with UFS */
143 return false;
144 }
145
146 /* === STATIC =========================================================== */
147
148 void
149 BlockingFile::readDone(int rvfd, const char *buf, int len, int errflag)
150 {
151 debugs(79, 3, "BlockingFile::readDone: FD " << rvfd);
152 assert (fd == rvfd);
153
154 ssize_t rlen;
155
156 if (errflag) {
157 debugs(79, 3, "BlockingFile::readDone: got failure (" << errflag << ")");
158 rlen = -1;
159 } else {
160 rlen = (ssize_t) len;
161 }
162
163 if (errflag == DISK_EOF)
164 errflag = DISK_OK; /* EOF is signalled by len == 0, not errors... */
165
166 ReadRequest::Pointer result = readRequest;
167
168 readRequest = NULL;
169
170 ioRequestor->readCompleted(buf, rlen, errflag, result);
171 }
172
173 void
174 BlockingFile::WriteDone (int fd, int errflag, size_t len, void *me)
175 {
176 BlockingFile *aFile = static_cast<BlockingFile *>(me);
177 aFile->writeDone (fd, errflag, len);
178 }
179
180 void
181 BlockingFile::writeDone(int rvfd, int errflag, size_t len)
182 {
183 assert (rvfd == fd);
184 debugs(79, 3, HERE << "FD " << fd << ", len " << len);
185
186 WriteRequest::Pointer result = writeRequest;
187 writeRequest = NULL;
188
189 if (errflag) {
190 debugs(79, DBG_CRITICAL, "storeUfsWriteDone: got failure (" << errflag << ")");
191 doClose();
192 ioRequestor->writeCompleted (DISK_ERROR,0, result);
193 return;
194 }
195
196 ioRequestor->writeCompleted(DISK_OK, len, result);
197 }
198