Ticket #6305: htree_update.patch

File htree_update.patch, 38.9 KB (added by jvff, 14 years ago)

This is an updated patch of the same code. I'm not sure it fixes the crash, but it will output more information to help find the cause.

  • src/add-ons/kernel/file_systems/ext2/Inode.cpp

     
    2626    fID(id),
    2727    fCache(NULL),
    2828    fMap(NULL),
    29     fNode(NULL),
    3029    fAttributesBlock(NULL)
    3130{
    3231    rw_lock_init(&fLock, "ext2 inode");
    3332
    3433    uint32 block;
    35     if (volume->GetInodeBlock(id, block) == B_OK) {
    36         TRACE("inode %Ld at block %lu\n", ID(), block);
    37         uint8* inodeBlock = (uint8*)block_cache_get(volume->BlockCache(),
    38             block);
     34    fInitStatus = volume->GetInodeBlock(id, block);
     35    if (fInitStatus == B_OK) {
     36        TRACE("inode %Ld at block %lu\n", id, block);
     37
     38        CachedBlock cached(volume);
     39        const uint8* inodeBlock = cached.SetTo(block);
     40        TRACE("Inode table block in memory: %p\n", inodeBlock);
     41
    3942        if (inodeBlock != NULL) {
    40             fNode = (ext2_inode*)(inodeBlock + volume->InodeBlockIndex(id)
    41                 * volume->InodeSize());
    42         }
     43            TRACE("Inode size: %lu, inode index: %lu\n", volume->InodeSize(),
     44                volume->InodeBlockIndex(id));
     45            ext2_inode* inode = (ext2_inode*)(inodeBlock
     46                + volume->InodeBlockIndex(id) * volume->InodeSize());
     47           
     48            fNodeSize = sizeof(ext2_inode) > volume->InodeSize()
     49                ? volume->InodeSize() : sizeof(ext2_inode);
     50           
     51            TRACE("Attempting to copy inode data from %p to %p, ext2_inode "
     52                "size: %lu\n", inode, &fNode, fNodeSize);
     53           
     54            memcpy(&fNode, inode, fNodeSize);
     55        } else
     56            fInitStatus = B_IO_ERROR;
    4357    }
    4458
    45     if (fNode != NULL) {
    46         // TODO: we don't need a cache for short symlinks
    47         fCache = file_cache_create(fVolume->ID(), ID(), Size());
    48         fMap = file_map_create(fVolume->ID(), ID(), Size());
     59    if (fInitStatus == B_OK) {
     60        if (Size() == 0 || IsDirectory() || (IsSymLink() && Size() < 60)) {
     61            fCached = false;
     62        } else {
     63            fCache = file_cache_create(fVolume->ID(), ID(), Size());
     64            fMap = file_map_create(fVolume->ID(), ID(), Size());
     65
     66            if (fCache != NULL) {
     67                TRACE("Inode::Inode(): Created file cache\n");
     68                fCached = true;
     69            } else {
     70                TRACE("Inode::Inode(): Failed to create file cache\n");
     71                fCached = false;
     72                fInitStatus = B_ERROR;
     73            }
     74        }
     75    } else {
     76        TRACE("Inode: Failed initialization\n");
     77        fCached = false;
    4978    }
    5079}
    5180
    5281
    5382Inode::~Inode()
    5483{
    55     file_cache_delete(FileCache());
    56     file_map_delete(Map());
     84    TRACE("Inode destructor\n");
    5785
     86    if (fCached) {
     87        TRACE("Deleting the file cache and file map\n");
     88        file_cache_delete(FileCache());
     89        file_map_delete(Map());
     90    }
     91
    5892    if (fAttributesBlock) {
     93        TRACE("Returning the attributes block\n");
    5994        uint32 block = B_LENDIAN_TO_HOST_INT32(Node().file_access_control);
    6095        block_cache_put(fVolume->BlockCache(), block);
    6196    }
    6297
    63     if (fNode != NULL) {
    64         uint32 block;
    65         if (fVolume->GetInodeBlock(ID(), block) == B_OK)
    66             block_cache_put(fVolume->BlockCache(), block);
    67     }
     98    TRACE("Inode destructor: Done\n");
    6899}
    69100
    70101
    71102status_t
    72103Inode::InitCheck()
    73104{
    74     return fNode != NULL ? B_OK : B_ERROR;
     105    return fInitStatus;
    75106}
    76107
    77108
     
    95126
    96127    // shift mode bits, to check directly against accessMode
    97128    mode_t mode = Mode();
    98     if (user == (uid_t)fNode->UserID())
     129    if (user == (uid_t)fNode.UserID())
    99130        mode >>= 6;
    100     else if (group == (gid_t)fNode->GroupID())
     131    else if (group == (gid_t)fNode.GroupID())
    101132        mode >>= 3;
    102133
    103134    if (accessMode & ~(mode & S_IRWXO))
     
    114145    uint32 perIndirectBlock = perBlock * perBlock;
    115146    uint32 index = offset >> fVolume->BlockShift();
    116147
    117     if (offset >= Size())
     148    if (offset >= Size()) {
     149        TRACE("FindBlock: offset larger than inode size\n");
    118150        return B_ENTRY_NOT_FOUND;
     151    }
    119152
    120153    // TODO: we could return the size of the sparse range, as this might be more
    121154    // than just a block
     
    203236
    204237    // set/check boundaries for pos/length
    205238    if (pos < 0) {
    206         TRACE("inode %Ld: ReadAt failed(pos %Ld, length %lu)\n", ID(), pos, length);
     239        TRACE("inode %Ld: ReadAt failed(pos %Ld, length %lu)\n", ID(), pos,
     240            length);
    207241        return B_BAD_VALUE;
    208242    }
    209243
     
    245279    *_length = length;
    246280    return B_NO_ERROR;
    247281}
     282
     283
     284status_t
     285Inode::DisableFileCache()
     286{
     287    TRACE("Inode::DisableFileCache()\n");
     288
     289    if (!fCached)
     290        return B_OK;
     291
     292    file_cache_delete(FileCache());
     293    file_map_delete(Map());
     294
     295    fCached = false;
     296
     297    return B_OK;
     298}
  • src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp

     
    116116
    117117    status_t status = volume->Mount(device, flags);
    118118    if (status != B_OK) {
     119        TRACE("Failed mounting the volume. Error: %s\n", strerror(status));
    119120        delete volume;
    120121        return status;
    121122    }
  • src/add-ons/kernel/file_systems/ext2/Inode.h

     
    3232
    3333            status_t    CheckPermissions(int accessMode) const;
    3434
    35             mode_t      Mode() const { return fNode->Mode(); }
    36             int32       Flags() const { return fNode->Flags(); }
     35            mode_t      Mode() const { return fNode.Mode(); }
     36            int32       Flags() const { return fNode.Flags(); }
    3737
    38             off_t       Size() const { return fNode->Size(); }
     38            off_t       Size() const { return fNode.Size(); }
    3939            time_t      ModificationTime() const
    40                             { return fNode->ModificationTime(); }
     40                            { return fNode.ModificationTime(); }
    4141            time_t      CreationTime() const
    42                             { return fNode->CreationTime(); }
     42                            { return fNode.CreationTime(); }
    4343            time_t      AccessTime() const
    44                             { return fNode->AccessTime(); }
     44                            { return fNode.AccessTime(); }
    4545
    4646            //::Volume* _Volume() const { return fVolume; }
    4747            Volume*     GetVolume() const { return fVolume; }
     
    5252            status_t    AttributeBlockReadAt(off_t pos, uint8 *buffer,
    5353                            size_t *length);
    5454
    55             ext2_inode& Node() { return *fNode; }
     55            ext2_inode& Node() { return fNode; }
    5656
    5757            void*       FileCache() const { return fCache; }
    5858            void*       Map() const { return fMap; }
     59            status_t    DisableFileCache();
     60            bool        IsFileCacheDisabled() const { return !fCached; }
    5961
    6062private:
    6163                        Inode(const Inode&);
     
    6365                            // no implementation
    6466
    6567private:
    66     rw_lock             fLock;
    67     ::Volume*           fVolume;
    68     ino_t               fID;
    69     void*               fCache;
    70     void*               fMap;
    71     ext2_inode*         fNode;
    72     ext2_xattr_header*  fAttributesBlock;
     68            rw_lock     fLock;
     69            ::Volume*   fVolume;
     70            ino_t       fID;
     71            void*       fCache;
     72            void*       fMap;
     73            bool        fCached;
     74            ext2_inode  fNode;
     75            uint32      fNodeSize;
     76                // Inodes have a varible size, but the important
     77                // information is always the same size (except in ext4)
     78            ext2_xattr_header* fAttributesBlock;
     79            status_t    fInitStatus;
    7380};
    7481
    7582#endif  // INODE_H
  • src/add-ons/kernel/file_systems/ext2/HTreeEntryIterator.cpp

     
    1111
    1212#include <new>
    1313
     14#include "CachedBlock.h"
    1415#include "HTree.h"
    1516#include "IndexedDirectoryIterator.h"
    1617#include "Inode.h"
     
    2728
    2829HTreeEntryIterator::HTreeEntryIterator(off_t offset, Inode* directory)
    2930    :
     31    fDirectory(directory),
     32    fVolume(directory->GetVolume()),
    3033    fHasCollision(false),
    31     fDirectory(directory),
    32     fOffset(offset),
     34    fBlockSize(directory->GetVolume()->BlockSize()),
    3335    fParent(NULL),
    3436    fChild(NULL)
    3537{
    36     fBlockSize = fDirectory->GetVolume()->BlockSize();
     38    fInitStatus = fDirectory->FindBlock(offset, fBlockNum);
     39   
     40    if (fInitStatus == B_OK) {
     41        fFirstEntry = offset % fBlockSize / sizeof(HTreeEntry);
     42        fCurrentEntry = fFirstEntry;
     43    }
     44
     45    TRACE("HTreeEntryIterator::HTreeEntryIterator() block %lu entry no. %lu\n",
     46        fBlockNum, (uint32)fCurrentEntry);
    3747}
    3848
    3949
    4050HTreeEntryIterator::HTreeEntryIterator(uint32 block, uint32 blockSize,
    4151    Inode* directory, HTreeEntryIterator* parent, bool hasCollision)
    4252    :
     53    fDirectory(directory),
     54    fVolume(directory->GetVolume()),
    4355    fHasCollision(hasCollision),
     56    fFirstEntry(1),
     57    fCurrentEntry(1),
    4458    fBlockSize(blockSize),
    45     fDirectory(directory),
    46     fOffset(block * blockSize + sizeof(HTreeFakeDirEntry)),
     59    fBlockNum(block),
    4760    fParent(parent),
    4861    fChild(NULL)
    4962{
    50     TRACE("HTreeEntryIterator::HTreeEntryIterator() block %ld offset %Lx\n",
    51         block, fOffset);
     63    // fCurrentEntry is initialized to 1 to skip the fake directory entry
     64    fInitStatus = B_OK;
     65
     66    TRACE("HTreeEntryIterator::HTreeEntryIterator() block %lu\n", block);
    5267}
    5368
    5469
    5570status_t
    5671HTreeEntryIterator::Init()
    5772{
    58     size_t length = sizeof(HTreeCountLimit);
    59     HTreeCountLimit countLimit;
     73    TRACE("HTreeEntryIterator::Init() first entry: %lu\n",
     74        (uint32)fFirstEntry);
    6075   
    61     status_t status = fDirectory->ReadAt(fOffset, (uint8*)&countLimit,
    62         &length);
    63    
    64     if (status != B_OK)
    65         return status;
    66    
    67     if (length != sizeof(HTreeCountLimit)) {
    68         ERROR("HTreeEntryIterator::Init() bad length %ld fOffset 0x%Lx\n",
    69             length, fOffset);
     76    if (fInitStatus != B_OK)
     77        return fInitStatus;
     78
     79    CachedBlock cached(fVolume);
     80    const uint8* block = cached.SetTo(fBlockNum);
     81    if (block == NULL) {
     82        ERROR("Failed to read htree entry block.\n");
    7083        fCount = fLimit = 0;
    71         return B_ERROR;
     84        return B_IO_ERROR;
    7285    }
    73    
    74     fCount = countLimit.Count();
    75     fLimit = countLimit.Limit();
    7686
     87    HTreeCountLimit* countLimit = (HTreeCountLimit*)(
     88        &((HTreeEntry*)block)[fFirstEntry]);
     89
     90    fCount = countLimit->Count();
     91    fLimit = countLimit->Limit();
     92
    7793    if (fCount >= fLimit) {
    78         ERROR("HTreeEntryIterator::Init() bad fCount %d fOffset 0x%Lx\n",
    79             fCount, fOffset);
     94        ERROR("HTreeEntryIterator::Init() bad fCount %lu\n", (uint32)fCount);
    8095        fCount = fLimit = 0;
    8196        return B_ERROR;
    8297    }
    8398
    84     if (fParent != NULL &&
    85         fLimit != ((fBlockSize - sizeof(HTreeFakeDirEntry))
    86             / sizeof(HTreeEntry)) ) {
    87         ERROR("HTreeEntryIterator::Init() bad fLimit %d should be %ld "
    88             "fOffset 0x%Lx\n", fLimit, (fBlockSize - sizeof(HTreeFakeDirEntry))
    89                 / sizeof(HTreeEntry), fOffset);
     99    if (fLimit != fBlockSize / sizeof(HTreeEntry) - fFirstEntry) {
     100        ERROR("HTreeEntryIterator::Init() bad fLimit %lu should be %lu "
     101            "at block %lu\n", (uint32)fLimit, fBlockSize / sizeof(HTreeEntry)
     102                - fFirstEntry, fBlockNum);
    90103        fCount = fLimit = 0;
    91104        return B_ERROR;
    92     } 
     105    }
    93106
    94     TRACE("HTreeEntryIterator::Init() count 0x%x limit 0x%x\n", fCount,
    95         fLimit);
     107    TRACE("HTreeEntryIterator::Init() count %lu limit %lu\n",
     108        (uint32)fCount, (uint32)fLimit);
    96109
    97     fMaxOffset = fOffset + (fCount - 1) * sizeof(HTreeEntry);
    98    
    99110    return B_OK;
    100111}
    101112
    102113
    103114HTreeEntryIterator::~HTreeEntryIterator()
    104115{
     116    delete fChild;
    105117}
    106118
    107119
     
    109121HTreeEntryIterator::Lookup(uint32 hash, int indirections,
    110122    DirectoryIterator** directoryIterator)
    111123{
    112     off_t start = fOffset + sizeof(HTreeEntry);
    113     off_t end = fMaxOffset;
    114     off_t middle = start;
    115     size_t entrySize = sizeof(HTreeEntry);
    116     HTreeEntry entry;
     124    TRACE("HTreeEntryIterator::Lookup()\n");
     125    CachedBlock cached(fVolume);
     126    const uint8* block = cached.SetTo(fBlockNum);
     127    if (block == NULL) {
     128        ERROR("Failed to read htree entry block.\n");
     129        // Fallback to linear search
     130        *directoryIterator = new(std::nothrow)
     131            DirectoryIterator(fDirectory);
     132
     133        if (*directoryIterator == NULL)
     134            return B_NO_MEMORY;
     135
     136        return B_OK;
     137    }
     138
     139    HTreeEntry* start = (HTreeEntry*)block + fCurrentEntry + 1;
     140    HTreeEntry* end = (HTreeEntry*)block + fCount + fFirstEntry - 1;
     141    HTreeEntry* middle = start;
    117142   
     143    TRACE("HTreeEntryIterator::Lookup() current entry: %lu\n",
     144        (uint32)fCurrentEntry);
     145    TRACE("HTreeEntryIterator::Lookup() indirections: %d s:%p m:%p e:%p\n",
     146        indirections, start, middle, end);
     147
    118148    while (start <= end) {
    119         middle = (end - start) / 2;
    120         middle -= middle % entrySize; // Alignment
    121         middle += start;
     149        middle = (HTreeEntry*)((end - start) / 2
     150            + start);
    122151
    123         TRACE("HTreeEntryIterator::Lookup() %d 0x%Lx 0x%Lx 0x%Lx\n",
    124             indirections, start, end, middle);
    125        
    126         status_t status = fDirectory->ReadAt(middle, (uint8*)&entry,
    127             &entrySize);
     152        TRACE("HTreeEntryIterator::Lookup() indirections: %d s:%p m:%p e:%p\n",
     153            indirections, start, middle, end);
    128154
    129         TRACE("HTreeEntryIterator::Lookup() %lx %lx\n", hash, entry.Hash());
    130        
    131         if (status != B_OK)
    132             return status;
    133         else if (entrySize != sizeof(entry)) {
    134             // Fallback to linear search
    135             *directoryIterator = new(std::nothrow)
    136                 DirectoryIterator(fDirectory);
    137            
    138             if (*directoryIterator == NULL)
    139                 return B_NO_MEMORY;
    140            
    141             return B_OK;
    142         }
    143        
    144         if (hash >= entry.Hash())
    145             start = middle + entrySize;
     155        TRACE("HTreeEntryIterator::Lookup() %lx %lx\n", hash, middle->Hash());
     156
     157        if (hash >= middle->Hash())
     158            start = middle + 1;
    146159        else
    147             end = middle - entrySize;
     160            end = middle - 1;
    148161    }
    149162
    150     status_t status = fDirectory->ReadAt(start - entrySize, (uint8*)&entry,
    151         &entrySize);
    152     if (status != B_OK)
    153         return status;
    154    
     163    --start;
     164
     165    fCurrentEntry = ((uint8*)start - block) / sizeof(HTreeEntry);
     166
    155167    if (indirections == 0) {
     168        TRACE("HTreeEntryIterator::Lookup(): Creating an indexed directory "
     169            "iterator starting at block: %lu, hash: 0x%lX\n", start->Block(),
     170            start->Hash());
    156171        *directoryIterator = new(std::nothrow)
    157             IndexedDirectoryIterator(entry.Block() * fBlockSize, fBlockSize,
    158             fDirectory, this);
    159        
     172            IndexedDirectoryIterator(start->Block() * fBlockSize, fDirectory,
     173                this);
     174
    160175        if (*directoryIterator == NULL)
    161176            return B_NO_MEMORY;
    162177
    163178        return B_OK;
    164179    }
    165180
     181    TRACE("HTreeEntryIterator::Lookup(): Creating a HTree entry iterator "
     182        "starting at block: %lu, hash: 0x%lX\n", start->Block(), start->Hash());
     183    uint32 blockNum;
     184    status_t status = fDirectory->FindBlock(start->Block() * fBlockSize,
     185        blockNum);
     186    if (status != B_OK)
     187        return status;
     188
    166189    delete fChild;
    167190
    168     fChild = new(std::nothrow) HTreeEntryIterator(entry.Block(), fBlockSize,
    169         fDirectory, this, entry.Hash() & 1 == 1);
    170    
     191    fChild = new(std::nothrow) HTreeEntryIterator(blockNum, fBlockSize,
     192        fDirectory, this, start->Hash() & 1 == 1);
    171193    if (fChild == NULL)
    172194        return B_NO_MEMORY;
    173     fChildDeleter.SetTo(fChild);
    174195   
    175196    status = fChild->Init();
    176197    if (status != B_OK)
     
    181202
    182203
    183204status_t
    184 HTreeEntryIterator::GetNext(off_t& childOffset)
     205HTreeEntryIterator::GetNext(uint32& childBlock)
    185206{
    186     size_t entrySize = sizeof(HTreeEntry);
    187     fOffset += entrySize;
    188     bool firstEntry = fOffset >= fMaxOffset;
    189    
    190     if (firstEntry) {
    191         if (fParent == NULL)
     207    fCurrentEntry++;
     208    TRACE("HTreeEntryIterator::GetNext(): current entry: %lu\n",
     209        (uint32)fCurrentEntry);
     210    bool endOfBlock = fCurrentEntry >= (fCount + fFirstEntry);
     211
     212    if (endOfBlock) {
     213        TRACE("HTreeEntryIterator::GetNext(): end of entries in the block\n");
     214        if (fParent == NULL) {
     215            TRACE("HTreeEntryIterator::GetNext(): block was the root block\n");
    192216            return B_ENTRY_NOT_FOUND;
     217        }
    193218       
    194         status_t status = fParent->GetNext(fOffset);
     219        uint32 logicalBlock;
     220        status_t status = fParent->GetNext(logicalBlock);
    195221        if (status != B_OK)
    196222            return status;
    197223       
     224        TRACE("HTreeEntryIterator::GetNext(): moving to next block: %lu\n",
     225            logicalBlock);
     226       
     227        status = fDirectory->FindBlock(logicalBlock * fBlockSize, fBlockNum);
     228        if (status != B_OK)
     229            return status;
     230       
     231        fFirstEntry = 1; // Skip fake directory entry
     232        fCurrentEntry = 1;
    198233        status = Init();
    199234        if (status != B_OK)
    200235            return status;
    201236
    202237        fHasCollision = fParent->HasCollision();
    203238    }
     239
     240    CachedBlock cached(fVolume);
     241    const uint8* block = cached.SetTo(fBlockNum);
     242    if (block == NULL)
     243        return B_IO_ERROR;
     244
     245    HTreeEntry* entry = &((HTreeEntry*)block)[fCurrentEntry];
     246
     247    if (!endOfBlock)
     248        fHasCollision = (entry[fCurrentEntry].Hash() & 1) == 1;
    204249   
    205     HTreeEntry entry;
    206     status_t status = fDirectory->ReadAt(fOffset, (uint8*)&entry, &entrySize);
    207     if (status != B_OK)
    208         return status;
    209     else if (entrySize != sizeof(entry)) {
    210         // Weird error, try to skip it
    211         return GetNext(childOffset);
    212     }
     250    TRACE("HTreeEntryIterator::GetNext(): next block: %lu\n",
     251        entry->Block());
     252
     253    childBlock = entry->Block();
    213254   
    214     if (!firstEntry)
    215         fHasCollision = (entry.Hash() & 1) == 1;
    216    
    217     childOffset = entry.Block() * fBlockSize;
    218    
    219255    return B_OK;
    220256}
  • src/add-ons/kernel/file_systems/ext2/Volume.cpp

     
    1515#include <stdlib.h>
    1616#include <string.h>
    1717
     18#include <util/AutoLock.h>
     19
    1820#include <fs_cache.h>
    1921#include <fs_volume.h>
    2022
    21 #include <util/AutoLock.h>
    22 
    2323#include "Inode.h"
    2424
    2525
     
    220220
    221221Volume::~Volume()
    222222{
     223    TRACE("Volume destructor.\n");
    223224    if (fGroupBlocks != NULL) {
    224225        uint32 blockCount = (fNumGroups + fGroupsPerBlock - 1)
    225226            / fGroupsPerBlock;
     
    254255{
    255256    flags |= B_MOUNT_READ_ONLY;
    256257        // we only support read-only for now
     258   
     259    if ((flags & B_MOUNT_READ_ONLY) != 0) {
     260        TRACE("Volume::Mount(): Read only\n");
     261    } else {
     262        TRACE("Volume::Mount(): Read write\n");
     263    }
    257264
    258265    DeviceOpener opener(deviceName, (flags & B_MOUNT_READ_ONLY) != 0
    259266        ? O_RDONLY : O_RDWR);
     
    278285    fBlockSize = 1UL << fSuperBlock.BlockShift();
    279286    fFirstDataBlock = fSuperBlock.FirstDataBlock();
    280287
     288    fFreeBlocks = fSuperBlock.FreeBlocks();
     289
     290    uint32 numBlocks = fSuperBlock.NumBlocks() - fFirstDataBlock;
     291    uint32 blocksPerGroup = fSuperBlock.BlocksPerGroup();
     292    fNumGroups = numBlocks / blocksPerGroup;
     293    if (numBlocks % blocksPerGroup != 0)
     294        fNumGroups++;
     295
     296    fGroupsPerBlock = fBlockSize / sizeof(ext2_block_group);
    281297    fNumInodes = fSuperBlock.NumInodes();
    282     fNumGroups = (fSuperBlock.NumBlocks() - fFirstDataBlock - 1)
    283         / fSuperBlock.BlocksPerGroup() + 1;
    284     fGroupsPerBlock = fBlockSize / sizeof(ext2_block_group);
    285298
    286299    TRACE("block size %ld, num groups %ld, groups per block %ld, first %lu\n",
    287300        fBlockSize, fNumGroups, fGroupsPerBlock, fFirstDataBlock);
     
    309322    fBlockCache = opener.InitCache(NumBlocks(), fBlockSize);
    310323    if (fBlockCache == NULL)
    311324        return B_ERROR;
     325   
     326    TRACE("Volume::Mount(): Initialized block cache: %p\n", fBlockCache);
    312327
     328    // ready
    313329    status = get_vnode(fFSVolume, EXT2_ROOT_NODE, (void**)&fRootNode);
    314330    if (status != B_OK) {
    315331        TRACE("could not create root node: get_vnode() failed!\n");
     
    342358status_t
    343359Volume::Unmount()
    344360{
     361    TRACE("Volume::Unmount()\n");
     362
     363    TRACE("Volume::Unmount(): Putting root node\n");
    345364    put_vnode(fFSVolume, RootNode()->ID());
     365    TRACE("Volume::Unmount(): Deleting the block cache\n");
    346366    block_cache_delete(fBlockCache, !IsReadOnly());
     367    TRACE("Volume::Unmount(): Closing device\n");
    347368    close(fDevice);
    348369
     370    TRACE("Volume::Unmount(): Done\n");
    349371    return B_OK;
    350372}
    351373
     
    459481    return _UnsupportedIncompatibleFeatures(*superBlock) == 0
    460482        ? B_OK : B_NOT_SUPPORTED;
    461483}
    462 
  • src/add-ons/kernel/file_systems/ext2/HTree.cpp

     
    77 */
    88
    99
     10#include "CachedBlock.h"
    1011#include "HTree.h"
    1112
    1213#include <new>
     
    1718#include "Volume.h"
    1819
    1920
     21//#define COLLISION_TEST
     22
    2023//#define TRACE_EXT2
    2124#ifdef TRACE_EXT2
    2225#   define TRACE(x...) dprintf("\33[34mext2:\33[0m " x)
     
    7578
    7679HTree::~HTree()
    7780{
     81    delete fRootEntry;
    7882}
    7983
    8084
    8185status_t
    8286HTree::Lookup(const char* name, DirectoryIterator** iterator)
    8387{
     88    TRACE("HTree::Lookup()\n");
    8489    if (!fIndexed || (name[0] == '.'
    8590        && (name[1] == '\0' || (name[1] == '.' && name[2] == '0')))) {
    8691        // No HTree support or looking for trivial directories
    8792        // TODO: Does these directories get hashed?
    8893        *iterator = new(std::nothrow) DirectoryIterator(fDirectory);
     94        TRACE("HTree::Lookup(): Falling back to linear iteration\n");
    8995       
    9096        if (*iterator == NULL)
    9197            return B_NO_MEMORY;
    9298        return B_OK;
    9399    }
    94100   
    95     HTreeRoot root;
    96     size_t length = sizeof(root);
     101    uint32 blockNum;
     102    status_t status = fDirectory->FindBlock(0, blockNum);
     103    if (status != B_OK) {
     104        *iterator = new(std::nothrow) DirectoryIterator(fDirectory);
     105        TRACE("HTree::Lookup(): Failed to read block in diretory\n");
     106       
     107        if (*iterator == NULL)
     108            return B_NO_MEMORY;
     109        return B_OK;
     110    }
     111
     112    CachedBlock cached(fDirectory->GetVolume());
     113    const uint8* block = cached.SetTo(blockNum);
     114
     115    HTreeRoot* root = (HTreeRoot*)block;
    97116   
    98     status_t status = fDirectory->ReadAt(0, (uint8*)&root, &length);
    99     if (status < B_OK)
    100         return status;
    101    
    102     if (length != sizeof(root) || !root.IsValid()) {
     117    if (root == NULL || !root->IsValid()) {
    103118        // Fallback to linear search
    104119        *iterator = new(std::nothrow) DirectoryIterator(fDirectory);
     120        TRACE("HTree::Lookup(): Invalid root node\n");
    105121        if (*iterator == NULL)
    106122            return B_NO_MEMORY;
    107123       
    108124        return B_OK;
    109125    }
    110126   
    111     uint32 hash = _Hash(name, root.hash_version);
     127    uint32 hash = _Hash(name, root->hash_version);
    112128   
    113     off_t start = (off_t)root.root_info_length
     129    off_t start = (off_t)root->root_info_length
    114130        + 2 * (sizeof(HTreeFakeDirEntry) + 4);
    115131
     132    delete fRootEntry;
     133
    116134    fRootEntry = new(std::nothrow) HTreeEntryIterator(start, fDirectory);
    117135    if (fRootEntry == NULL)
    118136        return B_NO_MEMORY;
    119137   
    120     fRootDeleter.SetTo(fRootEntry);
    121138    status = fRootEntry->Init();
    122139    if (status != B_OK)
    123140        return status;
    124141   
    125     return fRootEntry->Lookup(hash, (uint32)root.indirection_levels, iterator);
     142    return fRootEntry->Lookup(hash, (uint32)root->indirection_levels, iterator);
    126143}
    127144
    128145
     
    131148{
    132149    uint32 hash;
    133150   
     151#ifndef COLLISION_TEST
    134152    switch (version) {
    135153        case HTREE_HASH_LEGACY:
    136154            hash = _HashLegacy(name);
     
    145163            panic("Hash verification succeeded but then failed?");
    146164            hash = 0;
    147165    };
     166#else
     167    hash = 0;
     168#endif
    148169
    149     TRACE("Filename hash: %u\n", hash);
     170    TRACE("HTree::_Hash(): filename hash 0x%lX\n", hash);
    150171   
    151172    return hash & ~1;
    152173}
     
    155176uint32
    156177HTree::_HashLegacy(const char* name)
    157178{
     179    TRACE("HTree::_HashLegacy()\n");
    158180    uint32 hash = 0x12a3fe2d;
    159181    uint32 previous = 0x37abe8f9;
    160182   
     
    168190        hash = next;
    169191    }
    170192   
    171     return hash;
     193    return hash << 1;
    172194}
    173195
    174196
     
    230252    shifts[2] = 9;
    231253    shifts[3] = 13;
    232254
    233     for (int j = 0; j < 2; ++j) {
    234         for (int i = j; i < 4; i += 2) {
     255    for (int j = 1; j >= 0; --j) {
     256        for (int i = j; i < 8; i += 2) {
    235257            a += _MD4G(b, c, d) + blocks[i] + 013240474631UL;
    236258            uint32 shift = shifts[i / 2];
    237259            a = (a << shift) | (a >> (32 - shift));
     
    247269
    248270    for (int i = 0; i < 4; ++i) {
    249271        a += _MD4H(b, c, d) + blocks[3 - i] + 015666365641UL;
    250         uint32 shift = shifts[i*2];
     272        uint32 shift = shifts[i * 2 % 4];
    251273        a = (a << shift) | (a >> (32 - shift));
    252274       
    253275        _MD4RotateVars(a, b, c, d);
    254276       
    255277        a += _MD4H(b, c, d) + blocks[7 - i] + 015666365641UL;
    256         shift = shifts[i*2 + 1];
     278        shift = shifts[(i * 2 + 1) % 4];
    257279        a = (a << shift) | (a >> (32 - shift));
    258280       
    259281        _MD4RotateVars(a, b, c, d);
     
    269291uint32
    270292HTree::_HashHalfMD4(const char* name)
    271293{
     294    TRACE("HTree::_HashHalfMD4()\n");
    272295    uint32 buffer[4];
    273296
    274297    buffer[0] = fHashSeed[0];
     
    318341uint32
    319342HTree::_HashTEA(const char* name)
    320343{
     344    TRACE("HTree::_HashTEA()\n");
    321345    uint32 buffer[4];
    322346
    323347    buffer[0] = fHashSeed[0];
     
    354378    int completeIterations = length / 4;
    355379   
    356380    for (int i = 0; i < completeIterations; ++i) {
    357         uint32 value = 0 | *(string++);
     381        uint32 value = (padding << 8) | *(string++);
    358382        value = (value << 8) | *(string++);
    359383        value = (value << 8) | *(string++);
    360384        value = (value << 8) | *(string++);
  • src/add-ons/kernel/file_systems/ext2/HTreeEntryIterator.h

    Property changes on: src/add-ons/kernel/file_systems/ext2/HTree.cpp
    ___________________________________________________________________
    Added: svn:executable
       + *
    
     
    1414#include "DirectoryIterator.h"
    1515
    1616
     17class Volume;
     18
     19
    1720class HTreeEntryIterator {
    1821public:
    1922                                HTreeEntryIterator(off_t offset,
     
    2629                                    DirectoryIterator** iterator);
    2730            bool                HasCollision() { return fHasCollision; }
    2831                       
    29             status_t            GetNext(off_t& offset);
     32            status_t            GetNext(uint32& offset);
    3033private:
    3134                                HTreeEntryIterator(uint32 block,
    3235                                    uint32 blockSize, Inode* directory,
     
    3437                                    bool hasCollision);
    3538
    3639private:
     40            Inode*              fDirectory;
     41            Volume*             fVolume;
     42            status_t            fInitStatus;
     43
    3744            bool                fHasCollision;
    3845            uint16              fLimit, fCount;
     46            uint16              fFirstEntry;
     47            uint16              fCurrentEntry;
    3948
    4049            uint32              fBlockSize;
    41             Inode*              fDirectory;
    42             off_t               fOffset;
    43             off_t               fMaxOffset;
     50            uint32              fBlockNum;
    4451
    4552            HTreeEntryIterator* fParent;
    4653            HTreeEntryIterator* fChild;
    47             ObjectDeleter<HTreeEntryIterator> fChildDeleter;
    4854};
    4955
    5056#endif  // HTREE_ENTRY_ITERATOR_H
  • src/add-ons/kernel/file_systems/ext2/HTree.h

     
    99#define HTREE_H
    1010
    1111
    12 #include <AutoDeleter.h>
    13 
    1412#include "ext2.h"
    1513#include "DirectoryIterator.h"
    1614#include "HTreeEntryIterator.h"
     
    127125            Inode*              fDirectory;
    128126            uint32              fHashSeed[4];
    129127            HTreeEntryIterator* fRootEntry;
    130             ObjectDeleter<HTreeEntryIterator> fRootDeleter;
    131128};
    132129
    133130#endif  // HTREE_H
  • src/add-ons/kernel/file_systems/ext2/Volume.h

    Property changes on: src/add-ons/kernel/file_systems/ext2/HTree.h
    ___________________________________________________________________
    Added: svn:executable
       + *
    
     
    4040
    4141            uint32              NumInodes() const
    4242                                    { return fNumInodes; }
     43            uint32              NumGroups() const
     44                                    { return fNumGroups; }
    4345            off_t               NumBlocks() const
    4446                                    { return fSuperBlock.NumBlocks(); }
    4547            off_t               FreeBlocks() const
    46                                     { return fSuperBlock.FreeBlocks(); }
     48                                    { return fFreeBlocks; }
     49            uint32              FirstDataBlock() const
     50                                    { return fFirstDataBlock; }
    4751
    4852            uint32              BlockSize() const { return fBlockSize; }
    4953            uint32              BlockShift() const { return fBlockShift; }
     54            uint32              BlocksPerGroup() const
     55                                    { return fSuperBlock.BlocksPerGroup(); }
    5056            uint32              InodeSize() const
    5157                                    { return fSuperBlock.InodeSize(); }
     58            uint32              InodesPerGroup() const
     59                                    { return fSuperBlock.InodesPerGroup(); }
    5260            ext2_super_block&   SuperBlock() { return fSuperBlock; }
    5361
    5462            status_t            GetInodeBlock(ino_t id, uint32& block);
    5563            uint32              InodeBlockIndex(ino_t id) const;
    5664            status_t            GetBlockGroup(int32 index,
    5765                                    ext2_block_group** _group);
    58            
     66
    5967            bool                IndexedDirectories() const
    6068                                    { return (fSuperBlock.CompatibleFeatures()
    6169                                        & EXT2_FEATURE_DIRECTORY_INDEX) != 0; }
     
    7684            int                 fDevice;
    7785            ext2_super_block    fSuperBlock;
    7886            char                fName[32];
     87
    7988            uint32              fFlags;
    8089            uint32              fBlockSize;
    8190            uint32              fBlockShift;
    8291            uint32              fFirstDataBlock;
     92
    8393            uint32              fNumInodes;
    8494            uint32              fNumGroups;
     95            uint32              fFreeBlocks;
    8596            uint32              fGroupsPerBlock;
    8697            ext2_block_group**  fGroupBlocks;
    8798            uint32              fInodesPerBlock;
  • src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp

     
    88
    99#include <string.h>
    1010
     11#include "CachedBlock.h"
    1112#include "HTree.h"
    1213#include "Inode.h"
    1314
     
    2324DirectoryIterator::DirectoryIterator(Inode* inode)
    2425    :
    2526    fInode(inode),
    26     fOffset(0)
     27    fLogicalBlock(0),
     28    fDisplacement(0),
     29    fBlockSize(inode->GetVolume()->BlockSize())
    2730{
     31    fInitStatus = fInode->FindBlock(0, fPhysicalBlock);
    2832}
    2933
    3034
     
    3438
    3539
    3640status_t
     41DirectoryIterator::InitCheck()
     42{
     43    return fInitStatus;
     44}
     45
     46
     47status_t
    3748DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id)
    3849{
    39     if (fOffset + sizeof(ext2_dir_entry) >= fInode->Size()) {
     50    if (fLogicalBlock * fBlockSize + fDisplacement
     51            + ext2_dir_entry::MinimumSize() >= fInode->Size()) {
    4052        TRACE("DirectoryIterator::GetNext() out of entries\n");
    4153        return B_ENTRY_NOT_FOUND;
    4254    }
    4355
    44     ext2_dir_entry entry;
     56    CachedBlock cached(fInode->GetVolume());
     57    ext2_dir_entry* entry;
    4558
    46     while (true) {
    47         size_t length = ext2_dir_entry::MinimumSize();
    48         status_t status = fInode->ReadAt(fOffset, (uint8*)&entry, &length);
    49         if (status != B_OK)
    50             return status;
    51         if (length < ext2_dir_entry::MinimumSize() || entry.Length() == 0)
     59    const uint8* block = cached.SetTo(fPhysicalBlock);
     60    if (block == NULL)
     61        return B_IO_ERROR;
     62
     63    bool gotEntry = false;
     64    while (!gotEntry) {
     65        TRACE("Checking entry at block %lu, displacement %lu\n", fPhysicalBlock,
     66            fDisplacement);
     67
     68        entry = (ext2_dir_entry*)(block + fDisplacement);
     69
     70        if (entry->Length() == 0) {
     71            TRACE("empty entry.\n");
    5272            return B_ENTRY_NOT_FOUND;
    53         if (!entry.IsValid())
     73        }
     74        if (!entry->IsValid()) {
     75            TRACE("invalid entry.\n");
    5476            return B_BAD_DATA;
     77        }
    5578
    56         if (entry.NameLength() != 0)
    57             break;
     79        if (entry->NameLength() != 0) {
     80            // Get name
     81            gotEntry = true;
    5882
    59         fOffset += entry.Length();
    60         TRACE("DirectoryIterator::GetNext() skipping entry\n");
    61     }
     83            size_t length = entry->NameLength();
    6284
    63     TRACE("offset %Ld: entry ino %lu, length %u, name length %u, type %u\n",
    64         fOffset, entry.InodeID(), entry.Length(), entry.NameLength(),
    65         entry.FileType());
     85            TRACE("block %lu, displacement %lu: entry ino %lu, length %u, "
     86                "name length %lu, type %lu\n", fLogicalBlock, fDisplacement,
     87                entry->InodeID(), entry->Length(), (uint32)length,
     88                (uint32)entry->FileType());
    6689
    67     // read name
     90            if (*_nameLength < length)
     91                length = *_nameLength - 1;
     92            memcpy(name, entry->name, length);
     93            name[length] = '\0';
    6894
    69     size_t length = entry.NameLength();
    70     status_t status = fInode->ReadAt(fOffset + ext2_dir_entry::MinimumSize(),
    71         (uint8*)entry.name, &length);
    72     if (status == B_OK) {
    73         if (*_nameLength < length)
    74             length = *_nameLength - 1;
    75         memcpy(name, entry.name, length);
    76         name[length] = '\0';
     95            *_id = entry->InodeID();
     96            *_nameLength = length;
     97        }
    7798
    78         *_id = entry.InodeID();
    79         *_nameLength = length;
     99        fDisplacement += entry->Length();
    80100
    81         fOffset += entry.Length();
     101        if (fDisplacement == fBlockSize) {
     102            TRACE("Reached end of block\n");
     103
     104            fDisplacement = 0;
     105            fLogicalBlock++;
     106           
     107            if (fLogicalBlock * fBlockSize + ext2_dir_entry::MinimumSize()
     108                    < fInode->Size()) {
     109                status_t status = fInode->FindBlock(fLogicalBlock * fBlockSize,
     110                    fPhysicalBlock);
     111                if (status != B_OK)
     112                    return status;
     113            } else if (!gotEntry) {
     114                TRACE("DirectoryIterator::GetNext() end of directory file\n");
     115                return B_ENTRY_NOT_FOUND;
     116            }
     117
     118            if (!gotEntry) {
     119                block = cached.SetTo(fPhysicalBlock);
     120                if (block == NULL)
     121                    return B_IO_ERROR;
     122            }
     123        } else if (fDisplacement > fBlockSize && !gotEntry) {
     124            TRACE("The entry isn't block aligned.\n");
     125            // TODO: Is block alignment obligatory?
     126            return B_BAD_DATA;
     127        }
     128
     129        TRACE("DirectoryIterator::GetNext() skipping entry\n");
    82130    }
    83131
    84     return status;
     132    return B_OK;
    85133}
    86134
    87135
    88136status_t
    89137DirectoryIterator::Rewind()
    90138{
    91     fOffset = 0;
    92     return B_OK;
     139    fDisplacement = 0;
     140    fLogicalBlock = 0;
     141
     142    return fInode->FindBlock(0, fPhysicalBlock);
    93143}
  • src/add-ons/kernel/file_systems/ext2/IndexedDirectoryIterator.cpp

     
    1515#include "Inode.h"
    1616
    1717
     18//#define COLLISION_TEST
     19
    1820//#define TRACE_EXT2
    1921#ifdef TRACE_EXT2
    2022#   define TRACE(x...) dprintf("\33[34mext2:\33[0m " x)
     
    2426
    2527
    2628IndexedDirectoryIterator::IndexedDirectoryIterator(off_t start,
    27     uint32 blockSize, Inode* directory, HTreeEntryIterator* parent)
     29    Inode* directory, HTreeEntryIterator* parent)
    2830    :
    2931    DirectoryIterator(directory),
    3032    fIndexing(true),
    31    
    3233    fParent(parent),
    33     fMaxOffset(start + blockSize),
    34     fBlockSize(blockSize),
    35     fMaxAttempts(0)
     34    fPreviousBlock(start / fBlockSize)
    3635{
    37     fOffset = start;
     36    fDisplacement = start % fBlockSize;
     37    fLogicalBlock = fPreviousBlock;
     38
     39    fInitStatus = fInode->FindBlock(fLogicalBlock * fBlockSize, fPhysicalBlock);
    3840}
    3941
    4042
     
    4648status_t
    4749IndexedDirectoryIterator::GetNext(char* name, size_t* nameLength, ino_t* id)
    4850{
    49     if (fIndexing && fOffset + sizeof(HTreeFakeDirEntry) >= fMaxOffset) {
     51    TRACE("IndexedDirectoryIterator::GetNext()\n");
     52    if (fIndexing && fLogicalBlock != fPreviousBlock) {
    5053        TRACE("IndexedDirectoryIterator::GetNext() calling next block\n");
    51         status_t status = fParent->GetNext(fOffset);
     54
     55        if (!fParent->HasCollision()) {
     56            TRACE("IndexedDirectoryIterator::GetNext(): next block doesn't "
     57                "contain collisions from previous block\n");
     58#ifndef COLLISION_TEST
     59            return B_ENTRY_NOT_FOUND;
     60#endif
     61        }
     62
     63        fDisplacement = 0;
     64        status_t status = fParent->GetNext(fLogicalBlock);
    5265        if (status != B_OK)
    5366            return status;
    5467
    55         if (fMaxAttempts++ > 4)
    56             return B_ERROR;
    57        
    58         fMaxOffset = fOffset + fBlockSize;
     68        fPreviousBlock = fLogicalBlock;
     69        status = fInode->FindBlock(fLogicalBlock * fBlockSize, fPhysicalBlock);
     70        if (status != B_OK)
     71            return status;
    5972    }
    6073   
    6174    return DirectoryIterator::GetNext(name, nameLength, id);
     
    6780{
    6881    // The only way to rewind it is too loose indexing
    6982   
    70     fOffset = 0;
    71     fMaxOffset = fInode->Size();
     83    fLogicalBlock = 0;
     84    fPreviousBlock = 0;
     85    fDisplacement = 0;
    7286    fIndexing = false;
    7387
    74     return B_OK;
     88    return fInode->FindBlock(fLogicalBlock, fPhysicalBlock);
    7589}
  • src/add-ons/kernel/file_systems/ext2/DirectoryIterator.h

     
    1616                        DirectoryIterator(Inode* inode);
    1717    virtual             ~DirectoryIterator();
    1818
     19    virtual status_t    InitCheck();
     20
    1921    virtual status_t    GetNext(char* name, size_t* _nameLength, ino_t* id);
    2022
    2123    virtual status_t    Rewind();
     
    2729
    2830protected:
    2931    Inode*              fInode;
    30     off_t               fOffset;
     32    uint32              fLogicalBlock;
     33    uint32              fPhysicalBlock;
     34    uint32              fDisplacement;
     35    uint32              fBlockSize;
     36    status_t            fInitStatus;
    3137};
    3238
    3339#endif  // DIRECTORY_ITERATOR_H
     40
  • src/add-ons/kernel/file_systems/ext2/IndexedDirectoryIterator.h

     
    1717class IndexedDirectoryIterator : public DirectoryIterator {
    1818public:
    1919                                IndexedDirectoryIterator(off_t start,
    20                                     uint32 blockSize, Inode* directory,
     20                                    Inode* directory,
    2121                                    HTreeEntryIterator* parent);
    2222    virtual                     ~IndexedDirectoryIterator();
    2323   
     
    2525                                    ino_t* id);
    2626           
    2727            status_t            Rewind();
     28
    2829private:
    2930            bool                fIndexing;
    3031            HTreeEntryIterator* fParent;
    31             off_t               fMaxOffset;
    32             uint32              fBlockSize;
    33             uint32              fMaxAttempts;
     32            uint32              fPreviousBlock;
    3433};
    3534
    3635#endif  // INDEXED_DIRECTORY_ITERATOR_H
  • src/add-ons/kernel/file_systems/ext2/ext2.h

     
    1313#include <KernelExport.h>
    1414
    1515
     16#define TRACE_EXT2
     17
    1618#define EXT2_SUPER_BLOCK_OFFSET 1024
    1719
    1820struct ext2_super_block {
     
    108110        { return B_LENDIAN_TO_HOST_INT32(read_only_features); }
    109111    uint32 IncompatibleFeatures() const
    110112        { return B_LENDIAN_TO_HOST_INT32(incompatible_features); }
     113    ino_t  JournalInode() const
     114        { return B_LENDIAN_TO_HOST_INT32(journal_inode); }
    111115    uint32 HashSeed(uint8 i) const
    112116        { return B_LENDIAN_TO_HOST_INT32(hash_seed[i]); }
    113117
     
    162166    uint16  _padding;
    163167    uint32  _reserved[3];
    164168
     169    uint32 BlockBitmap() const
     170        { return B_LENDIAN_TO_HOST_INT32(block_bitmap); }
     171    uint32 InodeBitmap() const
     172        { return B_LENDIAN_TO_HOST_INT32(inode_bitmap); }
    165173    uint32 InodeTable() const
    166174        { return B_LENDIAN_TO_HOST_INT32(inode_table); }
     175    uint16 FreeBlocks() const
     176        { return B_LENDIAN_TO_HOST_INT16(free_blocks); }
     177    uint16 FreeInodes() const
     178        { return B_LENDIAN_TO_HOST_INT16(free_inodes); }
    167179} _PACKED;
    168180
    169181#define EXT2_DIRECT_BLOCKS          12
     
    214226    uint16 Mode() const { return B_LENDIAN_TO_HOST_INT16(mode); }
    215227    uint32 Flags() const { return B_LENDIAN_TO_HOST_INT32(flags); }
    216228    uint16 NumLinks() const { return B_LENDIAN_TO_HOST_INT16(num_links); }
     229    uint32 NumBlocks() const { return B_LENDIAN_TO_HOST_INT32(num_blocks); }
    217230
    218231    time_t AccessTime() const { return B_LENDIAN_TO_HOST_INT32(access_time); }
    219232    time_t CreationTime() const { return B_LENDIAN_TO_HOST_INT32(creation_time); }
     
    270283    uint8   file_type;
    271284    char    name[EXT2_NAME_LENGTH];
    272285
    273     uint32 InodeID() const { return B_LENDIAN_TO_HOST_INT32(inode_id); }
    274     uint16 Length() const { return B_LENDIAN_TO_HOST_INT16(length); }
    275     uint8 NameLength() const { return name_length; }
    276     uint8 FileType() const { return file_type; }
     286    uint32  InodeID() const { return B_LENDIAN_TO_HOST_INT32(inode_id); }
     287    uint16  Length() const { return B_LENDIAN_TO_HOST_INT16(length); }
     288    uint8   NameLength() const { return name_length; }
     289    uint8   FileType() const { return file_type; }
    277290
    278291    bool IsValid() const
    279292    {
  • src/add-ons/kernel/file_systems/ext2/CachedBlock.h

     
    1414
    1515class CachedBlock {
    1616public:
    17                     CachedBlock(Volume* volume);
    18                     CachedBlock(Volume* volume, uint32 block);
    19                     ~CachedBlock();
     17                            CachedBlock(Volume* volume);
     18                            CachedBlock(Volume* volume, uint32 block);
     19                            ~CachedBlock();
    2020
    21             void    Keep();
    22             void    Unset();
     21            void            Keep();
     22            void            Unset();
    2323
    24     const   uint8*  SetTo(uint32 block);
     24            const uint8*    SetTo(uint32 block);
    2525
    26     const   uint8*  Block() const { return fBlock; }
    27             off_t   BlockNumber() const { return fBlockNumber; }
     26            const uint8*    Block() const { return fBlock; }
     27            off_t           BlockNumber() const { return fBlockNumber; }
    2828
    2929private:
    30                     CachedBlock(const CachedBlock &);
    31                     CachedBlock &operator=(const CachedBlock &);
    32                         // no implementation
    33 
     30                            CachedBlock(const CachedBlock &);
     31                            CachedBlock &operator=(const CachedBlock &);
     32                                // no implementation
     33                       
    3434protected:
    35     Volume*         fVolume;
    36     uint32          fBlockNumber;
    37     uint8*          fBlock;
     35            Volume*         fVolume;
     36            uint32          fBlockNumber;
     37            uint8*          fBlock;
    3838};
    3939
    4040
     
    9494    return fBlock = (uint8 *)block_cache_get(fVolume->BlockCache(), block);
    9595}
    9696
     97
    9798#endif  // CACHED_BLOCK_H