Changeset 5042


Ignore:
Timestamp:
Feb 15, 2008, 4:00:46 PM (13 years ago)
Author:
charles
Message:

modify "verify local data" to not lose the blocks in incomplete pieces

Location:
trunk/libtransmission
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/Makefile.am

    r4869 r5042  
    3434    trevent.c \
    3535    upnp.c \
    36     utils.c
     36    utils.c \
     37    verify.c
    3738
    3839noinst_HEADERS = \
     
    6970    trevent.h \
    7071    upnp.h \
    71     utils.h
     72    utils.h \
     73    verify.h
    7274
    7375
  • trunk/libtransmission/inout.c

    r4886 r5042  
    199199
    200200tr_errno
    201 tr_ioRead( tr_torrent  * tor,
    202            int           pieceIndex,
    203            int           begin,
    204            int           len,
    205            uint8_t     * buf )
    206 {
    207     return readOrWritePiece( tor, TR_IO_READ, pieceIndex, begin, buf, len );
     201tr_ioRead( const tr_torrent  * tor,
     202           int                 pieceIndex,
     203           int                 begin,
     204           int                 len,
     205           uint8_t           * buf )
     206{
     207    return readOrWritePiece( (tr_torrent*)tor, TR_IO_READ, pieceIndex, begin, buf, len );
    208208}
    209209
     
    223223
    224224static int
    225 tr_ioRecalculateHash( tr_torrent  * tor,
    226                       int           pieceIndex,
    227                       uint8_t     * setme )
     225tr_ioRecalculateHash( const tr_torrent  * tor,
     226                      int                 pieceIndex,
     227                      uint8_t           * setme )
    228228{
    229229    int offset;
     
    257257}
    258258
    259 static int
    260 checkPiece( tr_torrent * tor, int pieceIndex )
     259int
     260tr_ioTestPiece( const tr_torrent * tor, int pieceIndex )
    261261{
    262262    uint8_t hash[SHA_DIGEST_LENGTH];
     
    268268}
    269269
    270 static void
    271 checkFile( tr_torrent   * tor,
    272            int            fileIndex,
    273            int          * abortFlag )
    274 {
    275     int i;
    276     int nofile;
    277     struct stat sb;
    278     char path[MAX_PATH_LENGTH];
    279     const tr_file * file = &tor->info.files[fileIndex];
    280 
    281     tr_buildPath ( path, sizeof(path), tor->destination, file->name, NULL );
    282     nofile = stat( path, &sb ) || !S_ISREG( sb.st_mode );
    283 
    284     for( i=file->firstPiece; i<=file->lastPiece && i<tor->info.pieceCount && (!*abortFlag); ++i )
    285     {
    286         if( nofile )
    287         {
    288             tr_torrentSetHasPiece( tor, i, 0 );
    289         }
    290         else if( !tr_torrentIsPieceChecked( tor, i ) )
    291         {
    292             const int check = checkPiece( tor, i );
    293             tr_torrentSetHasPiece( tor, i, !check );
    294             tr_torrentSetPieceChecked( tor, i, TRUE );
    295         }
    296     }
    297 }
    298 
    299 /**
    300 ***
    301 **/
    302 
    303270int
    304271tr_ioHash( tr_torrent * tor, int pieceIndex )
    305272{
    306273    int ret;
    307     const int success = !checkPiece( tor, pieceIndex );
     274    const int success = !tr_ioTestPiece( tor, pieceIndex );
    308275
    309276    if( success )
     
    325292    return ret;
    326293}
    327 
    328 /**
    329 ***
    330 **/
    331 
    332 struct recheck_node
    333 {
    334     tr_torrent * torrent;
    335     tr_recheck_done_cb recheck_done_cb;
    336 };
    337 
    338 static void
    339 fireCheckDone( tr_torrent          * torrent,
    340                tr_recheck_done_cb    recheck_done_cb )
    341 {
    342     if( recheck_done_cb != NULL )
    343         (*recheck_done_cb)( torrent );
    344 }
    345 
    346 static struct recheck_node currentNode;
    347 
    348 static tr_list * recheckList = NULL;
    349 
    350 static tr_thread * recheckThread = NULL;
    351 
    352 static int stopCurrent = FALSE;
    353 
    354 static tr_lock* getRecheckLock( void )
    355 {
    356     static tr_lock * lock = NULL;
    357     if( lock == NULL )
    358         lock = tr_lockNew( );
    359     return lock;
    360 }
    361 
    362 static void
    363 recheckThreadFunc( void * unused UNUSED )
    364 {
    365     for( ;; )
    366     {
    367         int i;
    368         tr_torrent * tor;
    369         struct recheck_node * node;
    370 
    371         tr_lockLock( getRecheckLock( ) );
    372         stopCurrent = FALSE;
    373         node = (struct recheck_node*) recheckList ? recheckList->data : NULL;
    374         if( node == NULL ) {
    375             currentNode.torrent = NULL;
    376             break;
    377         }
    378 
    379         currentNode = *node;
    380         tor = currentNode.torrent;
    381         tr_list_remove_data( &recheckList, node );
    382         tr_free( node );
    383         tr_lockUnlock( getRecheckLock( ) );
    384 
    385         tor->recheckState = TR_RECHECK_NOW;
    386 
    387         /* remove the unchecked pieces from completion... */
    388         for( i=0; i<tor->info.pieceCount; ++i )
    389             if( !tr_torrentIsPieceChecked( tor, i ) )
    390                 tr_cpPieceRem( tor->completion, i );
    391 
    392         tr_inf( "Verifying some pieces of \"%s\"", tor->info.name );
    393         for( i=0; i<tor->info.fileCount && !stopCurrent; ++i )
    394             checkFile( tor, i, &stopCurrent );
    395 
    396         tor->recheckState = TR_RECHECK_NONE;
    397 
    398         if( !stopCurrent )
    399         {
    400             tr_fastResumeSave( tor );
    401             fireCheckDone( tor, currentNode.recheck_done_cb );
    402         }
    403     }
    404 
    405     recheckThread = NULL;
    406     tr_lockUnlock( getRecheckLock( ) );
    407 }
    408 
    409 void
    410 tr_ioRecheckAdd( tr_torrent          * tor,
    411                  tr_recheck_done_cb    recheck_done_cb )
    412 {
    413     const int uncheckedCount = tr_torrentCountUncheckedPieces( tor );
    414 
    415     if( !uncheckedCount )
    416     {
    417         /* doesn't need to be checked... */
    418         recheck_done_cb( tor );
    419     }
    420     else
    421     {
    422         struct recheck_node * node;
    423 
    424         tr_inf( "Queueing %s to verify %d local file pieces", tor->info.name, uncheckedCount );
    425 
    426         node = tr_new( struct recheck_node, 1 );
    427         node->torrent = tor;
    428         node->recheck_done_cb = recheck_done_cb;
    429 
    430         tr_lockLock( getRecheckLock( ) );
    431         tor->recheckState = recheckList ? TR_RECHECK_WAIT : TR_RECHECK_NOW;
    432         tr_list_append( &recheckList, node );
    433         if( recheckThread == NULL )
    434             recheckThread = tr_threadNew( recheckThreadFunc, NULL, "recheckThreadFunc" );
    435         tr_lockUnlock( getRecheckLock( ) );
    436     }
    437 }
    438 
    439 static int
    440 compareRecheckByTorrent( const void * va, const void * vb )
    441 {
    442     const struct recheck_node * a = va;
    443     const tr_torrent * b = vb;
    444     return a->torrent - b;
    445 }
    446 
    447 void
    448 tr_ioRecheckRemove( tr_torrent * tor )
    449 {
    450     tr_lock * lock = getRecheckLock( );
    451     tr_lockLock( lock );
    452 
    453     if( tor == currentNode.torrent )
    454     {
    455         stopCurrent = TRUE;
    456         while( stopCurrent )
    457         {
    458             tr_lockUnlock( lock );
    459             tr_wait( 100 );
    460             tr_lockLock( lock );
    461         }
    462     }
    463     else
    464     {
    465         tr_free( tr_list_remove( &recheckList, tor, compareRecheckByTorrent ) );
    466         tor->recheckState = TR_RECHECK_NONE;
    467     }
    468 
    469     tr_lockUnlock( lock );
    470 }
  • trunk/libtransmission/inout.h

    r4734 r5042  
    3333 * or TR_ERROR_IO_* otherwise.
    3434 */
    35 int tr_ioRead  ( struct tr_torrent*, int index, int begin, int len, uint8_t * );
     35int tr_ioRead  ( const struct tr_torrent  * tor,
     36                 int                        pieceIndex,
     37                 int                        offset,
     38                 int                        len,
     39                 uint8_t                  * setme );
    3640
    3741/**
     
    4044 * or TR_ERROR_IO_* otherwise.
    4145 */
    42 tr_errno tr_ioWrite ( struct tr_torrent *, int index, int begin, int len, const uint8_t * );
     46tr_errno tr_ioWrite ( struct tr_torrent  * tor,
     47                      int                  pieceIndex,
     48                      int                  offset,
     49                      int                  len,
     50                      const uint8_t      * writeme );
    4351
    44 /* hashes the specified piece and updates the completion accordingly. */
     52/**
     53 * returns true if the piece matches its metainfo's SHA1 checksum,
     54 * false otherwise.
     55 */
     56int tr_ioTestPiece( const tr_torrent*, int piece );
     57
     58
     59/**
     60 * tests the specified piece and uses the results to
     61 * update the torrent's "completion" and "blame" fields.
     62 */
    4563int tr_ioHash ( tr_torrent*, int piece );
    4664
    47 /**
    48 ***
    49 **/
    50 
    51 typedef void (*tr_recheck_done_cb)( tr_torrent * tor );
    52 
    53 void tr_ioRecheckAdd( tr_torrent          * tor,
    54                       tr_recheck_done_cb    recheck_done_cb );
    55 
    56 void tr_ioRecheckRemove( tr_torrent * tor );
    57 
    58 /**
    59 ***
    60 **/
    6165
    6266#endif
  • trunk/libtransmission/torrent.c

    r5011 r5042  
    4949#include "trevent.h"
    5050#include "utils.h"
     51#include "verify.h"
    5152
    5253/***
     
    601602    s->leftUntilDone = tr_cpLeftUntilDone( tor->completion );
    602603
    603     if( tor->recheckState == TR_RECHECK_NOW )
     604    if( tor->verifyState == TR_VERIFY_NOW )
    604605        s->status = TR_STATUS_CHECK;
    605     else if( tor->recheckState == TR_RECHECK_WAIT )
     606    else if( tor->verifyState == TR_VERIFY_WAIT )
    606607        s->status = TR_STATUS_CHECK_WAIT;
    607608    else if( !tor->isRunning )
     
    949950        tr_fastResumeLoad( tor, TR_FR_PROGRESS, NULL );
    950951        tor->isRunning = 1;
    951         tr_ioRecheckAdd( tor, checkAndStartCB );
     952        tr_verifyAdd( tor, checkAndStartCB );
    952953    }
    953954
     
    970971    tr_globalLock( tor->handle );
    971972
    972     tr_ioRecheckRemove( tor );
     973    tr_verifyRemove( tor );
    973974    tr_torrentUncheck( tor );
    974     tr_ioRecheckAdd( tor, torrentRecheckDoneCB );
     975    tr_verifyAdd( tor, torrentRecheckDoneCB );
    975976
    976977    tr_globalUnlock( tor->handle );
     
    984985
    985986    tr_torrent * tor = vtor;
    986     tr_ioRecheckRemove( tor );
     987    tr_verifyRemove( tor );
    987988    tr_peerMgrStopTorrent( tor->handle->peerMgr, tor->info.hash );
    988989    tr_trackerStop( tor->tracker );
  • trunk/libtransmission/torrent.h

    r4884 r5042  
    9292typedef enum
    9393{
    94    TR_RECHECK_NONE,
    95    TR_RECHECK_WAIT,
    96    TR_RECHECK_NOW
     94   TR_VERIFY_NONE,
     95   TR_VERIFY_WAIT,
     96   TR_VERIFY_NOW
    9797}
    98 tr_recheck_state;
     98tr_verify_state;
    9999
    100100struct tr_torrent
     
    157157    uint16_t                   maxConnectedPeers;
    158158
    159     tr_recheck_state           recheckState;
     159    tr_verify_state           verifyState;
    160160
    161161    time_t                     lastStatTime;
Note: See TracChangeset for help on using the changeset viewer.