Changeset 7142


Ignore:
Timestamp:
Nov 23, 2008, 5:27:39 PM (14 years ago)
Author:
charles
Message:

(1.4x libT) backport file preallocation improvements #1482 and #1486

Location:
branches/1.4x/libtransmission
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/1.4x/libtransmission/fdlimit.c

    r7103 r7142  
    2323 *****************************************************************************/
    2424
     25#ifndef WIN32
     26 #define HAVE_GETRLIMIT
     27#endif
     28
    2529#include <assert.h>
    2630#include <errno.h>
     
    3943#include <sys/types.h>
    4044#include <sys/stat.h>
     45#ifdef HAVE_GETRLIMIT
     46 #include <sys/time.h> /* getrlimit */
     47 #include <sys/resource.h> /* getrlimit */
     48#endif
    4149#include <unistd.h>
    4250#include <fcntl.h> /* O_LARGEFILE */
     
    96104***/
    97105
     106#ifndef O_LARGEFILE
     107#define O_LARGEFILE 0
     108#endif
     109
    98110static int
    99 preallocateFile( int fd UNUSED, uint64_t length UNUSED )
    100 {
    101 #ifdef HAVE_FALLOCATE
    102 
    103     return fallocate( fd, FALLOC_FL_KEEP_SIZE, 0, length );
    104 
    105 #elif defined(HAVE_POSIX_FALLOCATE)
    106 
    107     return posix_fallocate( fd, 0, length );
    108 
    109 #elif defined(SYS_DARWIN)
    110 
    111     fstore_t fst;
    112     fst.fst_flags = F_ALLOCATECONTIG;
    113     fst.fst_posmode = F_PEOFPOSMODE;
    114     fst.fst_offset = 0;
    115     fst.fst_length = length;
    116     fst.fst_bytesalloc = 0;
    117     return fcntl( fd, F_PREALLOCATE, &fst );
     111preallocateFile( const char * filename, uint64_t length )
     112{
     113    int success = 0;
     114
     115#ifdef WIN32
     116
     117    HANDLE hFile = CreateFile( filename, GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0 );
     118    if( hFile != INVALID_HANDLE_VALUE )
     119    {
     120        LARGE_INTEGER li;
     121        li.QuadPart = length;
     122        success = SetFilePointerEx( hFile, li, NULL, FILE_BEGIN ) && SetEndOfFile( hFile );
     123        CloseHandle( hFile );
     124    }
    118125
    119126#else
    120127
    121     #warning no known method to preallocate files on this platform
    122     return -1;
    123 
    124 #endif
     128    int flags = O_RDWR | O_CREAT | O_LARGEFILE;
     129    int fd = open( filename, flags, 0666 );
     130    if( fd >= 0 )
     131    {
     132       
     133# ifdef HAVE_FALLOCATE
     134
     135        success = !fallocate( fd, FALLOC_FL_KEEP_SIZE, 0, length );
     136
     137# elif defined(HAVE_POSIX_FALLOCATE)
     138
     139        success = !posix_fallocate( fd, 0, length );
     140
     141# elif defined(SYS_DARWIN)
     142
     143        fstore_t fst;
     144        fst.fst_flags = F_ALLOCATECONTIG;
     145        fst.fst_posmode = F_PEOFPOSMODE;
     146        fst.fst_offset = 0;
     147        fst.fst_length = length;
     148        fst.fst_bytesalloc = 0;
     149        success = !fcntl( fd, F_PREALLOCATE, &fst );
     150
     151# else
     152
     153        #warning no known method to preallocate files on this platform
     154        success = 0;
     155
     156# endif
     157
     158        close( fd );
     159    }
     160
     161#endif
     162
     163    return success;
    125164}
    126165
     
    162201
    163202    alreadyExisted = !stat( filename, &sb ) && S_ISREG( sb.st_mode );
     203
     204    if( doWrite && !alreadyExisted && doPreallocate )
     205        if( preallocateFile( filename, desiredFileSize ) )
     206            tr_inf( _( "Preallocated file \"%s\"" ), filename );
    164207   
    165208    /* open the file */
     
    181224    }
    182225
    183     if( ( file->fd >= 0 ) && !alreadyExisted && doPreallocate )
    184         if( !preallocateFile( file->fd, desiredFileSize ) )
    185             tr_inf( _( "Preallocated file \"%s\"" ), filename );
    186        
    187226    tr_free( filename );
    188227    return 0;
     
    501540    gFd = tr_new0( struct tr_fd_s, 1 );
    502541    gFd->lock = tr_lockNew( );
     542
     543#ifdef HAVE_GETRLIMIT
     544    {
     545        struct rlimit rlim;
     546        getrlimit( RLIMIT_NOFILE, &rlim );
     547        rlim.rlim_cur = MIN( rlim.rlim_max,
     548                            (rlim_t)( globalPeerLimit + NOFILE_BUFFER ) );
     549        setrlimit( RLIMIT_NOFILE, &rlim );
     550        gFd->socketMax = rlim.rlim_cur - NOFILE_BUFFER;
     551        tr_dbg( "setrlimit( RLIMIT_NOFILE, %d )", (int)rlim.rlim_cur );
     552    }
     553#else
    503554    gFd->socketMax = globalPeerLimit;
     555#endif
    504556    tr_dbg( "%d usable file descriptors", globalPeerLimit );
    505557
  • branches/1.4x/libtransmission/inout.c

    r7061 r7142  
    3636
    3737#ifdef WIN32
    38  #define lseek _lseeki64
    3938 #if defined(read)
    40     #undef read
     39  #undef read
    4140 #endif
    4241 #define read  _read
    4342 
    4443 #if defined(write)
    45     #undef write
     44  #undef write
    4645 #endif
    4746 #define write _write
     
    4948
    5049enum { TR_IO_READ, TR_IO_WRITE };
     50
     51static int64_t
     52tr_lseek( int fd, int64_t offset, int whence )
     53{
     54#if defined(_LARGEFILE_SOURCE)
     55    return lseek64( fd, (off64_t)offset, whence );
     56#elif defined(WIN32)
     57    return _lseeki64( fd, offset, whence );
     58#else
     59    return lseek( fd, (off_t)offset, whence );
     60#endif
     61}
    5162
    5263/* returns 0 on success, or an errno on failure */
     
    8697    else if( ( fd = tr_fdFileCheckout ( tor->downloadDir, file->name, ioMode == TR_IO_WRITE, !file->dnd, file->length ) ) < 0 )
    8798        err = errno;
    88     else if( lseek( fd, (off_t)fileOffset, SEEK_SET ) == ( (off_t)-1 ) )
     99    else if( tr_lseek( fd, (int64_t)fileOffset, SEEK_SET ) == -1 )
    89100        err = errno;
    90101    else if( func( fd, buf, buflen ) != buflen )
     
    118129                       tr_piece_index_t   pieceIndex,
    119130                       uint32_t           pieceOffset,
    120                        tr_file_index_t *  fileIndex,
    121                        uint64_t *         fileOffset )
    122 {
    123     const uint64_t  offset = tr_pieceOffset( tor, pieceIndex, pieceOffset,
    124                                              0 );
     131                       tr_file_index_t  * fileIndex,
     132                       uint64_t         * fileOffset )
     133{
     134    const uint64_t  offset = tr_pieceOffset( tor, pieceIndex, pieceOffset, 0 );
    125135    const tr_file * file;
    126136
     
    136146    assert( tor->info.files[*fileIndex].offset + *fileOffset == offset );
    137147}
    138 
    139 #ifdef WIN32
    140 /* return 0 on success, or an errno on failure */
    141 static int
    142 ensureMinimumFileSize( const tr_torrent * tor,
    143                        tr_file_index_t    fileIndex,
    144                        uint64_t           minBytes )
    145 {
    146     int             fd;
    147     int             err;
    148     struct stat     sb;
    149     const tr_file * file = &tor->info.files[fileIndex];
    150 
    151     assert( 0 <= fileIndex && fileIndex < tor->info.fileCount );
    152     assert( minBytes <= file->length );
    153 
    154     fd = tr_fdFileCheckout( tor->downloadDir,
    155                             file->name, TRUE, !file->dnd, file->length );
    156 
    157     if( fd < 0 ) /* bad fd */
    158         err = errno;
    159     else if( fstat ( fd, &sb ) ) /* how big is the file? */
    160         err = errno;
    161     else if( sb.st_size >= (off_t)minBytes ) /* already big enough */
    162         err = 0;
    163     else if( !ftruncate( fd, minBytes ) )  /* grow it */
    164         err = 0;
    165     else /* couldn't grow it */
    166         err = errno;
    167 
    168     if( fd >= 0 )
    169         tr_fdFileReturn( fd );
    170 
    171     return err;
    172 }
    173 
    174 #endif
    175148
    176149/* returns 0 on success, or an errno on failure */
     
    202175                                             file->length - fileOffset );
    203176
    204 #ifdef WIN32
    205         if( ioMode == TR_IO_WRITE )
    206             err = ensureMinimumFileSize( tor, fileIndex,
    207                                          fileOffset + bytesThisPass );
    208         if( !err )
    209 #endif
    210177        err = readOrWriteBytes( tor, ioMode,
    211178                                fileIndex, fileOffset, buf, bytesThisPass );
Note: See TracChangeset for help on using the changeset viewer.