[haiku-commits] r39343 - haiku/trunk/src/add-ons/kernel/file_systems/ext2

Author: korli
Date: 2010-11-07 16:19:08 +0100 (Sun, 07 Nov 2010)
New Revision: 39343
Changeset: http://dev.haiku-os.org/changeset/39343

Modified:
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.h
   haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp
Log:
DirectoryIterator changes:
* RemoveEntry(): set inode id to zero when reaching the end of block
* FindEntry(): keep on searching if Get() returns B_BAD_DATA
* added _Offset() based on fLogicalBlock and fDisplacement
* Next(): keep on searching when inode id is zero; also when entry length is 
zero, keep on with next block
* added GetNext() to get the next valid entry.
* Get(): now returns B_BAD_DATA on a zero length or inode id.


Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp 
2010-11-07 14:16:48 UTC (rev 39342)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/BlockAllocator.cpp 
2010-11-07 15:19:08 UTC (rev 39343)
@@ -660,7 +660,7 @@
        TRACE("BlockAllocator::Free(): first block: %lu, blocks per group: 
%lu\n", 
                fFirstBlock, fBlocksPerGroup);
 
-       //start -= fFirstBlock;
+       start -= fFirstBlock;
        off_t end = start + length - 1;
 
        uint32 group = start / fBlocksPerGroup;

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp      
2010-11-07 14:16:48 UTC (rev 39342)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp      
2010-11-07 15:19:08 UTC (rev 39343)
@@ -52,12 +52,12 @@
                : (directory->Size() - 1) / fBlockSize + 1),
        fLogicalBlock(start / fBlockSize),
        fDisplacement(start % fBlockSize),
