static status_t
udf_lookup(fs_volume *_volume, fs_vnode *_directory, const char *file,
	ino_t *vnodeID)
{
	TRACE(("udf_lookup: _directory = %p, filename = %s\n", _directory, file));

	Volume *volume = (Volume *)_volume->private_volume;
	Icb *dir = (Icb *)_directory->private_node;
	Icb *node = NULL;

	status_t status = B_OK;

	if (strcmp(file, ".") == 0) {
		TRACE(("udf_lookup: file = ./\n"));
		*vnodeID = dir->Id();
		status = get_vnode(volume->FSVolume(), *vnodeID, (void **)&node);
		if (status != B_OK)
			return B_ENTRY_NOT_FOUND;
	} else {
		status = dir->Find(file, vnodeID);
		if (status != B_OK)
			return status;

		Icb *icb;
		status = get_vnode(volume->FSVolume(), *vnodeID, (void **)&icb);
		if (status != B_OK)
			return B_ENTRY_NOT_FOUND;
	}
	TRACE(("udf_lookup: vnodeId = %Ld found!\n", *vnodeID));

	return B_OK;
}
Beispiel #2
0
static status_t
ext2_lookup(fs_volume* _volume, fs_vnode* _directory, const char* name,
	ino_t* _vnodeID)
{
	TRACE("ext2_lookup: name address: %p\n", name);
	TRACE("ext2_lookup: name: %s\n", name);
	Volume* volume = (Volume*)_volume->private_volume;
	Inode* directory = (Inode*)_directory->private_node;

	// check access permissions
	status_t status = directory->CheckPermissions(X_OK);
	if (status < B_OK)
		return status;

	HTree htree(volume, directory);
	DirectoryIterator* iterator;

	status = htree.Lookup(name, &iterator);
	if (status != B_OK)
		return status;

	ObjectDeleter<DirectoryIterator> iteratorDeleter(iterator);

	status = iterator->FindEntry(name, _vnodeID);
	if (status != B_OK)
		return status;

	return get_vnode(volume->FSVolume(), *_vnodeID, NULL);
}
Beispiel #3
0
static status_t
btrfs_lookup(fs_volume* _volume, fs_vnode* _directory, const char* name,
	ino_t* _vnodeID)
{
	TRACE("btrfs_lookup: name address: %p (%s)\n", name, name);
	Volume* volume = (Volume*)_volume->private_volume;
	Inode* directory = (Inode*)_directory->private_node;

	// check access permissions
	status_t status = directory->CheckPermissions(X_OK);
	if (status < B_OK)
		return status;

	status = DirectoryIterator(directory).Lookup(name, strlen(name), _vnodeID);
	if (status != B_OK)
		return status;
	
	return get_vnode(volume->FSVolume(), *_vnodeID, NULL);
}
Beispiel #4
0
static status_t
ext2_create_dir(fs_volume* _volume, fs_vnode* _directory, const char* name,
	int mode)
{
	TRACE("ext2_create_dir()\n");
	Volume* volume = (Volume*)_volume->private_volume;
	Inode* directory = (Inode*)_directory->private_node;

	if (volume->IsReadOnly())
		return B_READ_ONLY_DEVICE;

	if (!directory->IsDirectory())
		return B_BAD_TYPE;

	status_t status = directory->CheckPermissions(W_OK);
	if (status != B_OK)
		return status;

	TRACE("ext2_create_dir(): Starting transaction\n");
	Transaction transaction(volume->GetJournal());

	ino_t id;
	status = Inode::Create(transaction, directory, name,
		S_DIRECTORY | (mode & S_IUMSK), 0, EXT2_TYPE_DIRECTORY, NULL, &id);
	if (status != B_OK)
		return status;

	put_vnode(volume->FSVolume(), id);

	entry_cache_add(volume->ID(), directory->ID(), name, id);

	status = transaction.Done();
	if (status != B_OK) {
		entry_cache_remove(volume->ID(), directory->ID(), name);
		return status;
	}

	notify_entry_created(volume->ID(), directory->ID(), name, id);

	TRACE("ext2_create_dir(): Done\n");

	return B_OK;
}
Beispiel #5
0
static status_t
ext2_create_symlink(fs_volume* _volume, fs_vnode* _directory, const char* name,
	const char* path, int mode)
{
	TRACE("ext2_create_symlink()\n");

	Volume* volume = (Volume*)_volume->private_volume;
	Inode* directory = (Inode*)_directory->private_node;

	if (volume->IsReadOnly())
		return B_READ_ONLY_DEVICE;

	if (!directory->IsDirectory())
		return B_BAD_TYPE;

	status_t status = directory->CheckPermissions(W_OK);
	if (status != B_OK)
		return status;

	TRACE("ext2_create_symlink(): Starting transaction\n");
	Transaction transaction(volume->GetJournal());

	Inode* link;
	ino_t id;
	status = Inode::Create(transaction, directory, name, S_SYMLINK | 0777,
		0, (uint8)EXT2_TYPE_SYMLINK, NULL, &id, &link);
	if (status != B_OK)
		return status;

	// TODO: We have to prepare the link before publishing?

	size_t length = strlen(path);
	TRACE("ext2_create_symlink(): Path (%s) length: %d\n", path, (int)length);
	if (length < EXT2_SHORT_SYMLINK_LENGTH) {
		strcpy(link->Node().symlink, path);
		link->Node().SetSize((uint32)length);

		TRACE("ext2_create_symlink(): Publishing vnode\n");
		publish_vnode(volume->FSVolume(), id, link, &gExt2VnodeOps,
			link->Mode(), 0);
		put_vnode(volume->FSVolume(), id);
	} else {
		TRACE("ext2_create_symlink(): Publishing vnode\n");
		publish_vnode(volume->FSVolume(), id, link, &gExt2VnodeOps,
			link->Mode(), 0);
		put_vnode(volume->FSVolume(), id);

		if (!link->HasFileCache()) {
			status = link->CreateFileCache();
			if (status != B_OK)
				return status;
		}

		size_t written = length;
		status = link->WriteAt(transaction, 0, (const uint8*)path, &written);
		if (status == B_OK && written != length)
			status = B_IO_ERROR;
	}

	if (status == B_OK)
		status = link->WriteBack(transaction);

	entry_cache_add(volume->ID(), directory->ID(), name, id);

	status = transaction.Done();
	if (status != B_OK) {
		entry_cache_remove(volume->ID(), directory->ID(), name);
		return status;
	}

	notify_entry_created(volume->ID(), directory->ID(), name, id);

	TRACE("ext2_create_symlink(): Done\n");

	return status;
}