Exemplo n.º 1
0
// _VerifyHashFunction
bool
Volume::_VerifyHashFunction(hash_function_t function)
{
	bool result = true;
	// iterate over the entries in the root dir until we find an entry, that
	// doesn't falsify the hash function
	DirEntryIterator iterator(fTree, fRootVNode->GetDirID(),
							  fRootVNode->GetObjectID(), DOT_DOT_OFFSET + 1);
	DirItem item;
	int32 index = 0;
	while (iterator.GetNext(&item, &index) == B_OK) {
		DirEntry *entry = item.EntryAt(index);
		uint64 offset = entry->GetOffset();
		// try the hash function
		size_t nameLen = 0;
		if (const char *name = item.EntryNameAt(index, &nameLen)) {
			uint64 testOffset = key_offset_for_name(function, name, nameLen);
			if (offset_hash_value(offset) != offset_hash_value(testOffset)) {
				result = false;
				break;
			}
		} // else: bad data
	}
	return result;
}
Exemplo n.º 2
0
/*!	\brief Searches an entry in a directory.

	\note Must not be called with \a entryName "." or ".."!

	\param dir The directory.
	\param entryName Name of the entry.
	\param foundNode pointer to a pre-allocated VNode to be initialized to
		   the found entry.
	\param failIfHidden The method shall fail, if the entry is hidden.
	\return \c B_OK, if everything went fine.
*/
status_t
Volume::FindDirEntry(VNode *dir, const char *entryName, VNode *foundNode,
					 bool failIfHidden)
{
	status_t error = (dir && foundNode ? B_OK : B_BAD_VALUE);
	// find the DirEntry
	DirItem item;
	int32 entryIndex = 0;
	if (error == B_OK) {
		error = fTree->FindDirEntry(dir->GetDirID(), dir->GetObjectID(),
									entryName, &item, &entryIndex);
	}
	// find the child node
	if (error == B_OK) {
		DirEntry *entry = item.EntryAt(entryIndex);
		error = FindVNode(entry->GetDirID(), entry->GetObjectID(), foundNode);
		if (error == B_OK && failIfHidden && entry->IsHidden())
			error = B_ENTRY_NOT_FOUND;
	}
	return error;
}
Exemplo n.º 3
0
// _DetectHashFunction
uint32
Volume::_DetectHashFunction()
{
	// iterate over the entries in the root dir until we find an entry, that
	// let us draw an unambiguous conclusion
	DirEntryIterator iterator(fTree, fRootVNode->GetDirID(),
							  fRootVNode->GetObjectID(), DOT_DOT_OFFSET + 1);
	uint32 foundCode = UNSET_HASH;
	DirItem item;
	int32 index = 0;
	while (foundCode == UNSET_HASH
		   && iterator.GetNext(&item, &index) == B_OK) {
		DirEntry *entry = item.EntryAt(index);
		uint64 offset = entry->GetOffset();
		uint32 hashCodes[] = { TEA_HASH, YURA_HASH, R5_HASH };
		int32 hashCodeCount = sizeof(hashCodes) / sizeof(uint32);
		size_t nameLen = 0;
		const char *name = item.EntryNameAt(index, &nameLen);
		if (!name)	// bad data!
			continue;
		// try each hash function -- if there's a single winner, we're done,
		// otherwise the next entry must help
		for (int32 i = 0; i < hashCodeCount; i++) {
			hash_function_t function = hash_function_for_code(hashCodes[i]);
			uint64 testOffset = key_offset_for_name(function, name, nameLen);
			if (offset_hash_value(offset) == offset_hash_value(testOffset)) {
				if (foundCode != UNSET_HASH) {
					// ambiguous
					foundCode = UNSET_HASH;
					break;
				} else
					foundCode = hashCodes[i];
			}
		}
	}
	return foundCode;
}
Exemplo n.º 4
0
/*!	\brief Finds the node identified by a directory ID, object ID pair.

	\note The method does not initialize the parent ID for non-directory nodes.

	\param dirID Directory ID of the node to be found.
	\param objectID Object ID of the node to be found.
	\param node pointer to a pre-allocated VNode to be initialized to
		   the found node.
	\return \c B_OK, if everything went fine.
*/
status_t
Volume::FindVNode(uint32 dirID, uint32 objectID, VNode *node)
{
	// NOTE: The node's parent dir ID is not initialized!
	status_t error = (node ? B_OK : B_BAD_VALUE);
	// init the node
	if (error == B_OK)
		error = node->SetTo(dirID, objectID);
	// find the stat item
	StatItem item;
	if (error == B_OK) {
		error = fTree->FindStatItem(dirID, objectID, &item);
		if (error != B_OK) {
			FATAL(("Couldn't find stat item for node (%lu, %lu)\n",
				   dirID, objectID));
		}
	}
	// get the stat data
	if (error == B_OK)
		SET_ERROR(error, item.GetStatData(node->GetStatData(), true));
	// for dirs get the ".." entry, since we need the parent dir ID
	if (error == B_OK && node->IsDir()) {
		DirItem dirItem;
		int32 index = 0;
		error = fTree->FindDirEntry(dirID, objectID, "..", &dirItem, &index);
		if (error == B_OK) {
			DirEntry *entry = dirItem.EntryAt(index);
			node->SetParentID(entry->GetDirID(), entry->GetObjectID());
		}
		else {
			FATAL(("failed to find `..' entry for dir node (%lu, %ld)\n",
				   dirID, objectID));
		}
	}
	return error;
}