mirror of
https://github.com/transmission/transmission
synced 2024-12-23 08:13:27 +00:00
(libT) get file preallocation working on Windows by copying how fsutil does it. (source: http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/4dabec8e-2909-40b3-b398-66bd4c587b9b/)
This commit is contained in:
parent
3548135711
commit
10714dc224
1 changed files with 54 additions and 22 deletions
|
@ -95,33 +95,65 @@ static struct tr_fd_s * gFd = NULL;
|
|||
****
|
||||
***/
|
||||
|
||||
#ifndef O_LARGEFILE
|
||||
#define O_LARGEFILE 0
|
||||
#endif
|
||||
|
||||
static int
|
||||
preallocateFile( int fd UNUSED, uint64_t length UNUSED )
|
||||
preallocateFile( const char * filename, uint64_t length )
|
||||
{
|
||||
#ifdef HAVE_FALLOCATE
|
||||
int success = 0;
|
||||
|
||||
return fallocate( fd, FALLOC_FL_KEEP_SIZE, 0, length );
|
||||
#ifdef WIN32
|
||||
|
||||
#elif defined(HAVE_POSIX_FALLOCATE)
|
||||
|
||||
return posix_fallocate( fd, 0, length );
|
||||
|
||||
#elif defined(SYS_DARWIN)
|
||||
|
||||
fstore_t fst;
|
||||
fst.fst_flags = F_ALLOCATECONTIG;
|
||||
fst.fst_posmode = F_PEOFPOSMODE;
|
||||
fst.fst_offset = 0;
|
||||
fst.fst_length = length;
|
||||
fst.fst_bytesalloc = 0;
|
||||
return fcntl( fd, F_PREALLOCATE, &fst );
|
||||
HANDLE hFile = CreateFile( filename, GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0 );
|
||||
if( hFile != INVALID_HANDLE_VALUE )
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = desiredFileSize;
|
||||
success = SetFilePointerEx( hFile, desiredFileSize, NULL, FILE_BEGIN )
|
||||
&& SetEndOfFile( hFile );
|
||||
CloseHandle( hFile );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#warning no known method to preallocate files on this platform
|
||||
return -1;
|
||||
int flags = O_RDWR | O_CREAT | O_LARGEFILE;
|
||||
int fd = open( filename, flags, 0666 );
|
||||
if( fd >= 0 )
|
||||
{
|
||||
|
||||
# ifdef HAVE_FALLOCATE
|
||||
|
||||
success = !fallocate( fd, FALLOC_FL_KEEP_SIZE, 0, length );
|
||||
|
||||
# elif defined(HAVE_POSIX_FALLOCATE)
|
||||
|
||||
success = !posix_fallocate( fd, 0, length );
|
||||
|
||||
# elif defined(SYS_DARWIN)
|
||||
|
||||
fstore_t fst;
|
||||
fst.fst_flags = F_ALLOCATECONTIG;
|
||||
fst.fst_posmode = F_PEOFPOSMODE;
|
||||
fst.fst_offset = 0;
|
||||
fst.fst_length = length;
|
||||
fst.fst_bytesalloc = 0;
|
||||
success = !fcntl( fd, F_PREALLOCATE, &fst );
|
||||
|
||||
# else
|
||||
|
||||
#warning no known method to preallocate files on this platform
|
||||
success = 0;
|
||||
|
||||
# endif
|
||||
|
||||
close( fd );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,6 +194,10 @@ TrOpenFile( int i,
|
|||
|
||||
alreadyExisted = !stat( filename, &sb ) && S_ISREG( sb.st_mode );
|
||||
|
||||
if( doWrite && !alreadyExisted && doPreallocate )
|
||||
if( preallocateFile( filename, desiredFileSize ) )
|
||||
tr_inf( _( "Preallocated file \"%s\"" ), filename );
|
||||
|
||||
/* open the file */
|
||||
flags = doWrite ? ( O_RDWR | O_CREAT ) : O_RDONLY;
|
||||
#ifdef O_LARGEFILE
|
||||
|
@ -180,10 +216,6 @@ TrOpenFile( int i,
|
|||
return err;
|
||||
}
|
||||
|
||||
if( ( file->fd >= 0 ) && !alreadyExisted && doPreallocate )
|
||||
if( !preallocateFile( file->fd, desiredFileSize ) )
|
||||
tr_inf( _( "Preallocated file \"%s\"" ), filename );
|
||||
|
||||
tr_free( filename );
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue