* For regular files, BFS will now preallocate much more than the previous 64 KB,

which are now only used for directories and for files smaller than 1 MB.
* For files between 1 MB and 32 MB 512 KB are used as preallocation size,
  everything beyond that will get a 1/16 of their file size, ie. 4 MB with a
  file size of 64 MB, 64 MB with a file size of 1 GB.
* This should help a lot with fragmentation of large files when they are written
  synchronously.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26794 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-08-04 14:54:22 +00:00
parent 1a168f3f1f
commit 34d496f8c3

View File

@ -1568,7 +1568,7 @@ Inode::_GrowStream(Transaction& transaction, off_t size)
// blocks we need to allocate may be different from the one we request
// from the block allocator
// Should we preallocate some blocks (currently, always 64k)?
// Should we preallocate some blocks?
// Attributes, attribute directories, and long symlinks usually won't get
// that big, and should stay close to the inode - preallocating could be
// counterproductive.
@ -1576,8 +1576,24 @@ Inode::_GrowStream(Transaction& transaction, off_t size)
// well.
if (!IsAttribute() && !IsAttributeDirectory() && !IsSymLink()
&& blocksRequested < (65536 >> fVolume->BlockShift())
&& fVolume->FreeBlocks() > 128)
blocksRequested = 65536 >> fVolume->BlockShift();
&& fVolume->FreeBlocks() > 128) {
// preallocate 64 KB at minimum
if (IsFile()) {
// request preallocated blocks depending on the file size
if (size < 1 * 1024 * 1024) {
// preallocate 64 KB for file sizes < 1 MB
blocksRequested = 65536 >> fVolume->BlockShift();
} else if (size < 32 * 1024 * 1024) {
// preallocate 512 KB for file sizes between 1 MB and 32 MB
blocksRequested = (512 * 1024) >> fVolume->BlockShift();
} else {
// preallocate 1/16 of the file size (ie. 4 MB for 64 MB,
// 64 MB for 1 GB)
blocksRequested = size >> (fVolume->BlockShift() + 4);
}
} else
blocksRequested = 65536 >> fVolume->BlockShift();
}
while (blocksNeeded > 0) {
// the requested blocks do not need to be returned with a