Exemplo n.º 1
0
// 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;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
// _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;
}
Exemplo n.º 4
0
// 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);
}