[Haiku-commits] r31253 - haiku/trunk/src/add-ons/kernel/file_systems/bfs

axeld at BerliOS axeld at mail.berlios.de
Fri Jun 26 16:49:48 CEST 2009


Author: axeld
Date: 2009-06-26 16:49:48 +0200 (Fri, 26 Jun 2009)
New Revision: 31253
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31253&view=rev

Modified:
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp
Log:
* Directories now only preallocate 4 KB.
* Reworked how preallocations are chosen, and also take the grow rate into
  account.
* Also, the preallocation is now rounded to the next multiple of the
  preallocation size (previously, a 64K write would only allocate 64K).
* This should also close bug #2573.


Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp	2009-06-26 13:47:13 UTC (rev 31252)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp	2009-06-26 14:49:48 UTC (rev 31253)
@@ -1585,6 +1585,10 @@
 }
 
 
+/*!	Grows the stream to \a size, and fills the direct/indirect/double indirect
+	ranges with the runs.
+	This method will also determine the size of the preallocation, if any.
+*/
 status_t
 Inode::_GrowStream(Transaction& transaction, off_t size)
 {
@@ -1615,12 +1619,12 @@
 		bytes = size - data->Size();
 
 	// do we have enough free blocks on the disk?
-	off_t blocksRequested = (bytes + fVolume->BlockSize() - 1)
+	off_t blocksNeeded = (bytes + fVolume->BlockSize() - 1)
 		>> fVolume->BlockShift();
-	if (blocksRequested > fVolume->FreeBlocks())
+	if (blocksNeeded > fVolume->FreeBlocks())
 		return B_DEVICE_FULL;
 
-	off_t blocksNeeded = blocksRequested;
+	off_t blocksRequested = blocksNeeded;
 		// because of preallocations and partial allocations, the number of
 		// blocks we need to allocate may be different from the one we request
 		// from the block allocator
@@ -1629,27 +1633,33 @@
 	// Attributes, attribute directories, and long symlinks usually won't get
 	// that big, and should stay close to the inode - preallocating could be
 	// counterproductive.
-	// Also, if free disk space is tight, we probably don't want to do this as
-	// well.
+	// Also, if free disk space is tight, don't preallocate.
 	if (!IsAttribute() && !IsAttributeDirectory() && !IsSymLink()
-		&& blocksRequested < (65536 >> fVolume->BlockShift())
 		&& fVolume->FreeBlocks() > 128) {
-		// preallocate 64 KB at minimum
+		off_t roundTo = 0;
 		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();
+			// Request preallocated blocks depending on the file size and growth
+			if (size < 1 * 1024 * 1024 && bytes < 512 * 1024) {
+				// Preallocate 64 KB for file sizes <1 MB and grow rates <512 KB
+				roundTo = 65536 >> fVolume->BlockShift();
+			} else if (size < 32 * 1024 * 1024 && bytes <= 1 * 1024 * 1024) {
+				// Preallocate 512 KB for file sizes between 1 MB and 32 MB, and
+				// grow rates smaller than 1 MB
+				roundTo = (512 * 1024) >> fVolume->BlockShift();
 			} else {
-				// preallocate 1/16 of the file size (ie. 4 MB for 64 MB,
+				// Preallocate 1/16 of the file size (ie. 4 MB for 64 MB,
 				// 64 MB for 1 GB)
-				blocksRequested = size >> (fVolume->BlockShift() + 4);
+				roundTo = size >> (fVolume->BlockShift() + 4);
 			}
-		} else
-			blocksRequested = 65536 >> fVolume->BlockShift();
+		} else {
+			// Preallocate only 4 KB - directories only get trimmed when their
+			// vnode is flushed, which might not happen very often.
+			roundTo = 4096 >> fVolume->BlockShift();
+		}
+		if (roundTo > 1) {
+			// Round to next "roundTo" block count
+			blocksRequested = ((blocksNeeded + roundTo) / roundTo) * roundTo;
+		}
 	}
 
 	while (blocksNeeded > 0) {




More information about the Haiku-commits mailing list