From 34d496f8c38338a00542e96d9a327924c214523c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 4 Aug 2008 14:54:22 +0000 Subject: [PATCH] * 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 --- src/add-ons/kernel/file_systems/bfs/Inode.cpp | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index 3f18f831c4..20129d3ded 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -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