TAR fs is now also working correctly in the real boot loader.
Some more cleanup and better error output. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14370 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8d156f1c5e
commit
0ecc530bf0
@ -5,6 +5,7 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "tarfs.h"
|
#include "tarfs.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -24,6 +25,14 @@
|
|||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
|
||||||
|
//#define TRACE_TARFS
|
||||||
|
#ifdef TRACE_TARFS
|
||||||
|
# define TRACE(x) dprintf x
|
||||||
|
#else
|
||||||
|
# define TRACE(x) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static const uint32 kCompressedArchiveOffset = 192 * 1024; // at 192 kB
|
static const uint32 kCompressedArchiveOffset = 192 * 1024; // at 192 kB
|
||||||
static const size_t kTarRegionSize = 4 * 1024 * 1024; // 4 MB
|
static const size_t kTarRegionSize = 4 * 1024 * 1024; // 4 MB
|
||||||
|
|
||||||
@ -32,7 +41,8 @@ namespace TarFS {
|
|||||||
struct RegionDelete {
|
struct RegionDelete {
|
||||||
inline void operator()(void *memory)
|
inline void operator()(void *memory)
|
||||||
{
|
{
|
||||||
platform_free_region(memory, kTarRegionSize);
|
if (memory != NULL)
|
||||||
|
platform_free_region(memory, kTarRegionSize);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,14 +55,12 @@ class Directory;
|
|||||||
|
|
||||||
class Entry : public DoublyLinkedListLinkImpl<Entry> {
|
class Entry : public DoublyLinkedListLinkImpl<Entry> {
|
||||||
public:
|
public:
|
||||||
Entry(const char *name) : fName(name) {
|
Entry(const char *name) : fName(name) {}
|
||||||
printf("created Entry %p: %s\n", this, fName);
|
|
||||||
}
|
|
||||||
virtual ~Entry() {}
|
virtual ~Entry() {}
|
||||||
|
|
||||||
const char *Name() const { return fName; }
|
const char *Name() const { return fName; }
|
||||||
virtual ::Node *ToNode() = 0;
|
virtual ::Node *ToNode() = 0;
|
||||||
virtual TarFS::Directory *ToTarDirectory() { return NULL; }
|
virtual TarFS::Directory *ToTarDirectory() { return NULL; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const char *fName;
|
const char *fName;
|
||||||
@ -195,6 +203,8 @@ TarFS::Node::~Node()
|
|||||||
ssize_t
|
ssize_t
|
||||||
TarFS::Node::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
TarFS::Node::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
|
TRACE(("tarfs: read at %Ld, %lu bytes, fSize = %Ld\n", pos, bufferSize, fSize));
|
||||||
|
|
||||||
if (pos < 0 || !buffer)
|
if (pos < 0 || !buffer)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
@ -205,7 +215,7 @@ TarFS::Node::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
|||||||
if (toRead > bufferSize)
|
if (toRead > bufferSize)
|
||||||
toRead = bufferSize;
|
toRead = bufferSize;
|
||||||
|
|
||||||
memcpy(buffer, (char*)fHeader + 512 + pos, toRead);
|
memcpy(buffer, (char*)fHeader + BLOCK_SIZE + pos, toRead);
|
||||||
|
|
||||||
return toRead;
|
return toRead;
|
||||||
}
|
}
|
||||||
@ -455,7 +465,7 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
cookie(cookie)
|
cookie(cookie)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~PartitionCloser()
|
~PartitionCloser()
|
||||||
{
|
{
|
||||||
partition->Close(cookie);
|
partition->Close(cookie);
|
||||||
@ -502,8 +512,10 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
if (platform_allocate_region((void **)&out, kTarRegionSize,
|
if (platform_allocate_region((void **)&out, kTarRegionSize,
|
||||||
B_READ_AREA | B_WRITE_AREA) != B_OK)
|
B_READ_AREA | B_WRITE_AREA) != B_OK) {
|
||||||
|
TRACE(("tarfs: allocating region failed!\n"));
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
regionDeleter.SetTo(out);
|
regionDeleter.SetTo(out);
|
||||||
zStream.avail_out = kTarRegionSize;
|
zStream.avail_out = kTarRegionSize;
|
||||||
@ -518,13 +530,15 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
offset += sizeof(in);
|
offset += sizeof(in);
|
||||||
|
|
||||||
if (zStream.avail_in != 0 && status != Z_STREAM_END)
|
if (zStream.avail_in != 0 && status != Z_STREAM_END)
|
||||||
printf("buhuuu");
|
dprintf("tarfs: didn't read whole block!\n");
|
||||||
} while (status == Z_OK);
|
} while (status == Z_OK);
|
||||||
|
|
||||||
inflateEnd(&zStream);
|
inflateEnd(&zStream);
|
||||||
|
|
||||||
if (status != Z_STREAM_END)
|
if (status != Z_STREAM_END) {
|
||||||
|
TRACE(("tarfs: inflating failed: %d!\n", status));
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
|
|
||||||
@ -543,8 +557,7 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
|
|
||||||
if (strcmp(header->magic, kTarHeaderMagic) != 0) {
|
if (strcmp(header->magic, kTarHeaderMagic) != 0) {
|
||||||
if (strcmp(header->magic, kOldTarHeaderMagic) != 0) {
|
if (strcmp(header->magic, kOldTarHeaderMagic) != 0) {
|
||||||
fprintf(stderr, "Bad tar header magic in block %d.\n",
|
dprintf("Bad tar header magic in block %d.\n", blockIndex);
|
||||||
blockIndex);
|
|
||||||
status = B_BAD_DATA;
|
status = B_BAD_DATA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -552,6 +565,8 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
|
|
||||||
off_t size = strtol(header->size, NULL, 8);
|
off_t size = strtol(header->size, NULL, 8);
|
||||||
|
|
||||||
|
TRACE(("tarfs: \"%s\", %Ld bytes\n", header->name, size));
|
||||||
|
|
||||||
// TODO: this is old-style GNU tar which probably won't work with newer ones...
|
// TODO: this is old-style GNU tar which probably won't work with newer ones...
|
||||||
switch (header->type) {
|
switch (header->type) {
|
||||||
case TAR_FILE:
|
case TAR_FILE:
|
||||||
@ -593,12 +608,12 @@ TarFS::Volume::Init(boot::Partition *partition)
|
|||||||
static status_t
|
static status_t
|
||||||
tarfs_get_file_system(boot::Partition *partition, ::Directory **_root)
|
tarfs_get_file_system(boot::Partition *partition, ::Directory **_root)
|
||||||
{
|
{
|
||||||
// TODO: Who owns the Volume object created here?
|
|
||||||
TarFS::Volume *volume = new TarFS::Volume;
|
TarFS::Volume *volume = new TarFS::Volume;
|
||||||
if (volume == NULL)
|
if (volume == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (volume->Init(partition) < B_OK) {
|
if (volume->Init(partition) < B_OK) {
|
||||||
|
TRACE(("Initializing tarfs failed\n"));
|
||||||
delete volume;
|
delete volume;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user