Changeset 3665


Ignore:
Timestamp:
Oct 31, 2007, 6:10:54 PM (15 years ago)
Author:
charles
Message:

"corruption" fix part 3: cleanup. remove unneeded possible points of failure.

Location:
branches/0.9x
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/0.9x/configure.ac

    r3637 r3665  
    3030AC_HEADER_TIME
    3131AC_CHECK_FUNCS([lrintf strlcpy strlcat daemon dirname basename])
     32AC_CHECK_SIZEOF([void*])
    3233AC_PROG_INSTALL
    3334AC_PROG_MAKE_SET
  • branches/0.9x/libtransmission/fdlimit.c

    r3649 r3665  
    2525#include <assert.h>
    2626#include <errno.h>
     27#include <inttypes.h>
    2728#include <stdio.h>
    2829#include <stdlib.h>
     
    4344#include "transmission.h"
    4445#include "trcompat.h"
     46#include "list.h"
    4547#include "net.h"
    4648#include "platform.h"
    4749#include "utils.h"
     50
     51#if SIZEOF_VOIDP==8
     52#define TR_UINT_TO_PTR(i) (void*)((uint64_t)i)
     53#else
     54#define TR_UINT_TO_PTR(i) ((void*)((uint32_t)i))
     55#endif
    4856
    4957/**
     
    8290enum
    8391{
    84     TR_MAX_OPEN_FILES = 16, /* That is, real files, not sockets */
     92    TR_MAX_OPEN_FILES = 16, /* real files, not sockets */
    8593
    8694    TR_RESERVED_FDS   = 16 /* sockets reserved for tracker connections */
     
    92100    unsigned int  isWritable : 1;
    93101    char          filename[MAX_PATH_LENGTH];
    94     int           file;
     102    int           fd;
    95103    uint64_t      date;
    96104};
     
    118126{
    119127    struct tr_openfile * file = &gFd->open[i];
    120     struct stat sb;
    121128    char * dir;
    122129    int flags;
     
    131138    }
    132139
    133     /* Make sure the parent folder exists */
    134     if( stat( dir, &sb ) || !S_ISDIR( sb.st_mode ) ) {
    135         free( dir );
    136         return TR_ERROR_IO_PARENT;
    137     }
    138 
    139     errno = 0;
    140     flags = 0;
     140    /* open the file */
     141    flags = write ? (O_RDWR | O_CREAT) : O_RDONLY;
    141142#ifdef WIN32
    142143    flags |= O_BINARY;
    143144#endif
    144     flags |= write ? (O_RDWR | O_CREAT) : O_RDONLY;
    145     file->file = open( filename, flags, 0666 );
     145    errno = 0;
     146    file->fd = open( filename, flags, 0600 );
    146147    free( dir );
    147     if( write && ( file->file < 0 ) )
    148     {
    149         const int ret = tr_ioErrorFromErrno();
    150         if( errno )
     148    if( file->fd < 0 ) {
     149        if( errno ) {
    151150            tr_err( "Couldn't open '%s': %s", filename, strerror(errno) );
    152         else
     151            return tr_ioErrorFromErrno();
     152        } else {
    153153            tr_err( "Couldn't open '%s'", filename );
    154         return ret;
     154            return TR_ERROR_IO_OTHER;
     155        }
    155156    }
    156157
     
    161162fileIsOpen( const struct tr_openfile * o )
    162163{
    163     return o->file >= 0;
     164    return o->fd >= 0;
    164165}
    165166
     
    167168TrCloseFile( int i )
    168169{
    169     struct tr_openfile * file = &gFd->open[i];
     170    struct tr_openfile * o = &gFd->open[i];
    170171
    171172    assert( i >= 0 );
    172173    assert( i < TR_MAX_OPEN_FILES );
    173     assert( fileIsOpen( file ) );
    174 
    175     dbgmsg( "closing %s in slot %d writable %c",
    176             file->filename, i, file->isWritable?'y':'n' );
    177     close( file->file );
    178     file->file = -1;
    179     file->isCheckedOut = 0;
     174    assert( fileIsOpen( o ) );
     175
     176    dbgmsg( "closing slot #%d, %s", i, o->filename );
     177    close( o->fd );
     178    o->fd = -1;
     179    o->isCheckedOut = 0;
    180180    tr_condSignal( gFd->cond );
    181181}
     
    192192    int i, winner;
    193193    struct tr_openfile * o;
     194
     195    assert( filename && *filename );
     196    assert( write==0 || write==1 );
    194197
    195198    dbgmsg( "looking for file '%s', writable %c", filename, write?'y':'n' );
     
    211214            dbgmsg( "found it!  it's open, but checked out.  waiting..." );
    212215            tr_condWait( gFd->cond, gFd->lock );
    213             i = -1;
     216            i = -1; /* reloop */
    214217            continue;
    215218        }
     
    218221            dbgmsg( "found it!  it's open and available, but isn't writable. closing..." );
    219222            TrCloseFile( i );
    220             continue;
     223            break;
    221224        }
    222225
     
    243246            }
    244247
    245             if( o->date < date ) {
     248            if( date > o->date ) {
     249                date = o->date;
    246250                winner = i;
    247                 date = o->date;
    248251            }
    249252        }
     
    272275
    273276        dbgmsg( "opened '%s' in slot %d, write %c", filename, winner, write?'y':'n' );
    274         strlcpy( gFd->open[winner].filename, filename, MAX_PATH_LENGTH );
    275         gFd->open[winner].isWritable = write;
     277        strlcpy( o->filename, filename, sizeof( o->filename ) );
     278        o->isWritable = write;
    276279    }
    277280
    278281    dbgmsg( "checking out '%s' in slot %d", filename, winner );
    279     gFd->open[winner].isCheckedOut = 1;
    280     gFd->open[winner].date = tr_date();
     282    o->isCheckedOut = 1;
     283    o->date = tr_date();
    281284    tr_lockUnlock( gFd->lock );
    282     return gFd->open[winner].file;
     285    return o->fd;
    283286}
    284287
     
    291294    for( i=0; i<TR_MAX_OPEN_FILES; ++i ) {
    292295        struct tr_openfile * o = &gFd->open[i];
    293         if( o->file == file ) {
     296        if( o->fd == file ) {
    294297            dbgmsg( "releasing file '%s' in slot #%d", o->filename, i );
    295298            if( o->isWritable )
    296                 fsync( o->file ); /* fflush */
     299                fsync( o->fd ); /* fflush */
    297300            o->isCheckedOut = 0;
    298301            break;
     
    310313***/
    311314
    312 struct tr_socket
    313 {
    314     int socket;
    315     int priority;
    316 };
    317 
    318 /* Remember the priority of every socket we open, so that we can keep
    319  * track of how many reserved file descriptors we are using */
    320 static struct tr_socket * gSockets = NULL;
    321 static int gSocketsSize = 0;
    322 static int gSocketsCount = 0;
     315static tr_list * reservedSockets = NULL;
    323316
    324317static void
    325 SocketSetPriority( int s, int priority )
    326 {
    327     if( gSocketsSize <= gSocketsCount ) {
    328         gSocketsSize += 64;
    329         gSockets = tr_renew( struct tr_socket, gSockets, gSocketsSize );
    330     }
    331 
    332     gSockets[gSocketsCount].socket = s;
    333     gSockets[gSocketsCount].priority = priority;
    334     ++gSocketsCount;
     318setSocketPriority( int fd, int isReserved )
     319{
     320    if( isReserved )
     321        tr_list_append( &reservedSockets, TR_UINT_TO_PTR(fd) );
    335322}
    336323
    337324static int
    338 SocketGetPriority( int s )
    339 {
    340     int i, ret;
    341 
    342     for( i=0; i<gSocketsCount; ++i )
    343         if( gSockets[i].socket == s )
    344             break;
    345 
    346     if( i >= gSocketsCount ) {
    347         tr_err( "could not find that socket (%d)!", s );
    348         return -1;
    349     }
    350 
    351     ret = gSockets[i].priority;
    352     gSocketsCount--;
    353     memmove( &gSockets[i], &gSockets[i+1],
    354             ( gSocketsCount - i ) * sizeof( struct tr_socket ) );
    355     return ret;
     325socketWasReserved( int fd )
     326{
     327    return tr_list_remove_data( &reservedSockets, TR_UINT_TO_PTR(fd) ) != NULL;
    356328}
    357329
     
    360332{
    361333    int s = -1;
    362 
    363334    tr_lockLock( gFd->lock );
    364335
     
    367338
    368339    if( priority || ( gFd->normal < gFd->normalMax ) )
    369        if( ( s = socket( AF_INET, type, 0 ) ) < 0 )
    370            tr_err( "Couldn't create socket (%s)", strerror( sockerrno ) );
     340        if( ( s = socket( AF_INET, type, 0 ) ) < 0 )
     341            tr_err( "Couldn't create socket (%s)", strerror( sockerrno ) );
    371342
    372343    if( s > -1 )
    373344    {
    374         SocketSetPriority( s, priority );
     345        setSocketPriority( s, priority );
     346
    375347        if( priority )
    376             gFd->reserved++;
     348            ++gFd->reserved;
    377349        else
    378             gFd->normal++;
    379     }
     350            ++gFd->normal;
     351    }
     352
     353    assert( gFd->reserved >= 0 );
     354    assert( gFd->normal >= 0 );
     355
    380356    tr_lockUnlock( gFd->lock );
    381 
    382357    return s;
    383358}
     
    387362{
    388363    int s = -1;
    389     unsigned len;
     364    unsigned int len;
    390365    struct sockaddr_in sock;
    391366
     
    401376    if( s > -1 )
    402377    {
    403         SocketSetPriority( s, 0 );
     378        setSocketPriority( s, 0 );
    404379        *addr = sock.sin_addr;
    405380        *port = sock.sin_port;
     
    424399tr_fdSocketClose( int s )
    425400{
    426     if( s >= 0 )
    427     {
    428         tr_lockLock( gFd->lock );
     401    tr_lockLock( gFd->lock );
     402
     403    if( s >= 0 ) {
    429404        socketClose( s );
    430         if( SocketGetPriority( s ) )
    431             gFd->reserved--;
     405        if( socketWasReserved( s ) )
     406            --gFd->reserved;
    432407        else
    433             gFd->normal--;
    434         tr_lockUnlock( gFd->lock );
    435     }
     408            --gFd->normal;
     409    }
     410
     411    assert( gFd->reserved >= 0 );
     412    assert( gFd->normal >= 0 );
     413
     414    tr_lockUnlock( gFd->lock );
    436415}
    437416
     
    465444
    466445    for( i=0; i<TR_MAX_OPEN_FILES; ++i )
    467         gFd->open[i].file = -1;
     446        gFd->open[i].fd = -1;
    468447         
    469448}
     
    481460    tr_condFree( gFd->cond );
    482461
    483     tr_free( gSockets );
     462    tr_list_free( &reservedSockets, NULL );
    484463    tr_free( gFd );
    485464}
  • branches/0.9x/libtransmission/inout.c

    r3662 r3665  
    4747
    4848static int
    49 readOrWriteBytes ( const tr_torrent    * tor,
    50                    int                   ioMode,
    51                    int                   fileIndex,
    52                    uint64_t              fileOffset,
    53                    void                * buf,
    54                    size_t                buflen )
     49readOrWriteBytes( const tr_torrent  * tor,
     50                  int                 ioMode,
     51                  int                 fileIndex,
     52                  uint64_t            fileOffset,
     53                  void              * buf,
     54                  size_t              buflen )
    5555{
    5656    const tr_info * info = &tor->info;
     
    7171    if( !file->length )
    7272        return 0;
    73     else if ((ioMode==TR_IO_READ) && stat( path, &sb ) ) /* fast check to make sure file exists */
     73    else if ((ioMode==TR_IO_READ) && stat( path, &sb ) ) /* does file exist? */
    7474        ret = tr_ioErrorFromErrno ();
    7575    else if ((fd = tr_fdFileOpen ( path, ioMode==TR_IO_WRITE )) < 0)
     
    8989
    9090static void
    91 findFileLocation ( const tr_torrent * tor,
    92                    int                  pieceIndex,
    93                    int                  pieceOffset,
    94                    int                * fileIndex,
    95                    uint64_t           * fileOffset )
     91findFileLocation( const tr_torrent * tor,
     92                  int                  pieceIndex,
     93                  int                  pieceOffset,
     94                  int                * fileIndex,
     95                  uint64_t           * fileOffset )
    9696{
    9797    const tr_info * info = &tor->info;
     
    117117#ifdef WIN32
    118118static int
    119 ensureMinimumFileSize ( const tr_torrent  * tor,
    120                         int                 fileIndex,
    121                         uint64_t            minSize ) /* in bytes */
     119ensureMinimumFileSize( const tr_torrent  * tor,
     120                       int                 fileIndex,
     121                       uint64_t            minBytes )
    122122{
    123123    int fd;
     
    128128
    129129    assert ( 0<=fileIndex && fileIndex<tor->info.fileCount );
    130     assert ( minSize <= file->length );
     130    assert ( minBytes <= file->length );
    131131
    132132    tr_buildPath ( path, sizeof(path), tor->destination, file->name, NULL );
     
    137137    else if (fstat (fd, &sb) ) /* how big is the file? */
    138138        ret = tr_ioErrorFromErrno ();
    139     else if (sb.st_size >= (off_t)minSize) /* already big enough */
     139    else if (sb.st_size >= (off_t)minBytes) /* already big enough */
    140140        ret = TR_OK;
    141     else if (!ftruncate( fd, minSize )) /* grow it */
     141    else if (!ftruncate( fd, minBytes )) /* grow it */
    142142        ret = TR_OK;
    143143    else /* couldn't grow it */
     
    152152
    153153static int
    154 readOrWritePiece ( tr_torrent       * tor,
    155                    int                ioMode,
    156                    int                pieceIndex,
    157                    int                pieceOffset,
    158                    uint8_t          * buf,
    159                    size_t             buflen )
     154readOrWritePiece( tr_torrent  * tor,
     155                  int           ioMode,
     156                  int           pieceIndex,
     157                  int           pieceOffset,
     158                  uint8_t     * buf,
     159                  size_t        buflen )
    160160{
    161161    int ret = 0;
     
    194194tr_ioRead( tr_torrent * tor, int pieceIndex, int begin, int len, uint8_t * buf )
    195195{
    196     return readOrWritePiece ( tor, TR_IO_READ, pieceIndex, begin, buf, len );
     196    return readOrWritePiece( tor, TR_IO_READ, pieceIndex, begin, buf, len );
    197197}
    198198
     
    200200tr_ioWrite( tr_torrent * tor, int pieceIndex, int begin, int len, uint8_t * buf )
    201201{
    202     return readOrWritePiece ( tor, TR_IO_WRITE, pieceIndex, begin, buf, len );
     202    return readOrWritePiece( tor, TR_IO_WRITE, pieceIndex, begin, buf, len );
    203203}
    204204
     
    208208
    209209static int
    210 tr_ioRecalculateHash( tr_torrent    * tor,
    211                       int             pieceIndex,
    212                       uint8_t       * setme )
     210tr_ioRecalculateHash( tr_torrent  * tor,
     211                      int           pieceIndex,
     212                      uint8_t     * setme )
    213213{
    214214    int n;
     
    237237{
    238238    uint8_t hash[SHA_DIGEST_LENGTH];
    239     int ret = tr_ioRecalculateHash( tor, pieceIndex, hash )
    240            || memcmp( hash, tor->info.pieces[pieceIndex].hash, SHA_DIGEST_LENGTH );
     239    const int ret = tr_ioRecalculateHash( tor, pieceIndex, hash )
     240        || memcmp( hash, tor->info.pieces[pieceIndex].hash, SHA_DIGEST_LENGTH );
    241241    tr_dbg ("torrent [%s] piece %d hash check: %s",
    242242            tor->info.name, pieceIndex, (ret?"FAILED":"OK"));
     
    267267    }
    268268
    269     tr_peerMgrSetBlame( tor->handle->peerMgr, tor->info.hash, pieceIndex, success );
     269    tr_peerMgrSetBlame( tor->handle->peerMgr, tor->info.hash,
     270                        pieceIndex, success );
    270271
    271272    return ret;
     
    290291}
    291292
    292 struct recheck_node currentNode;
     293static struct recheck_node currentNode;
    293294
    294295static tr_list * recheckList = NULL;
     
    397398compareRecheckByTorrent( const void * va, const void * vb )
    398399{
    399     const struct recheck_node * a = ( const struct recheck_node * ) va;
    400     const struct recheck_node * b = ( const struct recheck_node * ) vb;
    401     return a->torrent - b->torrent;
     400    const struct recheck_node * a = va;
     401    const tr_torrent * b = vb;
     402    return a->torrent - b;
    402403}
    403404
     
    420421    else
    421422    {
    422         struct recheck_node tmp;
    423         struct recheck_node * node;
    424         tmp.torrent = tor;
    425         node = tr_list_remove( &recheckList,
    426                                &tmp,
    427                                compareRecheckByTorrent );
    428         tr_free( node );
     423        tr_free( tr_list_remove( &recheckList, tor, compareRecheckByTorrent ) );
    429424        tor->recheckState = TR_RECHECK_NONE;
    430425    }
  • branches/0.9x/libtransmission/ipcparse.c

    r3486 r3665  
    781781                    tr_bencInitStr( item, "assert", -1, 1 );
    782782                }
    783                 else if( TR_ERROR_ISSET( TR_ERROR_IO_PARENT, error ) )
    784                 {
    785                     tr_bencInitStr( item, "io-parent", -1, 1 );
    786                 }
    787783                else if( TR_ERROR_ISSET( TR_ERROR_IO_PERMISSIONS, error ) )
    788784                {
  • branches/0.9x/libtransmission/transmission.h

    r3573 r3665  
    8181/* I/O errors */
    8282#define TR_ERROR_IO_MASK            0x000000FF
    83 #define TR_ERROR_IO_PARENT          0x80000001
    8483#define TR_ERROR_IO_PERMISSIONS     0x80000002
    8584#define TR_ERROR_IO_SPACE           0x80000004
  • branches/0.9x/libtransmission/utils.c

    r3662 r3665  
    648648        case TR_ERROR_ASSERT:
    649649            return "Assert error";
    650         case TR_ERROR_IO_PARENT:
    651             return "Download folder does not exist";
    652650        case TR_ERROR_IO_PERMISSIONS:
    653651            return "Insufficient permissions";
Note: See TracChangeset for help on using the changeset viewer.