Ignore:
Timestamp:
Nov 5, 2008, 5:56:06 AM (13 years ago)
Author:
charles
Message:

(libT) #849: preallocate files when possible to prevent disk fragmentation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/fdlimit.c

    r6961 r7051  
    3333#include <stdlib.h>
    3434#include <string.h>
     35#ifdef SYS_DARWIN
     36#include <fcntl.h>
     37#endif
    3538
    3639#include <sys/types.h>
     
    9699****
    97100***/
     101
     102static int
     103preallocateFile( int fd UNUSED, uint64_t length UNUSED )
     104{
     105#ifdef HAVE_FALLOCATE
     106
     107    return fallocate( fd, 0, offset, length );
     108
     109#elif defined(HAVE_POSIX_FALLOCATE)
     110
     111    return posix_fallocate( fd, 0, length );
     112
     113#elif defined(SYS_DARWIN)
     114
     115    fstore_t fst;
     116    fst.fst_flags = F_ALLOCATECONTIG;
     117    fst.fst_posmode = F_PEOFPOSMODE;
     118    fst.fst_offset = 0;
     119    fst.fst_length = length;
     120    fst.fst_bytesalloc = 0;
     121    return fcntl( fd, F_PREALLOCATE, &fst );
     122
     123#else
     124
     125    #warning no known method to preallocate files on this platform
     126    return -1;
     127
     128#endif
     129}
    98130
    99131/**
     
    106138            const char * folder,
    107139            const char * torrentFile,
    108             int          write )
     140            int          doWrite,
     141            int          doPreallocate,
     142            uint64_t     desiredFileSize )
    109143{
    110144    struct tr_openfile * file = &gFd->open[i];
     
    112146    char               * filename;
    113147    struct stat          sb;
     148    int                  alreadyExisted;
    114149
    115150    /* confirm the parent folder exists */
     
    119154    /* create subfolders, if any */
    120155    filename = tr_buildPath( folder, torrentFile, NULL );
    121     if( write )
     156    if( doWrite )
    122157    {
    123158        char * tmp = tr_dirname( filename );
     
    130165    }
    131166
     167    alreadyExisted = !stat( filename, &sb ) && S_ISREG( sb.st_mode );
     168   
    132169    /* open the file */
    133     flags = write ? ( O_RDWR | O_CREAT ) : O_RDONLY;
     170    flags = doWrite ? ( O_RDWR | O_CREAT ) : O_RDONLY;
    134171#ifdef O_LARGEFILE
    135172    flags |= O_LARGEFILE;
     
    148185    }
    149186
     187    if( ( file->fd >= 0 ) && !alreadyExisted && doPreallocate )
     188        if( !preallocateFile( file->fd, desiredFileSize ) )
     189            tr_inf( _( "Preallocated file \"%s\"" ), filename );
     190       
    150191    tr_free( filename );
    151192    return 0;
     
    182223tr_fdFileCheckout( const char * folder,
    183224                   const char * torrentFile,
    184                    int          write )
     225                   int          doWrite,
     226                   int          doPreallocate,
     227                   uint64_t     desiredFileSize )
    185228{
    186229    int                  i, winner = -1;
     
    190233    assert( folder && *folder );
    191234    assert( torrentFile && *torrentFile );
    192     assert( write == 0 || write == 1 );
     235    assert( doWrite == 0 || doWrite == 1 );
    193236
    194237    filename = tr_buildPath( folder, torrentFile, NULL );
    195238    dbgmsg( "looking for file '%s', writable %c", filename,
    196             write ? 'y' : 'n' );
     239            doWrite ? 'y' : 'n' );
    197240
    198241    tr_lockLock( gFd->lock );
     
    219262        }
    220263
    221         if( write && !o->isWritable )
     264        if( doWrite && !o->isWritable )
    222265        {
    223266            dbgmsg(
     
    281324    if( !fileIsOpen( o ) )
    282325    {
    283         const int err = TrOpenFile( winner, folder, torrentFile, write );
     326        const int err = TrOpenFile( winner, folder, torrentFile, doWrite, doPreallocate, desiredFileSize );
    284327        if( err ) {
    285328            tr_lockUnlock( gFd->lock );
     
    289332        }
    290333
    291         dbgmsg( "opened '%s' in slot %d, write %c", filename, winner,
    292                 write ? 'y' : 'n' );
     334        dbgmsg( "opened '%s' in slot %d, doWrite %c", filename, winner,
     335                doWrite ? 'y' : 'n' );
    293336        tr_strlcpy( o->filename, filename, sizeof( o->filename ) );
    294         o->isWritable = write;
     337        o->isWritable = doWrite;
    295338    }
    296339
Note: See TracChangeset for help on using the changeset viewer.