Reverted r27685, r27676, r27665, and r27664, the changes related to
letting the boot loader provide full paths for the pre-loaded images. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27753 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -45,13 +45,7 @@ typedef NodeList::Iterator NodeIterator;
|
|||||||
|
|
||||||
class Directory : public Node {
|
class Directory : public Node {
|
||||||
public:
|
public:
|
||||||
Directory(Directory* parent);
|
Directory();
|
||||||
~Directory();
|
|
||||||
|
|
||||||
Directory* Parent() const;
|
|
||||||
void SetParent(Directory* parent);
|
|
||||||
|
|
||||||
status_t GetPath(const char* entry, char* buffer, size_t bufferSize);
|
|
||||||
|
|
||||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
|
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
|
||||||
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
|
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
|
||||||
@@ -64,9 +58,6 @@ class Directory : public Node {
|
|||||||
virtual status_t GetNextNode(void *cookie, Node **_node) = 0;
|
virtual status_t GetNextNode(void *cookie, Node **_node) = 0;
|
||||||
virtual status_t Rewind(void *cookie) = 0;
|
virtual status_t Rewind(void *cookie) = 0;
|
||||||
virtual bool IsEmpty() = 0;
|
virtual bool IsEmpty() = 0;
|
||||||
|
|
||||||
private:
|
|
||||||
Directory* fParent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The console based nodes don't need cookies for I/O, they
|
/** The console based nodes don't need cookies for I/O, they
|
||||||
|
|||||||
@@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
|
|
||||||
RootFileSystem::RootFileSystem()
|
RootFileSystem::RootFileSystem()
|
||||||
:
|
|
||||||
Directory(NULL)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,16 +29,7 @@ RootFileSystem::~RootFileSystem()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RootFileSystem::GetName(char *nameBuffer, size_t bufferSize) const
|
|
||||||
{
|
|
||||||
if (strlcpy(nameBuffer, "/", bufferSize) >= bufferSize)
|
|
||||||
return B_BUFFER_OVERFLOW;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
RootFileSystem::Open(void **_cookie, int mode)
|
RootFileSystem::Open(void **_cookie, int mode)
|
||||||
{
|
{
|
||||||
EntryIterator *iterator = new (std::nothrow) EntryIterator(&fList);
|
EntryIterator *iterator = new (std::nothrow) EntryIterator(&fList);
|
||||||
@@ -53,7 +42,7 @@ RootFileSystem::Open(void **_cookie, int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RootFileSystem::Close(void *cookie)
|
RootFileSystem::Close(void *cookie)
|
||||||
{
|
{
|
||||||
delete (EntryIterator *)cookie;
|
delete (EntryIterator *)cookie;
|
||||||
@@ -95,7 +84,7 @@ RootFileSystem::Lookup(const char *name, bool /*traverseLinks*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RootFileSystem::GetNextEntry(void *_cookie, char *name, size_t size)
|
RootFileSystem::GetNextEntry(void *_cookie, char *name, size_t size)
|
||||||
{
|
{
|
||||||
EntryIterator *iterator = (EntryIterator *)_cookie;
|
EntryIterator *iterator = (EntryIterator *)_cookie;
|
||||||
@@ -109,7 +98,7 @@ RootFileSystem::GetNextEntry(void *_cookie, char *name, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RootFileSystem::GetNextNode(void *_cookie, Node **_node)
|
RootFileSystem::GetNextNode(void *_cookie, Node **_node)
|
||||||
{
|
{
|
||||||
EntryIterator *iterator = (EntryIterator *)_cookie;
|
EntryIterator *iterator = (EntryIterator *)_cookie;
|
||||||
@@ -124,24 +113,24 @@ RootFileSystem::GetNextNode(void *_cookie, Node **_node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RootFileSystem::Rewind(void *_cookie)
|
RootFileSystem::Rewind(void *_cookie)
|
||||||
{
|
{
|
||||||
EntryIterator *iterator = (EntryIterator *)_cookie;
|
EntryIterator *iterator = (EntryIterator *)_cookie;
|
||||||
|
|
||||||
iterator->Rewind();
|
iterator->Rewind();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RootFileSystem::IsEmpty()
|
RootFileSystem::IsEmpty()
|
||||||
{
|
{
|
||||||
return fList.IsEmpty();
|
return fList.IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RootFileSystem::AddVolume(Directory *volume, Partition *partition)
|
RootFileSystem::AddVolume(Directory *volume, Partition *partition)
|
||||||
{
|
{
|
||||||
struct entry *entry = new (std::nothrow) RootFileSystem::entry();
|
struct entry *entry = new (std::nothrow) RootFileSystem::entry();
|
||||||
@@ -149,7 +138,6 @@ RootFileSystem::AddVolume(Directory *volume, Partition *partition)
|
|||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
volume->Acquire();
|
volume->Acquire();
|
||||||
volume->SetParent(this);
|
|
||||||
entry->name = NULL;
|
entry->name = NULL;
|
||||||
entry->root = volume;
|
entry->root = volume;
|
||||||
entry->partition = partition;
|
entry->partition = partition;
|
||||||
@@ -177,7 +165,7 @@ RootFileSystem::AddLink(const char *name, Directory *target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RootFileSystem::GetPartitionFor(Directory *volume, Partition **_partition)
|
RootFileSystem::GetPartitionFor(Directory *volume, Partition **_partition)
|
||||||
{
|
{
|
||||||
EntryIterator iterator = fList.GetIterator();
|
EntryIterator iterator = fList.GetIterator();
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ class RootFileSystem : public Directory {
|
|||||||
RootFileSystem();
|
RootFileSystem();
|
||||||
virtual ~RootFileSystem();
|
virtual ~RootFileSystem();
|
||||||
|
|
||||||
virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
|
|
||||||
|
|
||||||
virtual status_t Open(void **_cookie, int mode);
|
virtual status_t Open(void **_cookie, int mode);
|
||||||
virtual status_t Close(void *cookie);
|
virtual status_t Close(void *cookie);
|
||||||
|
|
||||||
|
|||||||
@@ -6,18 +6,15 @@
|
|||||||
|
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <boot/arch.h>
|
#include <boot/arch.h>
|
||||||
#include <boot/platform.h>
|
#include <boot/platform.h>
|
||||||
#include <boot/stage2.h>
|
#include <boot/stage2.h>
|
||||||
#include <elf32.h>
|
#include <elf32.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
|
||||||
#include "loader.h"
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
//#define TRACE_ELF
|
//#define TRACE_ELF
|
||||||
#ifdef TRACE_ELF
|
#ifdef TRACE_ELF
|
||||||
@@ -129,9 +126,9 @@ load_elf_symbol_table(int fd, preloaded_image *image)
|
|||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
goto error1;
|
goto error1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find symbol table in section headers
|
// find symbol table in section headers
|
||||||
|
|
||||||
for (int32 i = 0; i < elfHeader.e_shnum; i++) {
|
for (int32 i = 0; i < elfHeader.e_shnum; i++) {
|
||||||
if (sectionHeaders[i].sh_type == SHT_SYMTAB) {
|
if (sectionHeaders[i].sh_type == SHT_SYMTAB) {
|
||||||
stringHeader = §ionHeaders[sectionHeaders[i].sh_link];
|
stringHeader = §ionHeaders[sectionHeaders[i].sh_link];
|
||||||
@@ -426,14 +423,7 @@ elf_load_image(Directory *directory, const char *path)
|
|||||||
|
|
||||||
status_t status = elf_load_image(fd, image);
|
status_t status = elf_load_image(fd, image);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
char tempPath[B_PATH_NAME_LENGTH];
|
image->name = kernel_args_strdup(path);
|
||||||
if (directory->GetPath(path, tempPath, sizeof(tempPath)) == B_OK) {
|
|
||||||
// Replace the first path component with "boot", as the kernel
|
|
||||||
// will always mount the boot volume there.
|
|
||||||
to_boot_path(tempPath, sizeof(tempPath));
|
|
||||||
image->name = kernel_args_strdup(tempPath);
|
|
||||||
} else
|
|
||||||
image->name = kernel_args_strdup(path);
|
|
||||||
image->inode = stat.st_ino;
|
image->inode = stat.st_ino;
|
||||||
|
|
||||||
// insert to kernel args
|
// insert to kernel args
|
||||||
|
|||||||
@@ -18,9 +18,8 @@
|
|||||||
|
|
||||||
namespace FFS {
|
namespace FFS {
|
||||||
|
|
||||||
Directory::Directory(Volume &volume, ::Directory* parent, int32 block)
|
Directory::Directory(Volume &volume, int32 block)
|
||||||
:
|
:
|
||||||
::Directory(parent),
|
|
||||||
fVolume(volume)
|
fVolume(volume)
|
||||||
{
|
{
|
||||||
void *data = malloc(volume.BlockSize());
|
void *data = malloc(volume.BlockSize());
|
||||||
@@ -32,9 +31,8 @@ Directory::Directory(Volume &volume, ::Directory* parent, int32 block)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Directory::Directory(Volume &volume, ::Directory* parent, RootBlock &root)
|
Directory::Directory(Volume &volume, RootBlock &root)
|
||||||
:
|
:
|
||||||
::Directory(parent),
|
|
||||||
fVolume(volume)
|
fVolume(volume)
|
||||||
{
|
{
|
||||||
fNode.SetTo(root.BlockData(), root.BlockSize());
|
fNode.SetTo(root.BlockData(), root.BlockSize());
|
||||||
@@ -47,14 +45,14 @@ Directory::~Directory()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::InitCheck()
|
Directory::InitCheck()
|
||||||
{
|
{
|
||||||
return fNode.ValidateCheckSum();
|
return fNode.ValidateCheckSum();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::Open(void **_cookie, int mode)
|
Directory::Open(void **_cookie, int mode)
|
||||||
{
|
{
|
||||||
_inherited::Open(_cookie, mode);
|
_inherited::Open(_cookie, mode);
|
||||||
@@ -73,7 +71,7 @@ Directory::Open(void **_cookie, int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::Close(void *cookie)
|
Directory::Close(void *cookie)
|
||||||
{
|
{
|
||||||
_inherited::Close(cookie);
|
_inherited::Close(cookie);
|
||||||
@@ -106,7 +104,7 @@ Directory::Lookup(const char *name, bool traverseLinks)
|
|||||||
if (node->IsFile())
|
if (node->IsFile())
|
||||||
return new(nothrow) File(fVolume, block);
|
return new(nothrow) File(fVolume, block);
|
||||||
if (node->IsDirectory())
|
if (node->IsDirectory())
|
||||||
return new(nothrow) Directory(fVolume, this, block);
|
return new(nothrow) Directory(fVolume, block);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -115,7 +113,7 @@ Directory::Lookup(const char *name, bool traverseLinks)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::GetNextEntry(void *cookie, char *name, size_t size)
|
Directory::GetNextEntry(void *cookie, char *name, size_t size)
|
||||||
{
|
{
|
||||||
HashIterator *iterator = (HashIterator *)cookie;
|
HashIterator *iterator = (HashIterator *)cookie;
|
||||||
@@ -129,7 +127,7 @@ Directory::GetNextEntry(void *cookie, char *name, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::GetNextNode(void *cookie, Node **_node)
|
Directory::GetNextNode(void *cookie, Node **_node)
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ class Volume;
|
|||||||
|
|
||||||
class Directory : public ::Directory {
|
class Directory : public ::Directory {
|
||||||
public:
|
public:
|
||||||
Directory(Volume &volume, ::Directory* parent, RootBlock &root);
|
Directory();
|
||||||
Directory(Volume &volume, ::Directory* parent, int32 block);
|
Directory(Volume &volume, RootBlock &root);
|
||||||
|
Directory(Volume &volume, int32 block);
|
||||||
virtual ~Directory();
|
virtual ~Directory();
|
||||||
|
|
||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ Volume::Volume(boot::Partition *partition)
|
|||||||
buffer = newBuffer;
|
buffer = newBuffer;
|
||||||
|
|
||||||
fRootNode.SetTo(buffer, blockSize);
|
fRootNode.SetTo(buffer, blockSize);
|
||||||
fRoot = new(nothrow) Directory(*this, NULL, fRootNode);
|
fRoot = new(nothrow) Directory(*this, fRootNode);
|
||||||
// fRoot will free the buffer for us upon destruction
|
// fRoot will free the buffer for us upon destruction
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ Volume::~Volume()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::InitCheck()
|
Volume::InitCheck()
|
||||||
{
|
{
|
||||||
if (fRoot != NULL)
|
if (fRoot != NULL)
|
||||||
|
|||||||
@@ -22,27 +22,24 @@ extern Node *get_node_from(int fd);
|
|||||||
|
|
||||||
namespace BFS {
|
namespace BFS {
|
||||||
|
|
||||||
Directory::Directory(Volume &volume, ::Directory* parent, block_run run)
|
Directory::Directory(Volume &volume, block_run run)
|
||||||
:
|
:
|
||||||
::Directory(parent),
|
|
||||||
fStream(volume, run),
|
fStream(volume, run),
|
||||||
fTree(&fStream)
|
fTree(&fStream)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Directory::Directory(Volume &volume, ::Directory* parent, off_t id)
|
Directory::Directory(Volume &volume, off_t id)
|
||||||
:
|
:
|
||||||
::Directory(parent),
|
|
||||||
fStream(volume, id),
|
fStream(volume, id),
|
||||||
fTree(&fStream)
|
fTree(&fStream)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Directory::Directory(::Directory* parent, const Stream &stream)
|
Directory::Directory(const Stream &stream)
|
||||||
:
|
:
|
||||||
::Directory(parent),
|
|
||||||
fStream(stream),
|
fStream(stream),
|
||||||
fTree(&fStream)
|
fTree(&fStream)
|
||||||
{
|
{
|
||||||
@@ -54,14 +51,14 @@ Directory::~Directory()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::InitCheck()
|
Directory::InitCheck()
|
||||||
{
|
{
|
||||||
return fStream.InitCheck();
|
return fStream.InitCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::Open(void **_cookie, int mode)
|
Directory::Open(void **_cookie, int mode)
|
||||||
{
|
{
|
||||||
_inherited::Open(_cookie, mode);
|
_inherited::Open(_cookie, mode);
|
||||||
@@ -74,7 +71,7 @@ Directory::Open(void **_cookie, int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::Close(void *cookie)
|
Directory::Close(void *cookie)
|
||||||
{
|
{
|
||||||
_inherited::Close(cookie);
|
_inherited::Close(cookie);
|
||||||
@@ -91,7 +88,7 @@ Directory::Lookup(const char *name, bool traverseLinks)
|
|||||||
if (fTree.Find((uint8 *)name, strlen(name), &id) < B_OK)
|
if (fTree.Find((uint8 *)name, strlen(name), &id) < B_OK)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Node *node = Stream::NodeFactory(fStream.GetVolume(), this, id);
|
Node *node = Stream::NodeFactory(fStream.GetVolume(), id);
|
||||||
if (!node)
|
if (!node)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -120,7 +117,7 @@ Directory::Lookup(const char *name, bool traverseLinks)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::GetNextEntry(void *cookie, char *name, size_t size)
|
Directory::GetNextEntry(void *cookie, char *name, size_t size)
|
||||||
{
|
{
|
||||||
TreeIterator *iterator = (TreeIterator *)cookie;
|
TreeIterator *iterator = (TreeIterator *)cookie;
|
||||||
@@ -131,7 +128,7 @@ Directory::GetNextEntry(void *cookie, char *name, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::GetNextNode(void *cookie, Node **_node)
|
Directory::GetNextNode(void *cookie, Node **_node)
|
||||||
{
|
{
|
||||||
TreeIterator *iterator = (TreeIterator *)cookie;
|
TreeIterator *iterator = (TreeIterator *)cookie;
|
||||||
@@ -143,7 +140,7 @@ Directory::GetNextNode(void *cookie, Node **_node)
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
*_node = Stream::NodeFactory(fStream.GetVolume(), this, id);
|
*_node = Stream::NodeFactory(fStream.GetVolume(), id);
|
||||||
if (*_node == NULL)
|
if (*_node == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -151,7 +148,7 @@ Directory::GetNextNode(void *cookie, Node **_node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::Rewind(void *cookie)
|
Directory::Rewind(void *cookie)
|
||||||
{
|
{
|
||||||
TreeIterator *iterator = (TreeIterator *)cookie;
|
TreeIterator *iterator = (TreeIterator *)cookie;
|
||||||
@@ -160,7 +157,7 @@ Directory::Rewind(void *cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Directory::IsEmpty()
|
Directory::IsEmpty()
|
||||||
{
|
{
|
||||||
TreeIterator iterator(&fTree);
|
TreeIterator iterator(&fTree);
|
||||||
@@ -187,7 +184,7 @@ Directory::IsEmpty()
|
|||||||
status_t
|
status_t
|
||||||
Directory::GetName(char *name, size_t size) const
|
Directory::GetName(char *name, size_t size) const
|
||||||
{
|
{
|
||||||
if (fStream.InodeNum() == fStream.GetVolume().Root()) {
|
if (fStream.inode_num == fStream.GetVolume().Root()) {
|
||||||
strlcpy(name, fStream.GetVolume().SuperBlock().name, size);
|
strlcpy(name, fStream.GetVolume().SuperBlock().name, size);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ namespace BFS {
|
|||||||
|
|
||||||
class Directory : public ::Directory {
|
class Directory : public ::Directory {
|
||||||
public:
|
public:
|
||||||
Directory(Volume &volume, ::Directory* parent, block_run run);
|
Directory(Volume &volume, block_run run);
|
||||||
Directory(Volume &volume, ::Directory* parent, off_t id);
|
Directory(Volume &volume, off_t id);
|
||||||
Directory(::Directory* parent, const Stream &stream);
|
Directory(const Stream &stream);
|
||||||
virtual ~Directory();
|
virtual ~Directory();
|
||||||
|
|
||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
|
|||||||
@@ -106,47 +106,31 @@ CachedBlock::SetTo(block_run run)
|
|||||||
|
|
||||||
Stream::Stream(Volume &volume, block_run run)
|
Stream::Stream(Volume &volume, block_run run)
|
||||||
:
|
:
|
||||||
fVolume(volume),
|
fVolume(volume)
|
||||||
fInode(NULL)
|
|
||||||
{
|
{
|
||||||
_LoadInode(volume.ToOffset(run));
|
if (read_pos(volume.Device(), volume.ToOffset(run), this, sizeof(bfs_inode)) != sizeof(bfs_inode))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Stream::Stream(Volume &volume, off_t id)
|
Stream::Stream(Volume &volume, off_t id)
|
||||||
:
|
:
|
||||||
fVolume(volume),
|
fVolume(volume)
|
||||||
fInode(NULL)
|
|
||||||
{
|
{
|
||||||
_LoadInode(volume.ToOffset(id));
|
if (read_pos(volume.Device(), volume.ToOffset(id), this, sizeof(bfs_inode)) != sizeof(bfs_inode))
|
||||||
}
|
return;
|
||||||
|
|
||||||
|
|
||||||
Stream::Stream(const Stream& other)
|
|
||||||
:
|
|
||||||
fVolume(other.fVolume),
|
|
||||||
fInode(NULL)
|
|
||||||
{
|
|
||||||
_UseInode(other.fInode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Stream::~Stream()
|
Stream::~Stream()
|
||||||
{
|
{
|
||||||
if (fInode != NULL) {
|
|
||||||
if (--(((int32*)fInode)[-1]) == 0)
|
|
||||||
free((int32*)fInode - 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Stream::InitCheck()
|
Stream::InitCheck()
|
||||||
{
|
{
|
||||||
if (fInode == NULL)
|
return bfs_inode::InitCheck(&fVolume);
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
return fInode->InitCheck(&fVolume);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -157,12 +141,12 @@ Stream::GetNextSmallData(const small_data **_smallData) const
|
|||||||
|
|
||||||
// begin from the start?
|
// begin from the start?
|
||||||
if (smallData == NULL)
|
if (smallData == NULL)
|
||||||
smallData = fInode->small_data_start;
|
smallData = small_data_start;
|
||||||
else
|
else
|
||||||
smallData = smallData->Next();
|
smallData = smallData->Next();
|
||||||
|
|
||||||
// is already last item?
|
// is already last item?
|
||||||
if (smallData->IsLast(fInode))
|
if (smallData->IsLast(this))
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
*_smallData = smallData;
|
*_smallData = smallData;
|
||||||
@@ -171,7 +155,7 @@ Stream::GetNextSmallData(const small_data **_smallData) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Stream::GetName(char *name, size_t size) const
|
Stream::GetName(char *name, size_t size) const
|
||||||
{
|
{
|
||||||
const small_data *smallData = NULL;
|
const small_data *smallData = NULL;
|
||||||
@@ -186,17 +170,17 @@ Stream::GetName(char *name, size_t size) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Stream::ReadLink(char *buffer, size_t bufferSize)
|
Stream::ReadLink(char *buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
// link in the stream
|
// link in the stream
|
||||||
|
|
||||||
if (fInode->Flags() & INODE_LONG_SYMLINK)
|
if (Flags() & INODE_LONG_SYMLINK)
|
||||||
return ReadAt(0, (uint8 *)buffer, &bufferSize);
|
return ReadAt(0, (uint8 *)buffer, &bufferSize);
|
||||||
|
|
||||||
// link in the inode
|
// link in the inode
|
||||||
|
|
||||||
strlcpy(buffer, fInode->short_symlink, bufferSize);
|
strlcpy(buffer, short_symlink, bufferSize);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,25 +190,21 @@ Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
|
|||||||
{
|
{
|
||||||
// find matching block run
|
// find matching block run
|
||||||
|
|
||||||
if (fInode->data.MaxDirectRange() > 0
|
if (data.MaxDirectRange() > 0 && pos >= data.MaxDirectRange()) {
|
||||||
&& pos >= fInode->data.MaxDirectRange()) {
|
if (data.MaxDoubleIndirectRange() > 0 && pos >= data.MaxIndirectRange()) {
|
||||||
if (fInode->data.MaxDoubleIndirectRange() > 0
|
|
||||||
&& pos >= fInode->data.MaxIndirectRange()) {
|
|
||||||
// access to double indirect blocks
|
// access to double indirect blocks
|
||||||
|
|
||||||
CachedBlock cached(fVolume);
|
CachedBlock cached(fVolume);
|
||||||
|
|
||||||
off_t start = pos - fInode->data.MaxIndirectRange();
|
off_t start = pos - data.MaxIndirectRange();
|
||||||
int32 indirectSize
|
int32 indirectSize = (1L << (INDIRECT_BLOCKS_SHIFT + cached.BlockShift()))
|
||||||
= (1L << (INDIRECT_BLOCKS_SHIFT + cached.BlockShift()))
|
* (fVolume.BlockSize() / sizeof(block_run));
|
||||||
* (fVolume.BlockSize() / sizeof(block_run));
|
|
||||||
int32 directSize = NUM_ARRAY_BLOCKS << cached.BlockShift();
|
int32 directSize = NUM_ARRAY_BLOCKS << cached.BlockShift();
|
||||||
int32 index = start / indirectSize;
|
int32 index = start / indirectSize;
|
||||||
int32 runsPerBlock = cached.BlockSize() / sizeof(block_run);
|
int32 runsPerBlock = cached.BlockSize() / sizeof(block_run);
|
||||||
|
|
||||||
block_run *indirect = (block_run*)cached.SetTo(
|
block_run *indirect = (block_run *)cached.SetTo(
|
||||||
fVolume.ToBlock(fInode->data.double_indirect)
|
fVolume.ToBlock(data.double_indirect) + index / runsPerBlock);
|
||||||
+ index / runsPerBlock);
|
|
||||||
if (indirect == NULL)
|
if (indirect == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -233,25 +213,24 @@ Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
|
|||||||
|
|
||||||
int32 current = (start % indirectSize) / directSize;
|
int32 current = (start % indirectSize) / directSize;
|
||||||
|
|
||||||
indirect = (block_run*)cached.SetTo(
|
indirect = (block_run *)cached.SetTo(
|
||||||
fVolume.ToBlock(indirect[index % runsPerBlock]) + current / runsPerBlock);
|
fVolume.ToBlock(indirect[index % runsPerBlock]) + current / runsPerBlock);
|
||||||
if (indirect == NULL)
|
if (indirect == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
run = indirect[current % runsPerBlock];
|
run = indirect[current % runsPerBlock];
|
||||||
offset = fInode->data.MaxIndirectRange() + (index * indirectSize)
|
offset = data.MaxIndirectRange() + (index * indirectSize) + (current * directSize);
|
||||||
+ (current * directSize);
|
|
||||||
//printf("\tfCurrent = %ld, fRunFileOffset = %Ld, fRunBlockEnd = %Ld, fRun = %ld,%d\n",fCurrent,fRunFileOffset,fRunBlockEnd,fRun.allocation_group,fRun.start);
|
//printf("\tfCurrent = %ld, fRunFileOffset = %Ld, fRunBlockEnd = %Ld, fRun = %ld,%d\n",fCurrent,fRunFileOffset,fRunBlockEnd,fRun.allocation_group,fRun.start);
|
||||||
} else {
|
} else {
|
||||||
// access to indirect blocks
|
// access to indirect blocks
|
||||||
|
|
||||||
int32 runsPerBlock = fVolume.BlockSize() / sizeof(block_run);
|
int32 runsPerBlock = fVolume.BlockSize() / sizeof(block_run);
|
||||||
off_t runBlockEnd = fInode->data.MaxDirectRange();
|
off_t runBlockEnd = data.MaxDirectRange();
|
||||||
|
|
||||||
CachedBlock cached(fVolume);
|
CachedBlock cached(fVolume);
|
||||||
off_t block = fVolume.ToBlock(fInode->data.indirect);
|
off_t block = fVolume.ToBlock(data.indirect);
|
||||||
|
|
||||||
for (int32 i = 0;i < fInode->data.indirect.Length();i++) {
|
for (int32 i = 0;i < data.indirect.Length();i++) {
|
||||||
block_run *indirect = (block_run *)cached.SetTo(block + i);
|
block_run *indirect = (block_run *)cached.SetTo(block + i);
|
||||||
if (indirect == NULL)
|
if (indirect == NULL)
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
@@ -280,13 +259,12 @@ Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
|
|||||||
int32 current = -1;
|
int32 current = -1;
|
||||||
|
|
||||||
while (++current < NUM_DIRECT_BLOCKS) {
|
while (++current < NUM_DIRECT_BLOCKS) {
|
||||||
if (fInode->data.direct[current].IsZero())
|
if (data.direct[current].IsZero())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
runBlockEnd += fInode->data.direct[current].Length()
|
runBlockEnd += data.direct[current].Length() << fVolume.BlockShift();
|
||||||
<< fVolume.BlockShift();
|
|
||||||
if (runBlockEnd > pos) {
|
if (runBlockEnd > pos) {
|
||||||
run = fInode->data.direct[current];
|
run = data.direct[current];
|
||||||
offset = runBlockEnd - (run.Length() << fVolume.BlockShift());
|
offset = runBlockEnd - (run.Length() << fVolume.BlockShift());
|
||||||
//printf("### run[%ld] = (%ld,%d,%d), offset = %Ld\n",fCurrent,fRun.allocation_group,fRun.start,fRun.length,fRunFileOffset);
|
//printf("### run[%ld] = (%ld,%d,%d), offset = %Ld\n",fCurrent,fRun.allocation_group,fRun.start,fRun.length,fRunFileOffset);
|
||||||
return fVolume.ValidateBlockRun(run);
|
return fVolume.ValidateBlockRun(run);
|
||||||
@@ -306,15 +284,15 @@ Stream::ReadAt(off_t pos, uint8 *buffer, size_t *_length)
|
|||||||
|
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
if (pos >= fInode->data.Size()) {
|
if (pos >= data.Size()) {
|
||||||
*_length = 0;
|
*_length = 0;
|
||||||
return B_NO_ERROR;
|
return B_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t length = *_length;
|
size_t length = *_length;
|
||||||
|
|
||||||
if (pos + length > fInode->data.Size())
|
if (pos + length > data.Size())
|
||||||
length = fInode->data.Size() - pos;
|
length = data.Size() - pos;
|
||||||
|
|
||||||
block_run run;
|
block_run run;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
@@ -418,14 +396,14 @@ Stream::ReadAt(off_t pos, uint8 *buffer, size_t *_length)
|
|||||||
|
|
||||||
|
|
||||||
Node *
|
Node *
|
||||||
Stream::NodeFactory(Volume &volume, ::Directory* parent, off_t id)
|
Stream::NodeFactory(Volume &volume, off_t id)
|
||||||
{
|
{
|
||||||
Stream stream(volume, id);
|
Stream stream(volume, id);
|
||||||
if (stream.InitCheck() != B_OK)
|
if (stream.InitCheck() != B_OK)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (stream.IsContainer())
|
if (stream.IsContainer())
|
||||||
return new(nothrow) Directory(parent, stream);
|
return new(nothrow) Directory(stream);
|
||||||
|
|
||||||
if (stream.IsSymlink())
|
if (stream.IsSymlink())
|
||||||
return new(nothrow) Link(stream);
|
return new(nothrow) Link(stream);
|
||||||
@@ -434,43 +412,10 @@ Stream::NodeFactory(Volume &volume, ::Directory* parent, off_t id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
Stream::_LoadInode(off_t offset)
|
|
||||||
{
|
|
||||||
int32* inodeRef = (int32*)malloc(fVolume.BlockSize() + 4);
|
|
||||||
if (inodeRef == NULL) {
|
|
||||||
dprintf("Stream::_LoadInode(): Out of memory!\n");
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
fInode = (bfs_inode*)(inodeRef + 1);
|
|
||||||
*inodeRef = 1;
|
|
||||||
|
|
||||||
ssize_t bytesRead = read_pos(fVolume.Device(), offset, fInode,
|
|
||||||
fVolume.BlockSize());
|
|
||||||
if (bytesRead >= 0 && (size_t)bytesRead == fVolume.BlockSize())
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
free(inodeRef);
|
|
||||||
fInode = NULL;
|
|
||||||
|
|
||||||
return bytesRead < 0 ? bytesRead : B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Stream::_UseInode(bfs_inode* inode)
|
|
||||||
{
|
|
||||||
fInode = inode;
|
|
||||||
if (fInode != NULL)
|
|
||||||
((int32*)fInode)[-1]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
bfs_inode::InitCheck(Volume *volume)
|
bfs_inode::InitCheck(Volume *volume)
|
||||||
{
|
{
|
||||||
if (Flags() & INODE_NOT_READY) {
|
if (Flags() & INODE_NOT_READY) {
|
||||||
|
|||||||
@@ -6,23 +6,20 @@
|
|||||||
#ifndef STREAM_H
|
#ifndef STREAM_H
|
||||||
#define STREAM_H
|
#define STREAM_H
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <boot/vfs.h>
|
|
||||||
|
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
class Node;
|
class Node;
|
||||||
|
|
||||||
|
|
||||||
namespace BFS {
|
namespace BFS {
|
||||||
|
|
||||||
class Stream {
|
class Stream : public bfs_inode {
|
||||||
public:
|
public:
|
||||||
Stream(Volume &volume, block_run run);
|
Stream(Volume &volume, block_run run);
|
||||||
Stream(Volume &volume, off_t id);
|
Stream(Volume &volume, off_t id);
|
||||||
Stream(const Stream& other);
|
|
||||||
~Stream();
|
~Stream();
|
||||||
|
|
||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
@@ -32,27 +29,19 @@ class Stream {
|
|||||||
status_t ReadAt(off_t pos, uint8 *buffer, size_t *length);
|
status_t ReadAt(off_t pos, uint8 *buffer, size_t *length);
|
||||||
|
|
||||||
status_t GetName(char *name, size_t size) const;
|
status_t GetName(char *name, size_t size) const;
|
||||||
off_t Size() const { return fInode->data.Size(); }
|
off_t Size() const { return data.Size(); }
|
||||||
off_t ID() const { return fVolume.ToVnode(fInode->inode_num); }
|
off_t ID() const { return fVolume.ToVnode(inode_num); }
|
||||||
inode_addr InodeNum() const { return fInode->inode_num; }
|
|
||||||
int32 Mode() const { return fInode->Mode(); }
|
|
||||||
status_t ReadLink(char *buffer, size_t bufferSize);
|
status_t ReadLink(char *buffer, size_t bufferSize);
|
||||||
|
|
||||||
bool IsContainer() const { return Mode() & (S_IFDIR | S_INDEX_DIR | S_ATTR_DIR); }
|
bool IsContainer() const { return Mode() & (S_IFDIR | S_INDEX_DIR | S_ATTR_DIR); }
|
||||||
bool IsSymlink() const { return S_ISLNK(Mode()); }
|
bool IsSymlink() const { return S_ISLNK(Mode()); }
|
||||||
|
|
||||||
static Node *NodeFactory(Volume &volume, ::Directory* parent, off_t id);
|
static Node *NodeFactory(Volume &volume, off_t id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Stream& operator=(const Stream& other);
|
|
||||||
|
|
||||||
status_t GetNextSmallData(const small_data **_smallData) const;
|
status_t GetNextSmallData(const small_data **_smallData) const;
|
||||||
|
|
||||||
status_t _LoadInode(off_t offset);
|
Volume &fVolume;
|
||||||
void _UseInode(bfs_inode* inode);
|
|
||||||
|
|
||||||
Volume& fVolume;
|
|
||||||
bfs_inode* fInode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace BFS
|
} // namespace BFS
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ Volume::Volume(boot::Partition *partition)
|
|||||||
// try block 0 again (can only happen on the big endian BFS)
|
// try block 0 again (can only happen on the big endian BFS)
|
||||||
if (read_pos(fDevice, 0, &fSuperBlock, sizeof(disk_super_block)) < B_OK)
|
if (read_pos(fDevice, 0, &fSuperBlock, sizeof(disk_super_block)) < B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!IsValidSuperBlock())
|
if (!IsValidSuperBlock())
|
||||||
return;
|
return;
|
||||||
#else
|
#else
|
||||||
@@ -55,7 +55,7 @@ Volume::Volume(boot::Partition *partition)
|
|||||||
|
|
||||||
TRACE(("bfs: we do have a valid super block (name = %s)!\n", fSuperBlock.name));
|
TRACE(("bfs: we do have a valid super block (name = %s)!\n", fSuperBlock.name));
|
||||||
|
|
||||||
fRootNode = new(nothrow) BFS::Directory(*this, NULL, Root());
|
fRootNode = new(nothrow) BFS::Directory(*this, Root());
|
||||||
if (fRootNode == NULL)
|
if (fRootNode == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ Volume::~Volume()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::InitCheck()
|
Volume::InitCheck()
|
||||||
{
|
{
|
||||||
if (fDevice < B_OK)
|
if (fDevice < B_OK)
|
||||||
@@ -118,7 +118,7 @@ Volume::ValidateBlockRun(block_run run)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
block_run
|
block_run
|
||||||
Volume::ToBlockRun(off_t block) const
|
Volume::ToBlockRun(off_t block) const
|
||||||
{
|
{
|
||||||
block_run run;
|
block_run run;
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class File : public ::Node, public Entry {
|
|||||||
|
|
||||||
class Directory : public ::Directory, public Entry {
|
class Directory : public ::Directory, public Entry {
|
||||||
public:
|
public:
|
||||||
Directory(::Directory* parent, const char* name);
|
Directory(const char *name);
|
||||||
virtual ~Directory();
|
virtual ~Directory();
|
||||||
|
|
||||||
virtual status_t Open(void **_cookie, int mode);
|
virtual status_t Open(void **_cookie, int mode);
|
||||||
@@ -181,7 +181,7 @@ bool
|
|||||||
skip_gzip_header(z_stream *stream)
|
skip_gzip_header(z_stream *stream)
|
||||||
{
|
{
|
||||||
uint8 *buffer = (uint8 *)stream->next_in;
|
uint8 *buffer = (uint8 *)stream->next_in;
|
||||||
|
|
||||||
// check magic and skip method
|
// check magic and skip method
|
||||||
if (buffer[0] != 0x1f || buffer[1] != 0x8b)
|
if (buffer[0] != 0x1f || buffer[1] != 0x8b)
|
||||||
return false;
|
return false;
|
||||||
@@ -306,10 +306,8 @@ TarFS::File::Inode() const
|
|||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
TarFS::Directory::Directory(::Directory* parent, const char* name)
|
TarFS::Directory::Directory(const char *name)
|
||||||
:
|
: TarFS::Entry(name)
|
||||||
::Directory(parent),
|
|
||||||
TarFS::Entry(name)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,7 +321,7 @@ TarFS::Directory::~Directory()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::Open(void **_cookie, int mode)
|
TarFS::Directory::Open(void **_cookie, int mode)
|
||||||
{
|
{
|
||||||
_inherited::Open(_cookie, mode);
|
_inherited::Open(_cookie, mode);
|
||||||
@@ -338,7 +336,7 @@ TarFS::Directory::Open(void **_cookie, int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::Close(void *cookie)
|
TarFS::Directory::Close(void *cookie)
|
||||||
{
|
{
|
||||||
_inherited::Close(cookie);
|
_inherited::Close(cookie);
|
||||||
@@ -397,7 +395,7 @@ TarFS::Directory::Lookup(const char *name, bool traverseLinks)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::GetNextEntry(void *_cookie, char *name, size_t size)
|
TarFS::Directory::GetNextEntry(void *_cookie, char *name, size_t size)
|
||||||
{
|
{
|
||||||
EntryIterator *iterator = (EntryIterator *)_cookie;
|
EntryIterator *iterator = (EntryIterator *)_cookie;
|
||||||
@@ -412,7 +410,7 @@ TarFS::Directory::GetNextEntry(void *_cookie, char *name, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::GetNextNode(void *_cookie, Node **_node)
|
TarFS::Directory::GetNextNode(void *_cookie, Node **_node)
|
||||||
{
|
{
|
||||||
EntryIterator *iterator = (EntryIterator *)_cookie;
|
EntryIterator *iterator = (EntryIterator *)_cookie;
|
||||||
@@ -426,12 +424,12 @@ TarFS::Directory::GetNextNode(void *_cookie, Node **_node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TarFS::Directory::Rewind(void *_cookie)
|
TarFS::Directory::Rewind(void *_cookie)
|
||||||
{
|
{
|
||||||
EntryIterator *iterator = (EntryIterator *)_cookie;
|
EntryIterator *iterator = (EntryIterator *)_cookie;
|
||||||
*iterator = fEntries.GetIterator();
|
*iterator = fEntries.GetIterator();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -460,7 +458,7 @@ TarFS::Directory::AddDirectory(char *dirName, TarFS::Directory **_dir)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
} else {
|
} else {
|
||||||
// doesn't exist yet -- create it
|
// doesn't exist yet -- create it
|
||||||
dir = new(nothrow) TarFS::Directory(this, dirName);
|
dir = new(nothrow) TarFS::Directory(dirName);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -519,7 +517,7 @@ TarFS::Directory::AddFile(tar_header *header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TarFS::Directory::IsEmpty()
|
TarFS::Directory::IsEmpty()
|
||||||
{
|
{
|
||||||
return fEntries.IsEmpty();
|
return fEntries.IsEmpty();
|
||||||
@@ -599,7 +597,7 @@ TarFS::Symlink::Inode() const
|
|||||||
|
|
||||||
|
|
||||||
TarFS::Volume::Volume()
|
TarFS::Volume::Volume()
|
||||||
: TarFS::Directory(NULL, "Boot from CD-ROM")
|
: TarFS::Directory("Boot from CD-ROM")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2008, Axel Dörfler, [email protected].
|
* Copyright 2003-2005, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -51,32 +51,7 @@ is_bootable(Directory *volume)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Replace the first path component with "boot", as the kernel will always
|
status_t
|
||||||
mount the boot volume there.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
to_boot_path(char *path, size_t pathSize)
|
|
||||||
{
|
|
||||||
const size_t bootLength = strlen("boot");
|
|
||||||
|
|
||||||
if (path[0] != '/' || pathSize < bootLength + 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
char *second = strchr(path + 1, '/');
|
|
||||||
if (second == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
size_t volumeLength = second - path - 1;
|
|
||||||
if (volumeLength != bootLength) {
|
|
||||||
memmove(path + 1 + bootLength, path + 1 + volumeLength,
|
|
||||||
pathSize - 1 - max_c(volumeLength, bootLength));
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(path + 1, "boot", bootLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
load_kernel(stage2_args *args, Directory *volume)
|
load_kernel(stage2_args *args, Directory *volume)
|
||||||
{
|
{
|
||||||
int fd = open_from(volume, KERNEL_PATH, O_RDONLY);
|
int fd = open_from(volume, KERNEL_PATH, O_RDONLY);
|
||||||
@@ -100,13 +75,6 @@ load_kernel(stage2_args *args, Directory *volume)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
char tempPath[B_PATH_NAME_LENGTH];
|
|
||||||
if (volume->GetPath(KERNEL_PATH, tempPath, sizeof(tempPath)) == B_OK) {
|
|
||||||
to_boot_path(tempPath, sizeof(tempPath));
|
|
||||||
gKernelArgs.kernel_image.name = kernel_args_strdup(tempPath);
|
|
||||||
} else
|
|
||||||
gKernelArgs.kernel_image.name = kernel_args_strdup("kernel");
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,11 +111,12 @@ load_modules_from(Directory *volume, const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Loads a module by module name. This basically works in the same
|
/** Loads a module by module name. This basically works in the same
|
||||||
way as the kernel module loader; it will cut off the last part
|
* way as the kernel module loader; it will cut off the last part
|
||||||
of the module name until it could find a module and loads it.
|
* of the module name until it could find a module and loads it.
|
||||||
It tests both, kernel and user module directories.
|
* It tests both, kernel and user module directories.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
load_module(Directory *volume, const char *name)
|
load_module(Directory *volume, const char *name)
|
||||||
{
|
{
|
||||||
@@ -193,7 +162,7 @@ load_module(Directory *volume, const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
load_modules(stage2_args *args, Directory *volume)
|
load_modules(stage2_args *args, Directory *volume)
|
||||||
{
|
{
|
||||||
int32 failed = 0;
|
int32 failed = 0;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2008, Axel Dörfler, [email protected].
|
** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
** Distributed under the terms of the OpenBeOS License.
|
||||||
*/
|
*/
|
||||||
#ifndef LOADER_H
|
#ifndef LOADER_H
|
||||||
#define LOADER_H
|
#define LOADER_H
|
||||||
|
|
||||||
@@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
|
|
||||||
extern bool is_bootable(Directory *volume);
|
extern bool is_bootable(Directory *volume);
|
||||||
extern void to_boot_path(char *path, size_t pathSize);
|
|
||||||
extern status_t load_kernel(stage2_args *args, Directory *volume);
|
extern status_t load_kernel(stage2_args *args, Directory *volume);
|
||||||
extern status_t load_modules(stage2_args *args, Directory *volume);
|
extern status_t load_modules(stage2_args *args, Directory *volume);
|
||||||
|
|
||||||
|
|||||||
@@ -92,21 +92,21 @@ Node::Close(void *cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Node::GetName(char *nameBuffer, size_t bufferSize) const
|
Node::GetName(char *nameBuffer, size_t bufferSize) const
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
Node::Type() const
|
Node::Type() const
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
off_t
|
off_t
|
||||||
Node::Size() const
|
Node::Size() const
|
||||||
{
|
{
|
||||||
return 0LL;
|
return 0LL;
|
||||||
@@ -120,7 +120,7 @@ Node::Inode() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Node::Acquire()
|
Node::Acquire()
|
||||||
{
|
{
|
||||||
fRefCount++;
|
fRefCount++;
|
||||||
@@ -128,7 +128,7 @@ Node::Acquire()
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Node::Release()
|
Node::Release()
|
||||||
{
|
{
|
||||||
TRACE(("%p::Release(), fRefCount = %ld\n", this, fRefCount));
|
TRACE(("%p::Release(), fRefCount = %ld\n", this, fRefCount));
|
||||||
@@ -168,98 +168,27 @@ ConsoleNode::Write(const void *buffer, size_t bufferSize)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
Directory::Directory(Directory* parent)
|
Directory::Directory()
|
||||||
:
|
: Node()
|
||||||
Node(),
|
|
||||||
fParent(NULL)
|
|
||||||
{
|
{
|
||||||
SetParent(parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Directory::~Directory()
|
ssize_t
|
||||||
{
|
|
||||||
SetParent(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Directory*
|
|
||||||
Directory::Parent() const
|
|
||||||
{
|
|
||||||
return fParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Directory::SetParent(Directory* parent)
|
|
||||||
{
|
|
||||||
if (fParent != NULL)
|
|
||||||
fParent->Release();
|
|
||||||
|
|
||||||
fParent = parent;
|
|
||||||
|
|
||||||
if (fParent != NULL)
|
|
||||||
fParent->Acquire();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
Directory::GetPath(const char* entry, char* buffer, size_t bufferSize)
|
|
||||||
{
|
|
||||||
// get parent path, if any
|
|
||||||
if (fParent != NULL) {
|
|
||||||
status_t error = fParent->GetPath(NULL, buffer, bufferSize);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
size_t len = strlen(buffer);
|
|
||||||
if (len == 0)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
if (buffer[len - 1] != '/') {
|
|
||||||
if (len == bufferSize)
|
|
||||||
return B_BUFFER_OVERFLOW;
|
|
||||||
|
|
||||||
buffer[len++] = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer += len;
|
|
||||||
bufferSize -= len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// append directory name
|
|
||||||
status_t error = GetName(buffer, bufferSize);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
if (entry == NULL)
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
// append entry name
|
|
||||||
if (strlcat(buffer, "/", bufferSize) >= bufferSize
|
|
||||||
|| strlcat(buffer, entry, bufferSize) >= bufferSize) {
|
|
||||||
return B_BUFFER_OVERFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
Directory::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
Directory::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
Directory::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
|
Directory::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
Directory::Type() const
|
Directory::Type() const
|
||||||
{
|
{
|
||||||
return S_IFDIR;
|
return S_IFDIR;
|
||||||
@@ -336,7 +265,7 @@ Descriptor::~Descriptor()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
Descriptor::Read(void *buffer, size_t bufferSize)
|
Descriptor::Read(void *buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
ssize_t bytesRead = fNode->ReadAt(fCookie, fOffset, buffer, bufferSize);
|
ssize_t bytesRead = fNode->ReadAt(fCookie, fOffset, buffer, bufferSize);
|
||||||
@@ -347,7 +276,7 @@ Descriptor::Read(void *buffer, size_t bufferSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
Descriptor::ReadAt(off_t pos, void *buffer, size_t bufferSize)
|
Descriptor::ReadAt(off_t pos, void *buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
return fNode->ReadAt(fCookie, pos, buffer, bufferSize);
|
return fNode->ReadAt(fCookie, pos, buffer, bufferSize);
|
||||||
@@ -422,7 +351,7 @@ status_t
|
|||||||
register_boot_file_system(Directory *volume)
|
register_boot_file_system(Directory *volume)
|
||||||
{
|
{
|
||||||
gRoot->AddLink("boot", volume);
|
gRoot->AddLink("boot", volume);
|
||||||
|
|
||||||
Partition *partition;
|
Partition *partition;
|
||||||
status_t status = gRoot->GetPartitionFor(volume, &partition);
|
status_t status = gRoot->GetPartitionFor(volume, &partition);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
@@ -647,7 +576,7 @@ open_node(Node *node, int mode)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// get free descriptor
|
// get free descriptor
|
||||||
|
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
for (; fd < MAX_VFS_DESCRIPTORS; fd++) {
|
for (; fd < MAX_VFS_DESCRIPTORS; fd++) {
|
||||||
if (sDescriptors[fd] == NULL)
|
if (sDescriptors[fd] == NULL)
|
||||||
@@ -659,7 +588,7 @@ open_node(Node *node, int mode)
|
|||||||
TRACE(("got descriptor %d for node %p\n", fd, node));
|
TRACE(("got descriptor %d for node %p\n", fd, node));
|
||||||
|
|
||||||
// we got a free descriptor entry, now try to open the node
|
// we got a free descriptor entry, now try to open the node
|
||||||
|
|
||||||
void *cookie;
|
void *cookie;
|
||||||
status_t status = node->Open(&cookie, mode);
|
status_t status = node->Open(&cookie, mode);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
|
|||||||
@@ -4052,6 +4052,8 @@ vm_init(kernel_args *args)
|
|||||||
|
|
||||||
allocate_kernel_args(args);
|
allocate_kernel_args(args);
|
||||||
|
|
||||||
|
args->kernel_image.name = "kernel";
|
||||||
|
// the lazy boot loader currently doesn't set the kernel's name...
|
||||||
create_preloaded_image_areas(&args->kernel_image);
|
create_preloaded_image_areas(&args->kernel_image);
|
||||||
|
|
||||||
// allocate areas for preloaded images
|
// allocate areas for preloaded images
|
||||||
|
|||||||
Reference in New Issue
Block a user