packagefs: Add ioctl to get basic volume information

Also rename the MountType enum and members, since they are no longer
packagefs private.
This commit is contained in:
Ingo Weinhold 2013-04-06 04:26:40 +02:00
parent 91586bd3b6
commit 0c6927b5d7
7 changed files with 108 additions and 30 deletions

View File

@ -0,0 +1,38 @@
/*
* Copyright 2013, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ingo Weinhold <ingo_weinhold@gmx.de>
*/
#ifndef _PACKAGE__PRIVATE__PACKAGE_FS_H_
#define _PACKAGE__PRIVATE__PACKAGE_FS_H_
#include <Drivers.h>
enum PackageFSMountType {
PACKAGE_FS_MOUNT_TYPE_SYSTEM,
PACKAGE_FS_MOUNT_TYPE_COMMON,
PACKAGE_FS_MOUNT_TYPE_HOME,
PACKAGE_FS_MOUNT_TYPE_CUSTOM
};
enum {
PACKAGE_FS_OPERATION_GET_VOLUME_INFO = B_DEVICE_OP_CODES_END + 1
};
struct PackageFSVolumeInfo {
PackageFSMountType mountType;
// device and node id of the respective package FS root scope (e.g. "/boot"
// for the three standard volumes)
dev_t rootDeviceID;
ino_t rootDirectoryID;
};
#endif // _PACKAGE__PRIVATE__PACKAGE_FS_H_

View File

@ -3,7 +3,7 @@ SubDir HAIKU_TOP src add-ons kernel file_systems packagefs ;
UseLibraryHeaders zlib ;
UsePrivateKernelHeaders ;
UsePrivateHeaders shared storage ;
UsePrivateHeaders package shared storage ;
HAIKU_PACKAGE_FS_SOURCES =

View File

@ -96,14 +96,14 @@ PackageFSRoot::RegisterVolume(Volume* volume)
const char* relativeRootPath = NULL;
switch (volume->MountType()) {
case MOUNT_TYPE_SYSTEM:
case MOUNT_TYPE_COMMON:
case PACKAGE_FS_MOUNT_TYPE_SYSTEM:
case PACKAGE_FS_MOUNT_TYPE_COMMON:
relativeRootPath = "..";
break;
case MOUNT_TYPE_HOME:
case PACKAGE_FS_MOUNT_TYPE_HOME:
relativeRootPath = "../..";
break;
case MOUNT_TYPE_CUSTOM:
case PACKAGE_FS_MOUNT_TYPE_CUSTOM:
default:
break;
}
@ -217,8 +217,10 @@ PackageFSRoot::_AddVolume(Volume* volume)
fVolumes.Add(volume);
// TODO: Correct order?
if (fSystemVolume == NULL && volume->MountType() == MOUNT_TYPE_SYSTEM)
if (fSystemVolume == NULL && volume->MountType()
== PACKAGE_FS_MOUNT_TYPE_SYSTEM) {
fSystemVolume = volume;
}
return B_OK;
}

View File

