static status_t
udf_read_dir(fs_volume *_volume, fs_vnode *vnode, void *cookie,
	struct dirent *dirent, size_t bufferSize, uint32 *_num)
{
	TRACE(("udf_read_dir: _volume = %p, vnode = %p, bufferSize = %ld\n",
		_volume, vnode, bufferSize));

	if (!_volume || !vnode || !cookie || !_num
			|| bufferSize < sizeof(struct dirent)) {
		return B_BAD_VALUE;
	}

	Volume *volume = (Volume *)_volume->private_volume;
	Icb *dir = (Icb *)vnode->private_node;
	DirectoryIterator *iterator = (DirectoryIterator *)cookie;

	if (dir != iterator->Parent()) {
		TRACE_ERROR(("udf_read_dir: Icb does not match parent Icb of given "
			"DirectoryIterator! (iterator->Parent = %p)\n", iterator->Parent()));
		return B_BAD_VALUE;
	}

	uint32 nameLength = bufferSize - sizeof(struct dirent) + 1;
	ino_t id;
	status_t status = iterator->GetNextEntry(dirent->d_name, &nameLength, &id);
	if (!status) {
		TRACE(("udf_read_dir: dirent->d_name = %s, length = %ld\n", dirent->d_name, nameLength));
		*_num = 1;
		dirent->d_dev = volume->ID();
		dirent->d_ino = id;
		dirent->d_reclen = sizeof(struct dirent) + nameLength - 1;
	} else {
		*_num = 0;
		// Clear the status for end of directory
		if (status == B_ENTRY_NOT_FOUND)
			status = B_OK;
	}

	RETURN(status);
}
status_t
udf_rewind_dir(fs_volume *volume, fs_vnode *vnode, void *cookie)
{
	TRACE(("udf_rewind_dir: volume = %p, vnode = %p, cookie = %p\n",
		volume, vnode, cookie));

	if (!volume || !vnode || !cookie)
		RETURN(B_BAD_VALUE);

	Icb *dir = (Icb *)vnode->private_node;
	DirectoryIterator *iterator = (DirectoryIterator *)cookie;

	if (dir != iterator->Parent()) {
		PRINT(("udf_rewind_dir: icb does not match parent Icb of given "
			"DirectoryIterator! (iterator->Parent = %p)\n", iterator->Parent()));
		return B_BAD_VALUE;
	}

	iterator->Rewind();

	return B_OK;
}