From 9d6c014f662e29cc6f21aafce95609fb996ef1b9 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 29 Apr 2007 07:20:58 +0000 Subject: [PATCH] Added very basic volume initialization support. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20899 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/bfs/Index.cpp | 6 +- src/add-ons/kernel/file_systems/bfs/Inode.cpp | 14 +- .../kernel/file_systems/bfs/Volume.cpp | 16 +- .../file_systems/bfs/kernel_interface.cpp | 152 ++++++++++++++++++ 4 files changed, 169 insertions(+), 19 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/Index.cpp b/src/add-ons/kernel/file_systems/bfs/Index.cpp index a04e77ed9e..f66fb90ba0 100644 --- a/src/add-ons/kernel/file_systems/bfs/Index.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Index.cpp @@ -33,7 +33,8 @@ Index::~Index() if (fNode == NULL) return; - put_vnode(fVolume->ID(), fNode->ID()); + if (fVolume->ID() >= 0) + put_vnode(fVolume->ID(), fNode->ID()); } @@ -43,7 +44,8 @@ Index::Unset() if (fNode == NULL) return; - put_vnode(fVolume->ID(), fNode->ID()); + if (fVolume->ID() >= 0) + put_vnode(fVolume->ID(), fNode->ID()); fNode = NULL; fName = NULL; } diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index 16738e0987..ecf659841f 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -72,11 +72,13 @@ InodeAllocator::New(block_run *parentRun, mode_t mode, block_run &run, Inode **_ if (fInode == NULL) RETURN_ERROR(B_NO_MEMORY); - status = new_vnode(volume->ID(), fInode->ID(), fInode); - if (status < B_OK) { - delete fInode; - fInode = NULL; - RETURN_ERROR(status); + if (volume->ID() >= 0) { + status = new_vnode(volume->ID(), fInode->ID(), fInode); + if (status < B_OK) { + delete fInode; + fInode = NULL; + RETURN_ERROR(status); + } } *_inode = fInode; @@ -118,7 +120,7 @@ InodeAllocator::Keep() return status; } - if (!fInode->IsSymLink()) + if (!fInode->IsSymLink() && volume->ID() >= 0) status = publish_vnode(volume->ID(), fInode->ID(), fInode); fTransaction = NULL; diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.cpp b/src/add-ons/kernel/file_systems/bfs/Volume.cpp index 514c415ee2..611cd26e52 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp @@ -562,12 +562,10 @@ Volume::Identify(int fd, disk_super_block *superBlock) return B_OK; } -#ifdef USER -//extern "C" void kill_device_vnodes(dev_t id); - // This call is only available in the userland fs_shell status_t -Volume::Initialize(const char *device, const char *name, uint32 blockSize, uint32 flags) +Volume::Initialize(const char *device, const char *name, uint32 blockSize, + uint32 flags) { // although there is no really good reason for it, we won't // accept '/' in disk names (mkbfs does this, too - and since @@ -657,15 +655,11 @@ Volume::Initialize(const char *device, const char *name, uint32 blockSize, uint3 WriteSuperBlock(); transaction.Done(); - put_vnode(ID(), fRootNode->ID()); - if (fIndicesNode != NULL) - put_vnode(ID(), fIndicesNode->ID()); - -// kill_device_vnodes(ID()); - // This call is only available in the userland fs_shell +// put_vnode(ID(), fRootNode->ID()); +// if (fIndicesNode != NULL) +// put_vnode(ID(), fIndicesNode->ID()); Sync(); opener.RemoveCache(true); return B_OK; } -#endif diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 428f48caea..dd3e845ebd 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -2010,6 +2010,131 @@ bfs_rewind_query(void */*fs*/, void *cookie) // #pragma mark - +bool +bfs_supports_initializing(partition_data *partition) +{ + // TODO: We should at least check the partition size. + return true; +} + + +bool +bfs_validate_initialize(partition_data *partition, char *name, + const char *parameters) +{ + // TODO: Actual checks. + return true; +} + + +status_t +bfs_initialize(const char *partition, const char *name, const char *parameters, + disk_job_id job) +{ + if (partition == NULL) + return B_BAD_VALUE; + +// TODO: Handle parameters! +// char **argv = (char**)parms; + + uint32 blockSize = 1024; + uint32 flags = 0; + bool verbose = false; + +#if 0 + while (argv && *++argv) { + char *arg = *argv; + if (*arg == '-') { + if (arg[1] == '-') { + if (!strcmp(arg, "--noindex")) + flags |= VOLUME_NO_INDICES; + else + return B_BAD_VALUE; + } + + while (*++arg && *arg >= 'a' && *arg <= 'z') { + switch (*arg) { + case 'v': + verbose = true; + break; + case 'b': + if (*++argv == NULL || !(**argv >= '0' && **argv <= '9')) + return B_BAD_VALUE; + + blockSize = atol(*argv); + break; + case 'n': + flags |= VOLUME_NO_INDICES; + break; + } + } + } + else + break; + } +#endif // 0 + + if (blockSize != 1024 && blockSize != 2048 && blockSize != 4096 && blockSize != 8192) { + FATAL(("valid block sizes are: 1024, 2048, 4096, and 8192\n")); + return -1; + } + + Volume volume(-1); + status_t status = volume.Initialize(partition, name, blockSize, flags); + if (status < B_OK) { + FATAL(("Initializing volume failed: %s\n", strerror(status))); + return -1; + } + + if (verbose) { + disk_super_block super = volume.SuperBlock(); + + INFORM(("Disk was initialized successfully.\n")); + INFORM(("\tname: \"%s\"\n", super.name)); + INFORM(("\tnum blocks: %Ld\n", super.NumBlocks())); + INFORM(("\tused blocks: %Ld\n", super.UsedBlocks())); + INFORM(("\tblock size: %u bytes\n", (unsigned)super.BlockSize())); + INFORM(("\tnum allocation groups: %d\n", + (int)super.AllocationGroups())); + INFORM(("\tallocation group size: %ld blocks\n", + 1L << super.AllocationGroupShift())); + INFORM(("\tlog size: %u blocks\n", super.log_blocks.Length())); + } + + // make the disk image bootable + +// TODO: Check whether this is necessary. Actually makebootable should do the +// trick anyway. +#if 0 + int device = open(partition, O_RDWR); + if (device < 0) { + FATAL(("Could not make image bootable: Failed to open \"%s\"\n", + partition)); + return B_FILE_ERROR; + } + + // change BIOS drive and partition offset + // TODO: for now, this will only work for images only + + sBootBlockData1[kBIOSDriveOffset] = 0x80; + // for now, this should be replaced by the real thing + uint32 *offset = (uint32 *)&sBootBlockData1[kPartitionDataOffset]; + *offset = 0; + + write_pos(device, 0, sBootBlockData1, kBootBlockData1Size); + write_pos(device, kBootBlockData2Offset, sBootBlockData2, + kBootBlockData2Size); + + close(device); +#endif // 0 + + return B_OK; +} + + +// #pragma mark - + + static status_t bfs_std_ops(int32 op, ...) { @@ -2137,6 +2262,33 @@ static file_system_module_info sBeFileSystem = { &bfs_free_query_cookie, &bfs_read_query, &bfs_rewind_query, + + /* capability querying operations */ + NULL, // supports_defragmenting + NULL, // supports_repairing + NULL, // supports_resizing + NULL, // supports_moving + NULL, // supports_setting_content_name + NULL, // supports_setting_content_parameters + &bfs_supports_initializing, + + NULL, // validate_resize + NULL, // validate_move + NULL, // validate_set_content_name + NULL, // validate_set_content_parameters + &bfs_validate_initialize, + + /* shadow partition modification */ + NULL, // shadow_changed + + /* writing */ + NULL, // defragment + NULL, // repair + NULL, // resize + NULL, // move + NULL, // set_content_name + NULL, // set_content_parameters + bfs_initialize, }; module_info *modules[] = {