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

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 20 Oct 2009 02:29:11 +0200 (CEST)

Author: axeld
Date: 2009-10-20 02:29:11 +0200 (Tue, 20 Oct 2009)
New Revision: 33675
Changeset: http://dev.haiku-os.org/changeset/33675/haiku

Modified:
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h
Log:
* Fixed double indirect ranges again: I've messed them up when I tried to make
  them more BeOS compatible while still keeping them somewhat flexible.
* _GrowStream() did actually not check if the double indirect region was already
  filled up - this caused it to overwrite innocent memory. This fixes the bug
  Rudolf showed me on this laptop that happened while copying a large file.
* Loosened file size restriction on a heavy fragmented disk: the indirect block
  does not require a minimum array size anymore; before, you just couldn't let
  a stream grow into the indirect range if it couldn't allocate NUM_ARRAY_BLOCKS
  (4) blocks in a row. This considerably reduced the maximum file size in this
  case.
* Removed no longer valid TODO.


Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp   2009-10-20 
00:23:53 UTC (rev 33674)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp   2009-10-20 
00:29:11 UTC (rev 33675)
@@ -1583,12 +1583,13 @@
 */
 status_t
 Inode::_AllocateBlockArray(Transaction& transaction, block_run& run,
-       size_t length)
+       size_t length, bool variableSize)
 {
        if (!run.IsZero())
                return B_BAD_VALUE;
 
-       status_t status = fVolume->Allocate(transaction, this, length, run, 
length);
+       status_t status = fVolume->Allocate(transaction, this, length, run,
+               variableSize ? 1 : length);
        if (status != B_OK)
                return status;
 
@@ -1708,9 +1709,6 @@
                // okay, we have the needed blocks, so just distribute them to 
the
                // different ranges of the stream (direct, indirect & double 
indirect)
 
-               // TODO: if anything goes wrong here, we probably want to free 
the
-               // blocks that couldn't be distributed into the stream!
-
                blocksNeeded -= run.Length();
                // don't preallocate if the first allocation was already too 
small
                blocksRequested = blocksNeeded;
@@ -1720,9 +1718,10 @@
                if (data->Size() <= data->MaxDirectRange()) {
                        // let's try to put them into the direct block range
                        int32 free = 0;
-                       for (; free < NUM_DIRECT_BLOCKS; free++)
+                       for (; free < NUM_DIRECT_BLOCKS; free++) {
                                if (data->direct[free].IsZero())
                                        break;
+                       }
 
                        if (free < NUM_DIRECT_BLOCKS) {
                                // can we merge the last allocated run with the 
new one?
@@ -1754,7 +1753,7 @@
                        // if there is no indirect block yet, create one
                        if (data->indirect.IsZero()) {
                                status = _AllocateBlockArray(transaction, 
data->indirect,
-                                       NUM_ARRAY_BLOCKS);
+                                       NUM_ARRAY_BLOCKS, true);
                                if (status != B_OK)
                                        return status;
 
@@ -1875,8 +1874,12 @@
                        while (run.length != 0) {
                                // get the indirect array block
                                if (array == NULL) {
+                                       uint32 block = indirectIndex / 
runsPerBlock;
+                                       if (block >= minimum)
+                                               return EFBIG;
+
                                        array = 
(block_run*)cached.SetTo(fVolume->ToBlock(
-                                               data->double_indirect) + 
indirectIndex / runsPerBlock);
+                                               data->double_indirect) + block);
                                        if (array == NULL)
                                                return B_IO_ERROR;
                                }
@@ -1903,13 +1906,13 @@
                                                // insert the block_run into 
the array
                                                runs[index % runsPerBlock] = 
run;
                                                runs[index % 
runsPerBlock].length
-                                                       = 
HOST_ENDIAN_TO_BFS_INT16(NUM_ARRAY_BLOCKS);
+                                                       = 
HOST_ENDIAN_TO_BFS_INT16(minimum);
 
                                                // alter the remaining block_run
                                                run.start = 
HOST_ENDIAN_TO_BFS_INT16(run.Start()
-                                                       + NUM_ARRAY_BLOCKS);
+                                                       + minimum);
                                                run.length = 
HOST_ENDIAN_TO_BFS_INT16(run.Length()
-                                                       - NUM_ARRAY_BLOCKS);
+                                                       - minimum);
                                        } while ((++index % runsPerBlock) != 0 
&& run.length);
                                } while ((index % runsPerArray) != 0 && 
run.length);
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h     2009-10-20 
00:23:53 UTC (rev 33674)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h     2009-10-20 
00:29:11 UTC (rev 33675)
@@ -220,7 +220,8 @@
                                                                block_run* 
array, uint32 arrayLength,
                                                                off_t size, 
off_t& offset, off_t& max);
                        status_t                
_AllocateBlockArray(Transaction& transaction,
-                                                               block_run& run, 
size_t length);
+                                                               block_run& run, 
size_t length,
+                                                               bool 
variableSize = false);
                        status_t                _GrowStream(Transaction& 
transaction, off_t size);
                        status_t                _ShrinkStream(Transaction& 
transaction, off_t size);
 


Other related posts:

  • » [haiku-commits] r33675 - haiku/trunk/src/add-ons/kernel/file_systems/bfs - axeld