@ -28,13 +28,13 @@ static const char*
link_path_for_mount_type(MountType type)
{
switch (type) {
case MOUNT_TYPE_SYSTEM:
case PACKAGE_FS_MOUNT_TYPE_SYSTEM:
return kSystemLinkPath;
case MOUNT_TYPE_COMMON:
case PACKAGE_FS_MOUNT_TYPE_COMMON:
return kCommonLinkPath;
case MOUNT_TYPE_HOME:
case PACKAGE_FS_MOUNT_TYPE_HOME:
return kHomeLinkPath;
case MOUNT_TYPE_CUSTOM:
case PACKAGE_FS_MOUNT_TYPE_CUSTOM:
default:
return "?";
}

View File

@ -648,16 +648,16 @@ Volume::Mount(const char* parameterString)
// If no volume name is given, infer it from the mount type.
if (volumeName == NULL) {
switch (fMountType) {
case MOUNT_TYPE_SYSTEM:
case PACKAGE_FS_MOUNT_TYPE_SYSTEM:
volumeName = "system";
break;
case MOUNT_TYPE_COMMON:
case PACKAGE_FS_MOUNT_TYPE_COMMON:
volumeName = "common";
break;
case MOUNT_TYPE_HOME:
case PACKAGE_FS_MOUNT_TYPE_HOME:
volumeName = "home";
break;
case MOUNT_TYPE_CUSTOM:
case PACKAGE_FS_MOUNT_TYPE_CUSTOM:
default:
volumeName = "Package FS";
break;
@ -728,6 +728,28 @@ Volume::Unmount()
}
status_t
Volume::IOCtl(Node* node, uint32 operation, void* buffer, size_t size)
{
switch (operation) {
case PACKAGE_FS_OPERATION_GET_VOLUME_INFO:
{
if (size != sizeof(PackageFSVolumeInfo))
return B_BAD_VALUE;
PackageFSVolumeInfo info;
info.mountType = fMountType;
info.rootDeviceID = fPackageFSRoot->DeviceID();
info.rootDirectoryID = fPackageFSRoot->NodeID();
return user_memcpy(buffer, &info, sizeof(info));
}
default:
return B_BAD_VALUE;
}
}
void
Volume::AddNodeListener(NodeListener* listener, Node* node)
{
@ -1664,15 +1686,15 @@ status_t
Volume::_InitMountType(const char* mountType)
{
if (mountType == NULL)
fMountType = MOUNT_TYPE_CUSTOM;
fMountType = PACKAGE_FS_MOUNT_TYPE_CUSTOM;
else if (strcmp(mountType, "system") == 0)
fMountType = MOUNT_TYPE_SYSTEM;
fMountType = PACKAGE_FS_MOUNT_TYPE_SYSTEM;
else if (strcmp(mountType, "common") == 0)
fMountType = MOUNT_TYPE_COMMON;
fMountType = PACKAGE_FS_MOUNT_TYPE_COMMON;
else if (strcmp(mountType, "home") == 0)
fMountType = MOUNT_TYPE_HOME;
fMountType = PACKAGE_FS_MOUNT_TYPE_HOME;
else if (strcmp(mountType, "custom") == 0)
fMountType = MOUNT_TYPE_CUSTOM;
fMountType = PACKAGE_FS_MOUNT_TYPE_CUSTOM;
else
RETURN_ERROR(B_BAD_VALUE);
@ -1714,16 +1736,16 @@ Volume::_CreateShineThroughDirectories(const char* shineThroughSetting)
if (shineThroughSetting == NULL) {
// nothing specified -- derive from mount type
switch (fMountType) {
case MOUNT_TYPE_SYSTEM:
case PACKAGE_FS_MOUNT_TYPE_SYSTEM:
directories = kSystemShineThroughDirectories;
break;
case MOUNT_TYPE_COMMON:
case PACKAGE_FS_MOUNT_TYPE_COMMON:
directories = kCommonShineThroughDirectories;
break;
case MOUNT_TYPE_HOME:
case PACKAGE_FS_MOUNT_TYPE_HOME:
directories = kHomeShineThroughDirectories;
break;
case MOUNT_TYPE_CUSTOM:
case PACKAGE_FS_MOUNT_TYPE_CUSTOM:
return B_OK;
}
} else if (strcmp(shineThroughSetting, "system") == 0)

View File

@ -14,6 +14,8 @@
#include <util/DoublyLinkedList.h>
#include <util/KMessage.h>
#include <packagefs.h>
#include "Index.h"
#include "Node.h"
#include "NodeListener.h"
@ -29,12 +31,7 @@ class UnpackingNode;
typedef IndexHashTable::Iterator IndexDirIterator;
enum MountType {
MOUNT_TYPE_SYSTEM,
MOUNT_TYPE_COMMON,
MOUNT_TYPE_HOME,
MOUNT_TYPE_CUSTOM
};
typedef PackageFSMountType MountType;
class Volume : public DoublyLinkedListLinkImpl<Volume>,
@ -70,6 +67,9 @@ public:
Node* FindNode(ino_t nodeID) const
{ return fNodes.Lookup(nodeID); }
status_t IOCtl(Node* node, uint32 operation,
void* buffer, size_t size);
// node listeners -- volume must be write-locked
void AddNodeListener(NodeListener* listener,
Node* node);

View File

@ -284,6 +284,22 @@ packagefs_io(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
// #pragma mark - Nodes
status_t
packagefs_ioctl(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
uint32 operation, void* buffer, size_t size)
{
Volume* volume = (Volume*)fsVolume->private_volume;
Node* node = (Node*)fsNode->private_node;
FUNCTION("volume: %p, node: %p (%lld), cookie: %p, operation: %" B_PRI32u
", buffer: %p, size: %zu\n", volume, node, node->ID(), cookie,
operation, buffer, size);
TOUCH(cookie);
return volume->IOCtl(node, operation, buffer, size);
}
static status_t
packagefs_read_symlink(fs_volume* fsVolume, fs_vnode* fsNode, char* buffer,
size_t* _bufferSize)
@ -1179,7 +1195,7 @@ fs_vnode_ops gPackageFSVnodeOps = {
NULL, // get_file_map,
NULL, // ioctl,
&packagefs_ioctl,
NULL, // set_flags,
NULL, // select,
NULL, // deselect,