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

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

File:
1 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
Note: See TracChangeset for help on using the changeset viewer.