From e3c1d221fb7eae9f5b3cf3af2446feb7bab4e548 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 13 Mar 2008 00:38:16 +0000 Subject: [PATCH] #781: experimental commit on the "failed data" issue. --- libtransmission/inout.c | 44 ++++++++++++++++++++++----------------- libtransmission/torrent.c | 7 ++++--- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/libtransmission/inout.c b/libtransmission/inout.c index 9b2938b6c..f88bad472 100644 --- a/libtransmission/inout.c +++ b/libtransmission/inout.c @@ -12,17 +12,18 @@ #include #include +#include /* realloc */ #include /* memcmp */ #include #include #include -#include - #include "transmission.h" +#include "crypto.h" #include "fdlimit.h" #include "inout.h" +#include "platform.h" #include "stats.h" #include "torrent.h" #include "utils.h" @@ -220,33 +221,38 @@ tr_ioRecalculateHash( const tr_torrent * tor, int pieceIndex, uint8_t * setme ) { - int offset; - int bytesLeft; - uint8_t buf[4096]; + static uint8_t * buf = NULL; + static int buflen = 0; + static tr_lock * lock = NULL; + + int n; + tr_errno err; const tr_info * info; - SHA_CTX sha; + + /* only check one block at a time to prevent disk thrashing. + * this also lets us reuse the same buffer each time. */ + if( lock == NULL ) + lock = tr_lockNew( ); + + tr_lockLock( lock ); assert( tor != NULL ); assert( setme != NULL ); assert( 0<=pieceIndex && pieceIndexinfo.pieceCount ); info = &tor->info; - offset = 0; - bytesLeft = tr_torPieceCountBytes( tor, pieceIndex ); - SHA1_Init( &sha ); + n = tr_torPieceCountBytes( tor, pieceIndex ); - while( bytesLeft > 0 ) - { - const int bytesThisPass = MIN( bytesLeft, (int)sizeof(buf) ); - tr_errno err = tr_ioRead( tor, pieceIndex, offset, bytesThisPass, buf ); - if( err ) - return err; - SHA1_Update( &sha, buf, bytesThisPass ); - bytesLeft -= bytesThisPass; - offset += bytesThisPass; + if( buflen < n ) { + buflen = n; + buf = tr_renew( uint8_t, buf, buflen ); } + + err = tr_ioRead( tor, pieceIndex, 0, n, buf ); + if( !err ) + tr_sha1( setme, buf, n, NULL ); - SHA1_Final( setme, &sha ); + tr_lockUnlock( lock ); return 0; } diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index ea11cdb50..0e2e710fa 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -41,6 +41,8 @@ #include "utils.h" #include "verify.h" +#define MAX_BLOCK_SIZE (1024*16) + /*** **** ***/ @@ -289,7 +291,7 @@ torrentRealInit( tr_handle * h, * (2) pieceSize must be a multiple of block size */ tor->blockSize = info->pieceSize; - while( tor->blockSize > (1024*16) ) + while( tor->blockSize > MAX_BLOCK_SIZE ) tor->blockSize /= 2; tor->lastPieceSize = info->totalSize % info->pieceSize; @@ -1295,14 +1297,13 @@ tr_torrentReqIsValid( const tr_torrent * tor, uint32_t offset, uint32_t length ) { - static const uint32_t MAX_REQUEST_BYTE_COUNT = (16 * 1024); int err = 0; if( index >= (uint32_t) tor->info.pieceCount ) err = 1; else if ( (int)offset >= tr_torPieceCountBytes( tor, (int)index ) ) err = 2; - else if( length > MAX_REQUEST_BYTE_COUNT ) + else if( length > MAX_BLOCK_SIZE ) err = 3; else if( tr_pieceOffset( tor, index, offset, length ) > tor->info.totalSize ) err = 4;