Merged the disk device manager module interface for file systems with the

VFS's interface, so that a file system only has to implement one interface.
As a side effect, the automatic file system detection may now work (not yet
tested, though).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12786 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-05-23 17:15:56 +00:00
parent 87ab5d5c6d
commit 47f39c93cb
15 changed files with 183 additions and 263 deletions

View File

@ -10,6 +10,7 @@
#include <OS.h>
#include <Select.h>
#include <module.h>
#include <disk_device_manager.h>
#include <sys/uio.h>
@ -54,11 +55,22 @@ struct file_io_vec {
extern "C" {
#endif
typedef struct file_system_info {
struct module_info module_info;
typedef struct file_system_module_info {
struct module_info info;
const char *pretty_name;
/* scanning (the device is write locked) */
float (*identify_partition)(int fd, partition_data *partition,
void **cookie);
status_t (*scan_partition)(int fd, partition_data *partition,
void *cookie);
void (*free_identify_partition_cookie)(partition_data *partition,
void *cookie);
void (*free_partition_content_cookie)(partition_data *partition);
/* general operations */
status_t (*mount)(mount_id id, const char *device, uint32 flags, const char *args, fs_volume *_fs, vnode_id *_rootVnodeID);
status_t (*mount)(mount_id id, const char *device, uint32 flags,
const char *args, fs_volume *_fs, vnode_id *_rootVnodeID);
status_t (*unmount)(fs_volume fs);
status_t (*read_fs_info)(fs_volume fs, struct fs_info *info);
@ -154,9 +166,56 @@ typedef struct file_system_info {
status_t (*open_query)(fs_volume fs, const char *query, uint32 flags, port_id port, uint32 token, fs_cookie *_cookie);
status_t (*close_query)(fs_volume fs, fs_cookie cookie);
status_t (*free_query_cookie)(fs_volume fs, fs_cookie cookie);
status_t (*read_query)(fs_volume fs, fs_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_num);
status_t (*read_query)(fs_volume fs, fs_cookie cookie,
struct dirent *buffer, size_t bufferSize, uint32 *_num);
status_t (*rewind_query)(fs_volume fs, fs_cookie cookie);
} file_system_info;
/* capability querying (the device is read locked) */
// ToDo: this will probably be combined to a single call
bool (*supports_defragmenting)(partition_data *partition,
bool *whileMounted);
bool (*supports_repairing)(partition_data *partition,
bool checkOnly, bool *whileMounted);
bool (*supports_resizing)(partition_data *partition,
bool *whileMounted);
bool (*supports_moving)(partition_data *partition, bool *isNoOp);
bool (*supports_setting_content_name)(partition_data *partition,
bool *whileMounted);
bool (*supports_setting_content_parameters)(partition_data *partition,
bool *whileMounted);
bool (*supports_initializing)(partition_data *partition);
bool (*validate_resize)(partition_data *partition, off_t *size);
bool (*validate_move)(partition_data *partition, off_t *start);
bool (*validate_set_content_name)(partition_data *partition,
char *name);
bool (*validate_set_content_parameters)(partition_data *partition,
const char *parameters);
bool (*validate_initialize)(partition_data *partition, char *name,
const char *parameters);
/* shadow partition modification (device is write locked) */
status_t (*shadow_changed)(partition_data *partition,
uint32 operation);
/* writing (the device is NOT locked) */
status_t (*defragment)(int fd, partition_id partition,
disk_job_id job);
status_t (*repair)(int fd, partition_id partition, bool checkOnly,
disk_job_id job);
status_t (*resize)(int fd, partition_id partition, off_t size,
disk_job_id job);
status_t (*move)(int fd, partition_id partition, off_t offset,
disk_job_id job);
status_t (*set_content_name)(int fd, partition_id partition,
const char *name, disk_job_id job);
status_t (*set_content_parameters)(int fd, partition_id partition,
const char *parameters, disk_job_id job);
status_t (*initialize)(const char *partition, const char *name,
const char *parameters, disk_job_id job);
// This is pretty close to how the hook in R5 looked. Save the job ID, of
// course and that the parameters were given as (void*, size_t) pair.
} file_system_module_info;
/* file system add-ons only prototypes */

View File

@ -8,7 +8,7 @@
#include "KDiskSystem.h"
struct fs_module_info;
struct file_system_module_info;
namespace BPrivate {
namespace DiskDevice {
@ -76,7 +76,7 @@ protected:
virtual void UnloadModule();
private:
fs_module_info *fModule;
file_system_module_info *fModule;
};
} // namespace DiskDevice

View File

@ -1,6 +1,6 @@
// ddm_modules.h
//
// Interfaces to be implemented by partition/FS modules.
// Interface to be implemented by partition modules.
#ifndef _K_DISK_DEVICE_MODULES_H
#define _K_DISK_DEVICE_MODULES_H
@ -185,106 +185,4 @@ typedef struct partition_module_info {
partition_delete_child delete_child;
} partition_module_info;
// FS module interface
// scanning
// (the device is write locked)
typedef float (*fs_identify_partition)(int fd, partition_data *partition,
void **cookie);
typedef status_t (*fs_scan_partition)(int fd, partition_data *partition,
void *cookie);
typedef void (*fs_free_identify_partition_cookie)(partition_data *partition,
void *cookie);
typedef void (*fs_free_partition_content_cookie)(partition_data *partition);
// querying
// (the device is read locked)
typedef bool (*fs_supports_defragmenting)(partition_data *partition,
bool *whileMounted);
typedef bool (*fs_supports_repairing)(partition_data *partition,
bool checkOnly, bool *whileMounted);
typedef bool (*fs_supports_resizing)(partition_data *partition,
bool *whileMounted);
typedef bool (*fs_supports_moving)(partition_data *partition, bool *isNoOp);
typedef bool (*fs_supports_setting_content_name)(partition_data *partition,
bool *whileMounted);
typedef bool (*fs_supports_setting_content_parameters)(
partition_data *partition, bool *whileMounted);
typedef bool (*fs_supports_initializing)(partition_data *partition);
typedef bool (*fs_validate_resize)(partition_data *partition, off_t *size);
typedef bool (*fs_validate_move)(partition_data *partition, off_t *start);
typedef bool (*fs_validate_set_content_name)(partition_data *partition,
char *name);
typedef bool (*fs_validate_set_content_parameters)(partition_data *partition,
const char *parameters);
typedef bool (*fs_validate_initialize)(partition_data *partition, char *name,
const char *parameters);
// shadow partition modification
// (device is write locked)
typedef status_t (*fs_shadow_changed)(partition_data *partition,
uint32 operation);
// writing
// (the device is NOT locked)
typedef status_t (*fs_defragment)(int fd, partition_id partition,
disk_job_id job);
typedef status_t (*fs_repair)(int fd, partition_id partition, bool checkOnly,
disk_job_id job);
typedef status_t (*fs_resize)(int fd, partition_id partition, off_t size,
disk_job_id job);
typedef status_t (*fs_move)(int fd, partition_id partition, off_t offset,
disk_job_id job);
typedef status_t (*fs_set_content_name)(int fd, partition_id partition,
const char *name, disk_job_id job);
typedef status_t (*fs_set_content_parameters)(int fd, partition_id partition,
const char *parameters, disk_job_id job);
typedef status_t (*fs_initialize)(const char *partition, const char *name,
const char *parameters, disk_job_id job);
// This is pretty close to how the hook in R5 looked. Save the job ID, of
// course and that the parameters were given as (void*, size_t) pair.
typedef struct fs_module_info {
module_info module;
const char *pretty_name;
uint32 flags;
// scanning
fs_identify_partition identify_partition;
fs_scan_partition scan_partition;
fs_free_identify_partition_cookie free_identify_partition_cookie;
fs_free_partition_content_cookie free_partition_content_cookie;
// querying
fs_supports_defragmenting supports_defragmenting;
fs_supports_repairing supports_repairing;
fs_supports_resizing supports_resizing;
fs_supports_moving supports_moving;
fs_supports_setting_content_name supports_setting_content_name;
fs_supports_setting_content_parameters
supports_setting_content_parameters;
fs_supports_initializing supports_initializing;
fs_validate_resize validate_resize;
fs_validate_move validate_move;
fs_validate_set_content_name validate_set_content_name;
fs_validate_set_content_parameters
validate_set_content_parameters;
fs_validate_initialize validate_initialize;
// shadow partition modification
fs_shadow_changed shadow_changed;
// writing
fs_defragment defragment;
fs_repair repair;
fs_resize resize;
fs_move move;
fs_set_content_name set_content_name;
fs_set_content_parameters set_content_parameters;
fs_initialize initialize;
} fs_module_info;
#endif // _K_DISK_DEVICE_MODULES_H

View File

@ -7,7 +7,7 @@
#include <storage/DiskDeviceDefs.h>
#include <disk_device_manager/disk_device_manager.h>
#include <disk_device_manager.h>
#ifdef __cplusplus
extern "C" {

View File

@ -45,7 +45,6 @@ KernelAddon bfs : kernel file_systems :
Volume.cpp
kernel_interface.cpp
disk_device_interface.cpp
;
SEARCH on [ FGristFiles

View File

@ -1,106 +0,0 @@
/*
* Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de
* This file may be used under the terms of the MIT License.
*/
/* This file contains the module interface to the disk device manager.
* Currently, only the part for identifying and scanning a volume is implemented.
*/
#include "Volume.h"
#include <disk_device_manager/ddm_modules.h>
#include <util/kernel_cpp.h>
#include <string.h>
struct identify_cookie {
disk_super_block super_block;
};
// Scanning
static float
bfs_identify_partition(int fd, partition_data *partition, void **_cookie)
{
disk_super_block superBlock;
status_t status = Volume::Identify(fd, &superBlock);
if (status != B_OK)
return status;
identify_cookie *cookie = new identify_cookie;
memcpy(&cookie->super_block, &superBlock, sizeof(disk_super_block));
*_cookie = cookie;
return 0.8f;
}
static status_t
bfs_scan_partition(int fd, partition_data *partition, void *_cookie)
{
identify_cookie *cookie = (identify_cookie *)_cookie;
partition->status = B_PARTITION_VALID;
partition->flags |= B_PARTITION_FILE_SYSTEM;
partition->content_size = cookie->super_block.NumBlocks() * cookie->super_block.BlockSize();
partition->block_size = cookie->super_block.BlockSize();
partition->content_name = strdup(cookie->super_block.name);
if (partition->content_name == NULL)
return B_NO_MEMORY;
return B_OK;
}
static void
bfs_free_identify_partition_cookie(partition_data *partition, void *_cookie)
{
identify_cookie *cookie = (identify_cookie *)_cookie;
delete cookie;
}
// #pragma mark -
static status_t
bfs_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
case B_MODULE_UNINIT:
return B_OK;
}
return B_BAD_VALUE;
}
struct fs_module_info gDiskDeviceInfo = {
{
"file_systems/bfs/disk_device/v1",
0,
bfs_std_ops,
},
"Be File System",
0, /* flags ? */
// scanning
bfs_identify_partition,
bfs_scan_partition,
bfs_free_identify_partition_cookie,
NULL,
// querying
// shadow partition modification
// writing
NULL
};

View File

@ -33,6 +33,11 @@
#define BFS_IO_SIZE 65536
struct identify_cookie {
disk_super_block super_block;
};
extern void fill_stat_buffer(Inode *inode, struct stat &stat);
@ -73,6 +78,51 @@ strtod(const char */*start*/, char **/*end*/)
}
// #pragma mark - Scanning
static float
bfs_identify_partition(int fd, partition_data *partition, void **_cookie)
{
disk_super_block superBlock;
status_t status = Volume::Identify(fd, &superBlock);
if (status != B_OK)
return status;
identify_cookie *cookie = new identify_cookie;
memcpy(&cookie->super_block, &superBlock, sizeof(disk_super_block));
*_cookie = cookie;
return 0.8f;
}
static status_t
bfs_scan_partition(int fd, partition_data *partition, void *_cookie)
{
identify_cookie *cookie = (identify_cookie *)_cookie;
partition->status = B_PARTITION_VALID;
partition->flags |= B_PARTITION_FILE_SYSTEM;
partition->content_size = cookie->super_block.NumBlocks() * cookie->super_block.BlockSize();
partition->block_size = cookie->super_block.BlockSize();
partition->content_name = strdup(cookie->super_block.name);
if (partition->content_name == NULL)
return B_NO_MEMORY;
return B_OK;
}
static void
bfs_free_identify_partition_cookie(partition_data *partition, void *_cookie)
{
identify_cookie *cookie = (identify_cookie *)_cookie;
delete cookie;
}
// #pragma mark -
@ -2002,13 +2052,21 @@ bfs_std_ops(int32 op, ...)
}
static file_system_info sBeFileSystem = {
static file_system_module_info sBeFileSystem = {
{
"file_systems/bfs" B_CURRENT_FS_API_VERSION,
0,
bfs_std_ops,
},
"Be File System",
// scanning
bfs_identify_partition,
bfs_scan_partition,
bfs_free_identify_partition_cookie,
NULL, // free_partition_content_cookie()
&bfs_mount,
&bfs_unmount,
&bfs_read_fs_stat,
@ -2103,10 +2161,7 @@ static file_system_info sBeFileSystem = {
&bfs_rewind_query,
};
extern module_info gDiskDeviceInfo;
module_info *modules[] = {
(module_info *)&sBeFileSystem,
&gDiskDeviceInfo,
NULL,
};

View File

@ -42,7 +42,6 @@
// directories for partitioning and file system modules
static const char *kPartitioningSystemPrefix = "partitioning_systems";
static const char *kFileSystemPrefix = "file_systems";
static const char *kFileSystemDiskDeviceSuffix = "/disk_device/v1";
// singleton instance
@ -114,23 +113,6 @@ is_active_job_status(uint32 status)
}
static bool
is_fs_disk_device(const char *module)
{
size_t prefixLength = strlen(kFileSystemPrefix);
if (strncmp(module, kFileSystemPrefix, prefixLength))
return false;
size_t suffixLength = strlen(kFileSystemDiskDeviceSuffix);
size_t length = strlen(module);
if (length <= suffixLength + prefixLength)
return false;
return !strcmp(module + length - suffixLength, kFileSystemDiskDeviceSuffix);
}
// #pragma mark -
@ -153,6 +135,7 @@ KDiskDeviceManager::KDiskDeviceManager()
uint32 cookie = 0;
size_t partitioningPrefixLength = strlen(kPartitioningSystemPrefix);
size_t filePrefixLength = strlen(kFileSystemPrefix);
while (true) {
KPath name;
@ -169,7 +152,7 @@ KDiskDeviceManager::KDiskDeviceManager()
partitioningPrefixLength)) {
DBG(OUT("partitioning system: %s\n", name.Path()));
_AddPartitioningSystem(name.Path());
} else if (is_fs_disk_device(name.Path())) {
} else if (!strncmp(name.Path(), kFileSystemPrefix, filePrefixLength)) {
DBG(OUT("file system: %s\n", name.Path()));
_AddFileSystem(name.Path());
}

View File

@ -4,15 +4,18 @@
#include <stdlib.h>
#include <unistd.h>
#include <fs_interface.h>
#include "ddm_modules.h"
#include "KDiskDeviceUtils.h"
#include "KFileSystem.h"
#include "KPartition.h"
// constructor
KFileSystem::KFileSystem(const char *name)
: KDiskSystem(name),
fModule(NULL)
fModule(NULL)
{
}
@ -32,7 +35,7 @@ KFileSystem::Init()
if (error != B_OK)
return error;
error = SetPrettyName(fModule->pretty_name);
SetFlags(fModule->flags | B_DISK_SYSTEM_IS_FILE_SYSTEM);
SetFlags(/*fModule->flags |*/ B_DISK_SYSTEM_IS_FILE_SYSTEM);
Unload();
return error;
}
@ -291,31 +294,32 @@ KFileSystem::SetContentName(KPartition *partition, char *name,
return B_ERROR;
}
// SetContentParameters
status_t
KFileSystem::SetContentParameters(KPartition *partition,
const char *parameters, KDiskDeviceJob *job)
const char *parameters, KDiskDeviceJob *job)
{
// to be implemented
return B_ERROR;
}
// Initialize
status_t
KFileSystem::Initialize(KPartition *partition, const char *name,
const char *parameters, KDiskDeviceJob *job)
const char *parameters, KDiskDeviceJob *job)
{
// to be implemented
return B_ERROR;
}
// LoadModule
status_t
KFileSystem::LoadModule()
{
if (fModule) // shouldn't happen
return B_OK;
return get_module(Name(), (module_info**)&fModule);
return get_module(Name(), (module_info **)&fModule);
}
// UnloadModule
@ -323,7 +327,7 @@ void
KFileSystem::UnloadModule()
{
if (fModule) {
put_module(fModule->module.name);
put_module(fModule->info.name);
fModule = NULL;
}
}

