]>
Commit | Line | Data |
---|---|---|
b9ae18aa | 1 | /* |
5b74111a | 2 | * Copyright (C) 1996-2018 The Squid Software Foundation and contributors |
b9ae18aa | 3 | * |
bbc27441 AJ |
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. | |
b9ae18aa | 7 | */ |
bbc27441 AJ |
8 | |
9 | /* DEBUG: section 47 Store Directory Routines */ | |
10 | ||
f7f3304a | 11 | #include "squid.h" |
b9ae18aa | 12 | #include "BlockingFile.h" |
582c2af2 | 13 | #include "Debug.h" |
67679543 | 14 | #include "defines.h" |
b9ae18aa | 15 | #include "DiskIO/IORequestor.h" |
16 | #include "DiskIO/ReadRequest.h" | |
17 | #include "DiskIO/WriteRequest.h" | |
b3f7fd88 | 18 | #include "fs_io.h" |
602d9612 | 19 | #include "globals.h" |
b9ae18aa | 20 | |
1a30fdf5 | 21 | #include <cerrno> |
b9ae18aa | 22 | |
f49c09b2 | 23 | CBDATA_CLASS_INIT(BlockingFile); |
b9ae18aa | 24 | |
86c63190 | 25 | BlockingFile::BlockingFile(char const *aPath) : fd(-1), closed(true), error_(false) |
b9ae18aa | 26 | { |
63be0a78 | 27 | assert(aPath); |
bf8fe701 | 28 | debugs(79, 3, "BlockingFile::BlockingFile: " << aPath); |
86c63190 | 29 | path_ = xstrdup(aPath); |
b9ae18aa | 30 | } |
31 | ||
32 | BlockingFile::~BlockingFile() | |
33 | { | |
86c63190 | 34 | safe_free(path_); |
b9ae18aa | 35 | doClose(); |
36 | } | |
37 | ||
38 | void | |
ced8def3 | 39 | BlockingFile::open(int flags, mode_t, RefCount<IORequestor> callback) |
b9ae18aa | 40 | { |
41 | /* Simulate async calls */ | |
9e167fa2 | 42 | fd = file_open(path_, flags); |
b9ae18aa | 43 | ioRequestor = callback; |
44 | ||
45 | if (fd < 0) { | |
bf8fe701 | 46 | debugs(79, 3, "BlockingFile::open: got failure (" << errno << ")"); |
b9ae18aa | 47 | error(true); |
48 | } else { | |
49 | closed = false; | |
cb4185f1 | 50 | ++store_open_disk_fd; |
bf8fe701 | 51 | debugs(79, 3, "BlockingFile::open: opened FD " << fd); |
b9ae18aa | 52 | } |
53 | ||
54 | callback->ioCompletedNotification(); | |
55 | } | |
56 | ||
63be0a78 | 57 | /** |
58 | * Alias for BlockingFile::open(...) | |
59 | \copydoc BlockingFile::open(int flags, mode_t mode, RefCount<IORequestor> callback) | |
60 | */ | |
b9ae18aa | 61 | void |
63be0a78 | 62 | BlockingFile::create(int flags, mode_t mode, RefCount<IORequestor> callback) |
b9ae18aa | 63 | { |
64 | /* We use the same logic path for open */ | |
65 | open(flags, mode, callback); | |
66 | } | |
67 | ||
b9ae18aa | 68 | void BlockingFile::doClose() |
69 | { | |
70 | if (fd > -1) { | |
71 | closed = true; | |
72 | file_close(fd); | |
cb4185f1 | 73 | --store_open_disk_fd; |
b9ae18aa | 74 | fd = -1; |
75 | } | |
76 | } | |
77 | ||
78 | void | |
63be0a78 | 79 | BlockingFile::close() |
b9ae18aa | 80 | { |
bf8fe701 | 81 | debugs(79, 3, "BlockingFile::close: " << this << " closing for " << ioRequestor.getRaw()); |
b9ae18aa | 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; | |
e2851fe7 | 113 | debugs(79, 3, HERE << aRequest->len << " for FD " << fd << " at " << aRequest->offset); |
b9ae18aa | 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 | { | |
e2851fe7 | 128 | debugs(79, 3, HERE << aRequest->len << " for FD " << fd << " at " << aRequest->offset); |
b9ae18aa | 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 | |
63be0a78 | 140 | BlockingFile::ioInProgress() const |
b9ae18aa | 141 | { |
63be0a78 | 142 | /** \retval false IO is never pending with UFS */ |
b9ae18aa | 143 | return false; |
144 | } | |
145 | ||
146 | /* === STATIC =========================================================== */ | |
147 | ||
148 | void | |
149 | BlockingFile::readDone(int rvfd, const char *buf, int len, int errflag) | |
150 | { | |
bf8fe701 | 151 | debugs(79, 3, "BlockingFile::readDone: FD " << rvfd); |
b9ae18aa | 152 | assert (fd == rvfd); |
153 | ||
154 | ssize_t rlen; | |
155 | ||
156 | if (errflag) { | |
bf8fe701 | 157 | debugs(79, 3, "BlockingFile::readDone: got failure (" << errflag << ")"); |
b9ae18aa | 158 | rlen = -1; |
159 | } else { | |
160 | rlen = (ssize_t) len; | |
161 | } | |
162 | ||
163 | if (errflag == DISK_EOF) | |
f53969cc | 164 | errflag = DISK_OK; /* EOF is signalled by len == 0, not errors... */ |
b9ae18aa | 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); | |
e557e9df | 184 | debugs(79, 3, HERE << "FD " << fd << ", len " << len); |
b9ae18aa | 185 | |
186 | WriteRequest::Pointer result = writeRequest; | |
187 | writeRequest = NULL; | |
188 | ||
189 | if (errflag) { | |
fa84c01d | 190 | debugs(79, DBG_CRITICAL, "storeUfsWriteDone: got failure (" << errflag << ")"); |
b9ae18aa | 191 | doClose(); |
192 | ioRequestor->writeCompleted (DISK_ERROR,0, result); | |
193 | return; | |
194 | } | |
195 | ||
196 | ioRequestor->writeCompleted(DISK_OK, len, result); | |
197 | } | |
198 |