// GetNode status_t Tree::GetNode(uint64 blockNumber, Node **node) { status_t error = (node ? InitCheck() : B_BAD_VALUE); if (error == B_OK) { Block *block; error = fBlockCache->GetBlock(blockNumber, &block); if (error == B_OK) { if (block->GetKind() == Block::KIND_UNKNOWN) block->SetKind(Block::KIND_FORMATTED); if (block->GetKind() == Block::KIND_FORMATTED) { *node = block->ToNode(); // check the node if (!(*node)->IsChecked()) { if ((*node)->IsInternal()) error = (*node)->ToInternalNode()->Check(); else if ((*node)->IsLeaf()) error = (*node)->ToLeafNode()->Check(); else error = B_BAD_DATA; if (error == B_OK) (*node)->SetChecked(true); } } else { block->Put(); error = B_BAD_DATA; } } } return error; }
status_t Volume::Initialize(const char* name) { fName = strdup(name); if (fName == NULL) return B_NO_MEMORY; status_t error = fBlockAllocator->Initialize(); if (error != B_OK) return error; // create the root directory error = CreateDirectory(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, fRootDirectory); if (error != B_OK) return error; error = fRootDirectory->Flush(); if (error != B_OK) return error; // write the super block Block block; if (!block.GetZero(this, kCheckSumFSSuperBlockOffset / B_PAGE_SIZE)) return B_ERROR; SuperBlock* superBlock = (SuperBlock*)block.Data(); superBlock->Initialize(this); block.Put(); return block_cache_sync(fBlockCache); }
// _ReadIndirectItem status_t StreamReader::_ReadIndirectItem(off_t offset, void *buffer, size_t bufferSize) { //PRINT(("StreamReader::_ReadIndirectItem(%Ld, %p, %lu)\n", offset, buffer, bufferSize)); status_t error = B_OK; IndirectItem &indirect = *static_cast<IndirectItem*>(&fItem); // skip items until the offset is reached uint32 skipItems = 0; if (offset > 0) { skipItems = uint32(offset / fBlockSize); skipItems = min(skipItems, indirect.CountBlocks()); // not necessary } //PRINT((" skipItems: %lu\n", skipItems)); for (uint32 i = skipItems; error == B_OK && bufferSize > 0 && i < indirect.CountBlocks(); i++) { //PRINT((" child %lu\n", i)); // get the block Block *block = NULL; error = GetTree()->GetBlock(indirect.BlockNumberAt(i), &block); if (error == B_OK) { // copy the data into the buffer off_t blockOffset = i * (off_t)fBlockSize; uint32 localOffset = max(0LL, offset - blockOffset); uint32 toRead = min(fBlockSize - localOffset, bufferSize); memcpy(buffer, (uint8*)block->GetData() + localOffset, toRead); block->Put(); bufferSize -= toRead; buffer = (uint8*)buffer + toRead; } else { FATAL(("failed to get block %Lu\n", indirect.BlockNumberAt(i))); error = B_IO_ERROR; } } //PRINT(("StreamReader::_ReadIndirectItem() done: %s\n", strerror(error))) return error; }
// Mount status_t Volume::Mount(fs_volume *fsVolume, const char *path) { Unmount(); status_t error = (path ? B_OK : B_BAD_VALUE); fFSVolume = fsVolume; // load the settings if (error == B_OK) { fSettings = new(nothrow) Settings; if (fSettings) error = fSettings->SetTo(path); else error = B_NO_MEMORY; } // copy the device name if (error == B_OK) { fDeviceName = new(nothrow) char[strlen(path) + 1]; if (fDeviceName) strcpy(fDeviceName, path); else error = B_NO_MEMORY; } // open disk if (error == B_OK) { fDevice = open(path, O_RDONLY); if (fDevice < 0) SET_ERROR(error, errno); } // read and analyze super block if (error == B_OK) error = _ReadSuperBlock(); if (error == B_OK) UpdateName(fsVolume->partition); // create and init block cache if (error == B_OK) { fBlockCache = new(nothrow) BlockCache; if (fBlockCache) error = fBlockCache->Init(fDevice, CountBlocks(), GetBlockSize()); else error = B_NO_MEMORY; } // create the tree if (error == B_OK) { fTree = new(nothrow) Tree; if (!fTree) error = B_NO_MEMORY; } // get the root node and init the tree if (error == B_OK) { Block *rootBlock = NULL; error = fBlockCache->GetBlock(fSuperBlock->GetRootBlock(), &rootBlock); REPORT_ERROR(error); if (error == B_OK) { rootBlock->SetKind(Block::KIND_FORMATTED); error = fTree->Init(this, rootBlock->ToNode(), fSuperBlock->GetTreeHeight()); REPORT_ERROR(error); rootBlock->Put(); } } // get the root VNode (i.e. the root dir) if (error == B_OK) { fRootVNode = new(nothrow) VNode; if (fRootVNode) { error = FindVNode(REISERFS_ROOT_PARENT_OBJECTID, REISERFS_ROOT_OBJECTID, fRootVNode); REPORT_ERROR(error); if (error == B_OK) { error = publish_vnode(fFSVolume, fRootVNode->GetID(), fRootVNode, &gReiserFSVnodeOps, S_IFDIR, 0); } REPORT_ERROR(error); } else error = B_NO_MEMORY; } // init the hash function if (error == B_OK) _InitHashFunction(); // init the negative entry list if (error == B_OK) _InitNegativeEntries(); // cleanup on error if (error != B_OK) Unmount(); RETURN_ERROR(error); }