Search in sources :

Example 31 with FMFileManagerException

use of com.biglybt.core.diskmanager.file.FMFileManagerException in project BiglyBT by BiglySoftware.

the class FMFileAccessController method convertSupport.

private void convertSupport(int target_type, boolean force) throws FMFileManagerException {
    if (type == target_type) {
        return;
    }
    if (type == FMFile.FT_PIECE_REORDER || type == FMFile.FT_PIECE_REORDER_COMPACT || target_type == FMFile.FT_PIECE_REORDER || target_type == FMFile.FT_PIECE_REORDER_COMPACT) {
        if ((target_type == FMFile.FT_PIECE_REORDER_COMPACT && type == FMFile.FT_PIECE_REORDER) || (target_type == FMFile.FT_PIECE_REORDER && type == FMFile.FT_PIECE_REORDER_COMPACT)) {
            // these two access modes are in fact identical at the moment
            type = target_type;
            return;
        }
        throw (new FMFileManagerException("Conversion to/from piece-reorder not supported"));
    }
    File file = owner.getLinkedFile();
    FileAccessor fa = null;
    boolean ok = false;
    try {
        FMFileAccess target_access;
        if (target_type == FMFile.FT_LINEAR) {
            target_access = new FMFileAccessLinear(owner);
        } else {
            target_access = new FMFileAccessCompact(owner.getOwner().getTorrentFile(), control_dir, controlFileName, new FMFileAccessLinear(owner));
        }
        if (file.exists()) {
            fa = FileUtil.newFileAccessor(file, FMFileImpl.WRITE_ACCESS_MODE);
            // due to the simplistic implementation of compact we only actually need to deal with
            // the last piece of the file (first piece is in the right place already)
            FMFileAccessCompact compact_access;
            if (target_type == FMFile.FT_LINEAR) {
                compact_access = (FMFileAccessCompact) file_access;
            } else {
                compact_access = (FMFileAccessCompact) target_access;
            }
            long length = file_access.getLength(fa);
            long last_piece_start = compact_access.getLastPieceStart();
            long last_piece_length = compact_access.getLastPieceLength();
            if (last_piece_length > 0 && length > last_piece_start) {
                long data_length = length - last_piece_start;
                if (data_length > last_piece_length) {
                    Debug.out("data length inconsistent: len=" + data_length + ",limit=" + last_piece_length);
                    data_length = last_piece_length;
                }
                DirectByteBuffer buffer = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_FILE, (int) data_length);
                try {
                    file_access.read(fa, new DirectByteBuffer[] { buffer }, last_piece_start);
                    if (target_type == FMFile.FT_COMPACT) {
                        long first_piece_length = compact_access.getFirstPieceLength();
                        long physical_length = fa.getLength();
                        if (physical_length > first_piece_length) {
                            fa.setLength(first_piece_length);
                        }
                    }
                    buffer.flip(DirectByteBuffer.AL_FILE);
                    target_access.write(fa, new DirectByteBuffer[] { buffer }, last_piece_start);
                } finally {
                    buffer.returnToPool();
                }
            } else {
                if (target_type == FMFile.FT_COMPACT) {
                    long first_piece_length = compact_access.getFirstPieceLength();
                    long physical_length = fa.getLength();
                    if (physical_length > first_piece_length) {
                        fa.setLength(first_piece_length);
                    }
                }
            }
            target_access.setLength(fa, length);
            target_access.flush();
        }
        type = target_type;
        file_access = target_access;
        ok = true;
    } catch (Throwable e) {
        Debug.printStackTrace(e);
        throw (new FMFileManagerException("convert fails", e));
    } finally {
        try {
            if (fa != null) {
                try {
                    fa.close();
                } catch (Throwable e) {
                    if (ok) {
                        ok = false;
                        throw (new FMFileManagerException("convert fails", e));
                    }
                }
            }
        } finally {
            if (!ok) {
                // conversion failed - replace with linear access, caller is responsible for
                // handling this (marking file requiring recheck)
                type = FMFile.FT_LINEAR;
                file_access = new FMFileAccessLinear(owner);
            }
            if (type == FMFile.FT_LINEAR) {
                FileUtil.newFile(control_dir, controlFileName).delete();
            }
        }
    }
}
Also used : FMFileManagerException(com.biglybt.core.diskmanager.file.FMFileManagerException) RandomAccessFile(java.io.RandomAccessFile) TOTorrentFile(com.biglybt.core.torrent.TOTorrentFile) File(java.io.File) FMFile(com.biglybt.core.diskmanager.file.FMFile)

