Ticket #2551: prefetch.patch

File prefetch.patch, 4.9 KB (added by jch, 11 years ago)
  • libtransmission/peer-msgs.c

     
    12541301    else
    12551302        allow = TRUE;
    12561303
    1257     if( allow )
     1304    if( allow ) {
     1305        tr_ioPrefetch( msgs->torrent, req->index, req->offset, req->length );
    12581306        reqListAppend( &msgs->peerAskedFor, req );
    1259     else if( fext )
     1307    } else if( fext )
    12601308        protocolSendReject( msgs, req );
    12611309}
    12621310
  • libtransmission/fdlimit.c

     
    345345    if( doWrite && !alreadyExisted && ( preallocationMode == TR_PREALLOCATE_SPARSE ) )
    346346        preallocateFileSparse( file->fd, desiredFileSize );
    347347
    348 #ifdef HAVE_POSIX_FADVISE
    349     /* this doubles the OS level readahead buffer, which in practice
    350      * turns out to be a good thing, because many (most?) clients request
    351      * chunks of blocks in order.
    352      * It's okay for this to fail silently, so don't let it affect errno */
    353     {
    354         const int err = errno;
    355         posix_fadvise( file->fd, 0, 0, POSIX_FADV_SEQUENTIAL );
    356         errno = err;
    357     }
    358 #endif
     348    /* We used to fadvise(SEQUENTIAL) at this point.  This is no longer
     349       needed, since we now explicitly prefetch as soon as the peer queues
     350       a request. */
    359351
    360352    return 0;
    361353}
  • libtransmission/inout.c

     
    2222#include <sys/types.h>
    2323#include <sys/stat.h>
    2424#include <unistd.h>
     25#define _XOPEN_SOURCE 600
     26#include <fcntl.h>
    2527
    2628#include <openssl/sha.h>
    2729
     
    5052 #define write _write
    5153#endif
    5254
    53 enum { TR_IO_READ, TR_IO_WRITE };
     55enum { TR_IO_READ, TR_IO_WRITE, TR_IO_PREFETCH };
    5456
    5557int64_t
    5658tr_lseek( int fd, int64_t offset, int whence )
     
    7880    const tr_file * file = &info->files[fileIndex];
    7981
    8082    typedef size_t ( *iofunc )( int, void *, size_t );
    81     iofunc          func = ioMode == TR_IO_READ ? (iofunc)read : (iofunc)write;
    8283    int             fd = -1;
    8384    int             err = 0;
    8485    const tr_bool doWrite = ioMode == TR_IO_WRITE;
     
    142143        tr_free( subpath );
    143144    }
    144145
    145     if( !err )
    146     {
    147         if( tr_lseek( fd, (int64_t)fileOffset, SEEK_SET ) == -1 )
    148         {
    149             err = errno;
    150             tr_torerr( tor, "tr_lseek failed for \"%s\": %s", file->name, tr_strerror( err ) );
     146    if( !err ) {
     147        if( ioMode == TR_IO_READ || ioMode == TR_IO_WRITE ) {
     148            iofunc func = ioMode == TR_IO_READ ? (iofunc)read : (iofunc)write;
     149
     150            if( tr_lseek( fd, (int64_t)fileOffset, SEEK_SET ) == -1 ) {
     151                err = errno;
     152                tr_torerr( tor, "tr_lseek failed for \"%s\": %s",
     153                           file->name, tr_strerror( err ) );
     154            } else if( func( fd, buf, buflen ) != buflen ) {
     155                err = errno;
     156                tr_torerr( tor, "read/write failed for \"%s\": %s",
     157                           file->name, tr_strerror( err ) );
     158            }
     159        } else if( ioMode == TR_IO_PREFETCH ) {
     160            int rc;
     161            rc = posix_fadvise( fd, fileOffset, buflen, POSIX_FADV_WILLNEED );
     162            if( rc < 0 ) {
     163                tr_torerr( tor, "prefetch failed for \"%s\": %s",
     164                           file->name, tr_strerror( errno ) );
     165                /* But don't set err -- this is advisory. */
     166            }
    151167        }
    152         else if( func( fd, buf, buflen ) != buflen )
    153         {
    154             err = errno;
    155             tr_torerr( tor, "read/write failed for \"%s\": %s", file->name, tr_strerror( err ) );
    156         }
    157168    }
    158169
    159170    return err;
     
    258269                             len );
    259270}
    260271
     272int
     273tr_ioPrefetch( tr_torrent       * tor,
     274               tr_piece_index_t   pieceIndex,
     275               uint32_t           begin,
     276               uint32_t           len)
     277{
     278    return readOrWritePiece( tor, TR_IO_PREFETCH, pieceIndex, begin,
     279                             NULL, len );
     280}
     281
    261282/****
    262283*****
    263284****/
  • libtransmission/inout.h

     
    4545                const uint8_t      * writeme );
    4646
    4747/**
     48 * Prefetches the block specified by the piece index, offset, and length.
     49 * @return 0 on success, or an errno value on failure.
     50 */
     51int tr_ioPrefetch( struct tr_torrent  * tor,
     52                   tr_piece_index_t     pieceIndex,
     53                   uint32_t             offset,
     54                   uint32_t             len);
     55
     56/**
    4857 * @brief Test to see if the piece matches its metainfo's SHA1 checksum.
    4958 *
    5059 * @param optionalBuffer if calling tr_ioTestPiece() repeatedly, you can