Repository: ignite Updated Branches: refs/heads/master 4bfedaf85 -> 2285420cf
IGNITE-8888 Fixed read methods leading to a potential data corruption - Fixes #4485. Signed-off-by: Alexey Goncharuk <alexey.goncha...@gmail.com> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2285420c Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2285420c Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2285420c Branch: refs/heads/master Commit: 2285420cf716bddfad2cf9b0b310fe4d56974540 Parents: 4bfedaf Author: Alexey Stelmak <spiderru5...@gmail.com> Authored: Thu Aug 9 15:21:42 2018 +0300 Committer: Alexey Goncharuk <alexey.goncha...@gmail.com> Committed: Thu Aug 9 15:21:42 2018 +0300 ---------------------------------------------------------------------- .../cache/persistence/file/AbstractFileIO.java | 30 +++++++-------- .../cache/persistence/file/FilePageStore.java | 39 ++++---------------- 2 files changed, 22 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/2285420c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/AbstractFileIO.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/AbstractFileIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/AbstractFileIO.java index 4723644..418c676 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/AbstractFileIO.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/AbstractFileIO.java @@ -46,7 +46,7 @@ public abstract class AbstractFileIO implements FileIO { * * @param num Number of bytes to operate. */ - private int fully(IOOperation operation, int num, boolean write) throws IOException { + private int fully(IOOperation operation, long position, int num, boolean write) throws IOException { if (num > 0) { long time = 0; @@ -58,14 +58,17 @@ public abstract class AbstractFileIO implements FileIO { time = 0; } else if (n == 0) { + if (!write && available(num - i, position + i) == 0) + return i; + if (time == 0) time = U.currentTimeMillis(); else if ((U.currentTimeMillis() - time) >= MAX_IO_TIMEOUT_MS) - throw new IOException(write && position() == size() ? "Failed to extend file." : + throw new IOException(write && (position + i) == size() ? "Failed to extend file." : "Probably disk is too busy, please check your device."); } else - throw new EOFException("EOF at position [" + position() + "] expected to read [" + num + "] bytes."); + return -1; } } @@ -78,7 +81,7 @@ public abstract class AbstractFileIO implements FileIO { @Override public int run(int offs) throws IOException { return read(destBuf); } - }, available(destBuf.remaining()), false); + }, position(), destBuf.remaining(), false); } /** {@inheritDoc} */ @@ -87,7 +90,7 @@ public abstract class AbstractFileIO implements FileIO { @Override public int run(int offs) throws IOException { return read(destBuf, position + offs); } - }, available(destBuf.remaining(), position), false); + }, position, destBuf.remaining(), false); } /** {@inheritDoc} */ @@ -96,7 +99,7 @@ public abstract class AbstractFileIO implements FileIO { @Override public int run(int offs) throws IOException { return read(buf, off + offs, len - offs); } - }, len, false); + }, position(), len, false); } /** {@inheritDoc} */ @@ -105,7 +108,7 @@ public abstract class AbstractFileIO implements FileIO { @Override public int run(int offs) throws IOException { return write(srcBuf); } - }, srcBuf.remaining(), true); + }, position(), srcBuf.remaining(), true); } /** {@inheritDoc} */ @@ -114,7 +117,7 @@ public abstract class AbstractFileIO implements FileIO { @Override public int run(int offs) throws IOException { return write(srcBuf, position + offs); } - }, srcBuf.remaining(), true); + }, position, srcBuf.remaining(), true); } /** {@inheritDoc} */ @@ -123,19 +126,14 @@ public abstract class AbstractFileIO implements FileIO { @Override public int run(int offs) throws IOException { return write(buf, off + offs, len - offs); } - }, len, true); - } - - /** - * @param requested Requested. - */ - private int available(int requested) throws IOException { - return available(requested, position()); + }, position(), len, true); } /** * @param requested Requested. * @param position Position. + * + * @return Bytes available. */ private int available(int requested, long position) throws IOException { long avail = size() - position; http://git-wip-us.apache.org/repos/asf/ignite/blob/2285420c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java index d2d5506..ca31f05 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java @@ -347,28 +347,20 @@ public class FilePageStore implements PageStore { long off = pageOffset(pageId); assert pageBuf.capacity() == pageSize; + assert pageBuf.remaining() == pageSize; assert pageBuf.position() == 0; assert pageBuf.order() == ByteOrder.nativeOrder(); assert off <= (allocated.get() - headerSize()) : "calculatedOffset=" + off + ", allocated=" + allocated.get() + ", headerSize="+headerSize(); - int len = pageSize; + int n = readWithFailover(pageBuf, off); - do { - int n = readWithFailover(pageBuf, off); + // If page was not written yet, nothing to read. + if (n < 0) { + pageBuf.put(new byte[pageBuf.remaining()]); - // If page was not written yet, nothing to read. - if (n < 0) { - pageBuf.put(new byte[pageBuf.remaining()]); - - return; - } - - off += n; - - len -= n; + return; } - while (len > 0); int savedCrc32 = PageIO.getCrc(pageBuf); @@ -405,22 +397,7 @@ public class FilePageStore implements PageStore { try { assert buf.remaining() == headerSize(); - int len = headerSize(); - - long off = 0; - - do { - int n = readWithFailover(buf, off); - - // If page was not written yet, nothing to read. - if (n < 0) - return; - - off += n; - - len -= n; - } - while (len > 0); + readWithFailover(buf, 0); } catch (IOException e) { throw new PersistentStorageIOException("Read error", e); @@ -738,7 +715,7 @@ public class FilePageStore implements PageStore { try { assert destBuf.remaining() > 0; - int bytesRead = fileIO.read(destBuf, position); + int bytesRead = fileIO.readFully(destBuf, position); if (interrupted) Thread.currentThread().interrupt();