View File

@ -1,7 +1,7 @@
/*
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#include <KernelExport.h>
@ -950,13 +950,20 @@ bootfs_std_ops(int32 op, ...)
}
file_system_info gBootFileSystem = {
file_system_module_info gBootFileSystem = {
{
"file_systems/bootfs" B_CURRENT_FS_API_VERSION,
0,
bootfs_std_ops,
},
"Old Boot File System",
NULL, // identify_partition()
NULL, // scan_partition()
NULL, // free_identify_partition_cookie()
NULL, // free_partition_content_cookie()
&bootfs_mount,
&bootfs_unmount,
&bootfs_read_fs_info,

View File

@ -1574,13 +1574,20 @@ devfs_std_ops(int32 op, ...)
}
file_system_info gDeviceFileSystem = {
file_system_module_info gDeviceFileSystem = {
{
"file_systems/devfs" B_CURRENT_FS_API_VERSION,
0,
devfs_std_ops,
},
"Device File System",
NULL, // identify_partition()
NULL, // scan_partition()
NULL, // free_identify_partition_cookie()
NULL, // free_partition_content_cookie()
&devfs_mount,
&devfs_unmount,
NULL,

View File

@ -1677,13 +1677,20 @@ pipefs_std_ops(int32 op, ...)
using namespace pipefs;
file_system_info gPipeFileSystem = {
file_system_module_info gPipeFileSystem = {
{
"file_systems/pipefs" B_CURRENT_FS_API_VERSION,
0,
pipefs_std_ops,
},
"Pipe File System",
NULL, // identify_partition()
NULL, // scan_partition()
NULL, // free_identify_partition_cookie()
NULL, // free_partition_content_cookie()
&pipefs_mount,
&pipefs_unmount,
NULL,

View File

@ -1030,13 +1030,20 @@ rootfs_std_ops(int32 op, ...)
}
file_system_info gRootFileSystem = {
file_system_module_info gRootFileSystem = {
{
"file_systems/rootfs" B_CURRENT_FS_API_VERSION,
0,
rootfs_std_ops,
},
"Root File System",
NULL, // identify_partition()
NULL, // scan_partition()
NULL, // free_identify_partition_cookie()
NULL, // free_partition_content_cookie()
&rootfs_mount,
&rootfs_unmount,
NULL,

View File

@ -99,7 +99,7 @@ struct vnode_hash_key {
struct fs_mount {
struct fs_mount *next;
file_system_info *fs;
file_system_module_info *fs;
mount_id id;
void *cookie;
char *device_name;
@ -487,20 +487,20 @@ put_mount(struct fs_mount *mount)
static status_t
put_file_system(file_system_info *fs)
put_file_system(file_system_module_info *fs)
{
return put_module(fs->module_info.name);
return put_module(fs->info.name);
}
static file_system_info *
static file_system_module_info *
get_file_system(const char *fsName)
{
// construct module name (we currently support only one API)
char name[B_FILE_NAME_LENGTH];
snprintf(name, sizeof(name), "file_systems/%s/v1", fsName);
file_system_info *info;
file_system_module_info *info;
if (get_module(name, (module_info **)&info) != B_OK)
return NULL;
@ -2758,7 +2758,7 @@ vfs_mount_boot_file_system(kernel_args *args)
} else
dprintf("KDiskDeviceManager::InitialDeviceScan() failed: %s\n", strerror(status));
file_system_info *bootfs;
file_system_module_info *bootfs;
if ((bootfs = get_file_system("bootfs")) == NULL) {
// no bootfs there, yet