|
22 | 22 | import org.apache.lucene.store.NativeFSLockFactory;
|
23 | 23 | import org.apache.lucene.store.ReadAdvice;
|
24 | 24 | import org.apache.lucene.store.SimpleFSLockFactory;
|
| 25 | +import org.elasticsearch.common.Strings; |
25 | 26 | import org.elasticsearch.common.settings.Setting;
|
26 | 27 | import org.elasticsearch.common.settings.Setting.Property;
|
27 | 28 | import org.elasticsearch.core.IOUtils;
|
|
35 | 36 | import org.elasticsearch.plugins.IndexStorePlugin;
|
36 | 37 |
|
37 | 38 | import java.io.IOException;
|
| 39 | +import java.nio.file.FileSystemException; |
38 | 40 | import java.nio.file.Files;
|
39 | 41 | import java.nio.file.Path;
|
40 | 42 | import java.util.HashSet;
|
@@ -154,22 +156,38 @@ protected boolean useDirectIO(String name, IOContext context, OptionalLong fileL
|
154 | 156 |
|
155 | 157 | @Override
|
156 | 158 | public IndexInput openInput(String name, IOContext context) throws IOException {
|
| 159 | + Throwable directIOException = null; |
157 | 160 | if (directIODelegate != null && context.hints().contains(DirectIOHint.INSTANCE)) {
|
158 | 161 | ensureOpen();
|
159 | 162 | ensureCanRead(name);
|
160 |
| - Log.debug("Opening {} with direct IO", name); |
161 |
| - return directIODelegate.openInput(name, context); |
162 |
| - } else if (useDelegate(name, context)) { |
163 |
| - // we need to do these checks on the outer directory since the inner doesn't know about pending deletes |
164 |
| - ensureOpen(); |
165 |
| - ensureCanRead(name); |
166 |
| - // we only use the mmap to open inputs. Everything else is managed by the NIOFSDirectory otherwise |
167 |
| - // we might run into trouble with files that are pendingDelete in one directory but still |
168 |
| - // listed in listAll() from the other. We on the other hand don't want to list files from both dirs |
169 |
| - // and intersect for perf reasons. |
170 |
| - return delegate.openInput(name, context); |
171 |
| - } else { |
172 |
| - return super.openInput(name, context); |
| 163 | + try { |
| 164 | + Log.debug("Opening {} with direct IO", name); |
| 165 | + return directIODelegate.openInput(name, context); |
| 166 | + } catch (FileSystemException e) { |
| 167 | + Log.debug(() -> Strings.format("Could not open %s with direct IO", name), e); |
| 168 | + directIOException = e; |
| 169 | + // and fallthrough to normal opening below |
| 170 | + } |
| 171 | + } |
| 172 | + |
| 173 | + try { |
| 174 | + if (useDelegate(name, context)) { |
| 175 | + // we need to do these checks on the outer directory since the inner doesn't know about pending deletes |
| 176 | + ensureOpen(); |
| 177 | + ensureCanRead(name); |
| 178 | + // we only use the mmap to open inputs. Everything else is managed by the NIOFSDirectory otherwise |
| 179 | + // we might run into trouble with files that are pendingDelete in one directory but still |
| 180 | + // listed in listAll() from the other. We on the other hand don't want to list files from both dirs |
| 181 | + // and intersect for perf reasons. |
| 182 | + return delegate.openInput(name, context); |
| 183 | + } else { |
| 184 | + return super.openInput(name, context); |
| 185 | + } |
| 186 | + } catch (Throwable t) { |
| 187 | + if (directIOException != null) { |
| 188 | + t.addSuppressed(directIOException); |
| 189 | + } |
| 190 | + throw t; |
173 | 191 | }
|
174 | 192 | }
|
175 | 193 |
|
|
0 commit comments