-       fPreviousDisplacement(fPreviousDisplacement),
+       fPreviousDisplacement(fDisplacement),
        fStartLogicalBlock(fLogicalBlock),
        fStartDisplacement(fDisplacement)
 {
-       TRACE("DirectoryIterator::DirectoryIterator(): num blocks: %lu\n",
-               fNumBlocks);
+       TRACE("DirectoryIterator::DirectoryIterator() %lld: num blocks: %lu\n",
+               fDirectory->ID(), fNumBlocks);
        fIndexing = parent != NULL;
        fInitStatus = fDirectory->FindBlock(start, fPhysicalBlock);
        fStartPhysicalBlock = fPhysicalBlock;
@@ -83,7 +83,8 @@
 status_t
 DirectoryIterator::Get(char* name, size_t* _nameLength, ino_t* _id)
 {
-       if (fLogicalBlock * fBlockSize + fDisplacement >= fDirectory->Size()) {
+       TRACE("DirectoryIterator::Get() ID %lld\n", fDirectory->ID());
+       if (_Offset() >= fDirectory->Size()) {
                TRACE("DirectoryIterator::Get() out of entries\n");
                return B_ENTRY_NOT_FOUND;
        }
@@ -96,6 +97,9 @@
        TRACE("DirectoryIterator::Get(): Displacement: %lu\n", fDisplacement);
        const ext2_dir_entry* entry = (const 
ext2_dir_entry*)&block[fDisplacement];
 
+       if (entry->Length() == 0 || entry->InodeID() == 0)
+               return B_BAD_DATA;
+
        if (entry->NameLength() != 0) {
                size_t length = entry->NameLength();
 
@@ -122,11 +126,24 @@
 
 
 status_t
+DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id)
+{
+       status_t status;
+       while ((status = Get(name, _nameLength, _id)) == B_BAD_DATA) {
+               status = Next();
+               if (status != B_OK)
+                       return status;
+       }
+       return status;
+}
+
+
+status_t
 DirectoryIterator::Next()
 {
-       TRACE("DirectoryIterator::Next()\n");
+       TRACE("DirectoryIterator::Next() fDirectory->ID() %lld\n", 
fDirectory->ID());
 
-       if (fLogicalBlock * fBlockSize + fDisplacement >= fDirectory->Size()) {
+       if (_Offset() >= fDirectory->Size()) {
                TRACE("DirectoryIterator::Next() out of entries\n");
                return B_ENTRY_NOT_FOUND;
        }
@@ -144,21 +161,19 @@
        entry = (ext2_dir_entry*)(block + fDisplacement);
 
        do {
-               TRACE("Checking entry at block %llu, displacement %lu\n", 
fPhysicalBlock,
-                       fDisplacement);
+               TRACE("Checking entry at block %llu, displacement %lu entry 
inodeid %ld\n", fPhysicalBlock,
+                       fDisplacement, entry->InodeID());
 
-               if (entry->Length() == 0) {
-                       TRACE("empty entry.\n");
-                       return B_ENTRY_NOT_FOUND;
-               }
-               if (!entry->IsValid()) {
-                       TRACE("invalid entry.\n");
-                       return B_BAD_DATA;
-               }
+               if (entry->Length() != 0) {
+                       if (!entry->IsValid()) {
+                               TRACE("invalid entry.\n");
+                               return B_BAD_DATA;
+                       }
+                       fPreviousDisplacement = fDisplacement;
+                       fDisplacement += entry->Length();
+               } else 
+                       fDisplacement = fBlockSize;
 
-               fPreviousDisplacement = fDisplacement;
-               fDisplacement += entry->Length();
-
                if (fDisplacement == fBlockSize) {
                        TRACE("Reached end of block\n");
 
@@ -167,23 +182,19 @@
                        status_t status = _NextBlock();
                        if (status != B_OK)
                                return status;
-                       
-                       if (fLogicalBlock * fBlockSize + 
ext2_dir_entry::MinimumSize()
-                                       < fDirectory->Size()) {
-                               status_t status = fDirectory->FindBlock(
-                                       fLogicalBlock * fBlockSize, 
fPhysicalBlock);
-                               if (status != B_OK)
-                                       return status;
-                       } else {
+                                               
+                       if (_Offset() + ext2_dir_entry::MinimumSize()
+                                       >= fDirectory->Size()) {
                                TRACE("DirectoryIterator::Next() end of 
directory file\n");
                                return B_ENTRY_NOT_FOUND;
                        }
+                       status = fDirectory->FindBlock(_Offset(), 
fPhysicalBlock);
+                       if (status != B_OK)
+                               return status;
 
-                       if (entry->Length() == 0) {
-                               block = cached.SetTo(fPhysicalBlock);
-                               if (block == NULL)
-                                       return B_IO_ERROR;
-                       }
+                       block = cached.SetTo(fPhysicalBlock);
+                       if (block == NULL)
+                               return B_IO_ERROR;
                } else if (fDisplacement > fBlockSize) {
                        TRACE("The entry isn't block aligned.\n");
                        // TODO: Is block alignment obligatory?
@@ -192,9 +203,12 @@
 
                entry = (ext2_dir_entry*)(block + fDisplacement);
 
-               TRACE("DirectoryIterator::Next() skipping entry\n");
-       } while (entry->Length() == 0);
+               TRACE("DirectoryIterator::Next() skipping entry %d %ld\n", 
entry->Length(), entry->InodeID());
+       } while (entry->Length() == 0 || entry->InodeID() == 0);
 
+       TRACE("DirectoryIterator::Next() entry->Length() %d entry->name %s\n",
+                       entry->Length(), entry->name);
+
        return B_OK;
 }
 
@@ -244,11 +258,10 @@
                } else if (status != B_DEVICE_FULL)
                        return status;
                
+               fDisplacement = 0;
                status = _NextBlock();
-               if (status == B_OK) {
-                       status = fDirectory->FindBlock(fLogicalBlock * 
fBlockSize,
-                               fPhysicalBlock);
-               }
+               if (status == B_OK)
+                       status = fDirectory->FindBlock(_Offset(), 
fPhysicalBlock);
        }
 
        if (status != B_ENTRY_NOT_FOUND)
@@ -299,15 +312,14 @@
        while (status == B_OK) {
                size_t nameLength = EXT2_NAME_LENGTH;
                status = Get(buffer, &nameLength, &id);
-               if (status != B_OK)
-                       return status;
-
-               if (strcmp(name, buffer) == 0) {
-                       if (_id != NULL)
-                               *_id = id;
-                       return B_OK;
-               }
-
+               if (status == B_OK) {
+                       if (strcmp(name, buffer) == 0) {
+                               if (_id != NULL)
+                                       *_id = id;
+                               return B_OK;
+                       }
+               } else if (status != B_BAD_DATA)
+                       break;
                status = Next();
        }
 
@@ -318,6 +330,7 @@
 status_t
 DirectoryIterator::RemoveEntry(Transaction& transaction)
 {
+       TRACE("DirectoryIterator::RemoveEntry()\n");
        ext2_dir_entry* previousEntry;
        ext2_dir_entry* dirEntry;
        CachedBlock cached(fVolume);
@@ -331,9 +344,9 @@
                fDisplacement += previousEntry->Length();
 
                if (fDisplacement == fBlockSize) {
-                       memset(&previousEntry->name_length, 0, fBlockSize - 6);
+                       previousEntry->SetInodeID(0);
                        fDisplacement = 0;
-                       return Next();
+                       return B_OK;
                } else if (fDisplacement > fBlockSize) {
                        TRACE("DirectoryIterator::RemoveEntry(): Entry isn't 
aligned to "
                                "block entry.");
@@ -350,6 +363,8 @@
                return B_OK;
        }
 
+       TRACE("DirectoryIterator::RemoveEntry() fDisplacement %ld\n", 
fDisplacement);
+
        if (fPreviousDisplacement == fDisplacement) {
                char buffer[EXT2_NAME_LENGTH + 1];
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.h        
2010-11-07 14:16:48 UTC (rev 39342)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.h        
2010-11-07 15:19:08 UTC (rev 39343)
@@ -25,6 +25,7 @@
 
                        status_t        Next();
                        status_t        Get(char* name, size_t* _nameLength, 
ino_t* id);
+                       status_t        GetNext(char* name, size_t* 
_nameLength, ino_t* id);
 
                        status_t        Rewind();
                        void            Restart();
@@ -56,6 +57,8 @@
                                                        bool firstSplit = 
false);
 
                        status_t        _NextBlock();
+                       off_t           _Offset() { return fLogicalBlock * 
fBlockSize
+                                                       + fDisplacement; }
 
 
        Inode*                          fDirectory;

Modified: haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp       
2010-11-07 14:16:48 UTC (rev 39342)
+++ haiku/trunk/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp       
2010-11-07 15:19:08 UTC (rev 39343)
@@ -1371,7 +1371,7 @@
 
        size_t length = bufferSize;
        ino_t id;
-       status_t status = iterator->Get(dirent->d_name, &length, &id);
+       status_t status = iterator->GetNext(dirent->d_name, &length, &id);
        if (status == B_ENTRY_NOT_FOUND) {
                *_num = 0;
                return B_OK;


Other related posts:

  • » [haiku-commits] r39343 - haiku/trunk/src/add-ons/kernel/file_systems/ext2 - korli