Example 32 with FMFileManagerException

use of com.biglybt.core.diskmanager.file.FMFileManagerException in project BiglyBT by BiglySoftware.

the class FMFileAccessPieceReorderer method configBorked.

private void configBorked(String error) throws FMFileManagerException {
    piece_map = new int[num_pieces];
    piece_reverse_map = new int[num_pieces];
    Arrays.fill(piece_map, -1);
    piece_map[0] = 0;
    piece_reverse_map[0] = 0;
    current_length = getFile().getLinkedFile().length();
    int piece_count = (int) ((current_length + piece_size - 1) / piece_size) + 1;
    if (piece_count > num_pieces) {
        piece_count = num_pieces;
    }
    for (int i = 1; i < piece_count; i++) {
        piece_map[i] = i;
        piece_reverse_map[i] = i;
    }
    next_piece_index = piece_count;
    writeConfig();
    FMFileManagerException e = new FMFileManagerException(error);
    e.setRecoverable(false);
    throw (e);
}
Also used : FMFileManagerException(com.biglybt.core.diskmanager.file.FMFileManagerException)

Example 33 with FMFileManagerException

use of com.biglybt.core.diskmanager.file.FMFileManagerException in project BiglyBT by BiglySoftware.

the class FMFileAccessPieceReorderer method readWritePiece.

protected int readWritePiece(FileAccessor fa, DirectByteBuffer[] buffers, int piece_number, int piece_offset, boolean is_read) throws FMFileManagerException {
    String str = is_read ? "read" : "write";
    if (piece_number >= num_pieces) {
        throw (new FMFileManagerException("Attempt to " + str + " piece " + piece_number + ": last=" + num_pieces));
    }
    int this_piece_size = piece_number == 0 ? first_piece_length : (piece_number == (num_pieces - 1) ? last_piece_length : piece_size);
    final int piece_space = this_piece_size - piece_offset;
    if (piece_space <= 0) {
        throw (new FMFileManagerException("Attempt to " + str + " piece " + piece_number + ", offset " + piece_offset + " - no space in piece"));
    }
    int rem_space = piece_space;
    int[] limits = new int[buffers.length];
    for (int i = 0; i < buffers.length; i++) {
        DirectByteBuffer buffer = buffers[i];
        limits[i] = buffer.limit(SS_FILE);
        int rem = buffer.remaining(SS_FILE);
        if (rem > rem_space) {
            buffer.limit(SS_FILE, buffer.position(SS_FILE) + rem_space);
            rem_space = 0;
        } else {
            rem_space -= rem;
        }
    }
    try {
        long piece_start = getPieceOffset(fa, piece_number, !is_read);
        if (TRACE) {
            System.out.println(str + " to " + piece_number + "/" + piece_offset + "/" + this_piece_size + "/" + piece_space + "/" + rem_space + "/" + piece_start);
        }
        if (piece_start == -1) {
            return (0);
        }
        long piece_io_position = piece_start + piece_offset;
        if (is_read) {
            delegate.read(fa, buffers, piece_io_position);
        } else {
            delegate.write(fa, buffers, piece_io_position);
        }
        return (piece_space - rem_space);
    } finally {
        for (int i = 0; i < buffers.length; i++) {
            buffers[i].limit(SS_FILE, limits[i]);
        }
    }
}
Also used : FMFileManagerException(com.biglybt.core.diskmanager.file.FMFileManagerException)

Example 34 with FMFileManagerException

use of com.biglybt.core.diskmanager.file.FMFileManagerException in project BiglyBT by BiglySoftware.

the class FMFileAccessPieceReorderer method readWrite.

protected void readWrite(FileAccessor fa, DirectByteBuffer[] buffers, long position, boolean is_read) throws FMFileManagerException {
    long total_length = 0;
    for (DirectByteBuffer buffer : buffers) {
        total_length += buffer.remaining(SS_FILE);
    }
    if (!is_read && position + total_length > current_length) {
        current_length = position + total_length;
        setDirty();
    }
    long current_position = position;
    while (total_length > 0) {
        int piece_number;
        int piece_offset;
        if (current_position < first_piece_length) {
            piece_number = 0;
            piece_offset = (int) current_position;
        } else {
            long offset = current_position - first_piece_length;
            piece_number = (int) (offset / piece_size) + 1;
            piece_offset = (int) (offset % piece_size);
        }
        int count = readWritePiece(fa, buffers, piece_number, piece_offset, is_read);
        if (count == 0) {
            if (is_read) {
                for (DirectByteBuffer buffer : buffers) {
                    ByteBuffer bb = buffer.getBuffer(SS_FILE);
                    int rem = bb.remaining();
                    if (rem > 0) {
                        bb.put(new byte[rem]);
                        // not great this... to obey the normal file access semantics reads are
                        // never partial (normally we'd extend the file to accomodate the read but
                        // in the case of re-order access we don't want to do this when hash checking
                        // a file. The issue is in the unlikely case where our padding happens to
                        // match the real file contents and results in a piece hash check succeeding
                        // even though the data doesn't actually exist on disk... So I've added this
                        // flag to cause hash checking to always fail if the resulting data isn't 'real'
                        // this of course relies on this buffer being passed back to the checking process
                        // intact, which is the case currently during rechecks...
                        buffer.setFlag(DirectByteBuffer.FL_CONTAINS_TRANSIENT_DATA);
                    }
                }
            } else {
                throw (new FMFileManagerException("partial write operation"));
            }
            return;
        }
        total_length -= count;
        current_position += count;
    }
}
Also used : FMFileManagerException(com.biglybt.core.diskmanager.file.FMFileManagerException) ByteBuffer(java.nio.ByteBuffer)

Example 35 with FMFileManagerException

use of com.biglybt.core.diskmanager.file.FMFileManagerException in project BiglyBT by BiglySoftware.

the class FMFileAccessCompact method readState.

protected void readState() throws FMFileManagerException {
    try {
        Map data = FileUtil.readResilientFile(controlFileDir, controlFileName, false);
        if (data != null && data.size() > 0) {
            // Long	version = (Long)data.get( "version" );
            Long length = (Long) data.get("length");
            current_length = length.longValue();
        }
    } catch (Throwable e) {
        throw (new FMFileManagerException("Failed to read control file state", e));
    }
}
Also used : FMFileManagerException(com.biglybt.core.diskmanager.file.FMFileManagerException) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

FMFileManagerException (com.biglybt.core.diskmanager.file.FMFileManagerException)35 FMFile (com.biglybt.core.diskmanager.file.FMFile)14 TOTorrentFile (com.biglybt.core.torrent.TOTorrentFile)8 File (java.io.File)7 IOException (java.io.IOException)7 ByteBuffer (java.nio.ByteBuffer)6 MappedByteBuffer (java.nio.MappedByteBuffer)6 FileChannel (java.nio.channels.FileChannel)6 CacheFileManagerException (com.biglybt.core.diskmanager.cache.CacheFileManagerException)3 LogEvent (com.biglybt.core.logging.LogEvent)3 RandomAccessFile (java.io.RandomAccessFile)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 FMFileOwner (com.biglybt.core.diskmanager.file.FMFileOwner)1 TOTorrent (com.biglybt.core.torrent.TOTorrent)1 FileNotFoundException (java.io.FileNotFoundException)1