void FileAllocator::ensureLength(int fd , long size) { #if !defined(_WIN32) if (useSparseFiles(fd)) { LOG(1) << "using ftruncate to create a sparse file" << endl; int ret = ftruncate(fd, size); uassert(16063, "ftruncate failed: " + errnoWithDescription(), ret == 0); return; } #endif #if defined(__linux__) int ret = posix_fallocate(fd,0,size); if ( ret == 0 ) return; log() << "FileAllocator: posix_fallocate failed: " << errnoWithDescription( ret ) << " falling back" << endl; #endif off_t filelen = lseek( fd, 0, SEEK_END ); if ( filelen < size ) { if (filelen != 0) { stringstream ss; ss << "failure creating new datafile; lseek failed for fd " << fd << " with errno: " << errnoWithDescription(); uassert( 10440 , ss.str(), filelen == 0 ); } // Check for end of disk. uassert( 10441 , str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(), size - 1 == lseek(fd, size - 1, SEEK_SET) ); uassert( 10442 , str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(), 1 == write(fd, "", 1) ); // File expansion is completed here. Do not do the zeroing out on OS-es where there // is no risk of triggering allocation-related bugs such as // http://support.microsoft.com/kb/2731284. // if (!ProcessInfo::isDataFileZeroingNeeded()) { return; } lseek(fd, 0, SEEK_SET); const long z = 256 * 1024; const boost::scoped_array<char> buf_holder (new char[z]); char* buf = buf_holder.get(); memset(buf, 0, z); long left = size; while ( left > 0 ) { long towrite = left; if ( towrite > z ) towrite = z; int written = write( fd , buf , towrite ); uassert( 10443 , errnoWithPrefix("FileAllocator: file write failed" ), written > 0 ); left -= written; } } }
void FileAllocator::ensureLength(int fd , long size) { #if !defined(_WIN32) if (useSparseFiles(fd)) { LOG(1) << "using ftruncate to create a sparse file" << endl; int ret = ftruncate(fd, size); uassert(16063, "ftruncate failed: " + errnoWithDescription(), ret == 0); return; } #endif #if defined(__linux__) int ret = posix_fallocate(fd,0,size); if ( ret == 0 ) return; log() << "FileAllocator: posix_fallocate failed: " << errnoWithDescription( ret ) << " falling back" << endl; #endif off_t filelen = lseek( fd, 0, SEEK_END ); if ( filelen < size ) { if (filelen != 0) { stringstream ss; ss << "failure creating new datafile; lseek failed for fd " << fd << " with errno: " << errnoWithDescription(); uassert( 10440 , ss.str(), filelen == 0 ); } // Check for end of disk. uassert( 10441 , str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(), size - 1 == lseek(fd, size - 1, SEEK_SET) ); uassert( 10442 , str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(), 1 == write(fd, "", 1) ); lseek(fd, 0, SEEK_SET); const long z = 256 * 1024; const boost::scoped_array<char> buf_holder (new char[z]); char* buf = buf_holder.get(); memset(buf, 0, z); long left = size; while ( left > 0 ) { long towrite = left; if ( towrite > z ) towrite = z; int written = write( fd , buf , towrite ); uassert( 10443 , errnoWithPrefix("FileAllocator: file write failed" ), written > 0 ); left -= written; } } }