Compare commits
36 Commits
bb5551bdfe
...
c0d188f7b3
Author | SHA1 | Date |
---|---|---|
Jonas 'Sortie' Termansen | c0d188f7b3 | |
Jonas 'Sortie' Termansen | 2132778b48 | |
Jonas 'Sortie' Termansen | 6a64cc5182 | |
Jonas 'Sortie' Termansen | f19b102315 | |
Jonas 'Sortie' Termansen | 8cdacf2b86 | |
Jonas 'Sortie' Termansen | b0a55a5652 | |
Jonas 'Sortie' Termansen | 40067cecca | |
Jonas 'Sortie' Termansen | 53fa8f4157 | |
Jonas 'Sortie' Termansen | b3ec15f67b | |
Jonas 'Sortie' Termansen | 864f3c3bf0 | |
Jonas 'Sortie' Termansen | 285b35e8ee | |
Jonas 'Sortie' Termansen | 719f44ec8a | |
Jonas 'Sortie' Termansen | 835b156274 | |
Jonas 'Sortie' Termansen | 1b9c61c559 | |
Jonas 'Sortie' Termansen | 88ea91c9e5 | |
Jonas 'Sortie' Termansen | edc6a870e7 | |
Jonas 'Sortie' Termansen | 9ec3997a58 | |
Jonas 'Sortie' Termansen | 107db32735 | |
Jonas 'Sortie' Termansen | 47c8fc1381 | |
Jonas 'Sortie' Termansen | f0e8196715 | |
Jonas 'Sortie' Termansen | b24e46107d | |
Jonas 'Sortie' Termansen | d884a034c0 | |
Jonas 'Sortie' Termansen | 10c0f3b714 | |
Jonas 'Sortie' Termansen | cbb2243b70 | |
Jonas 'Sortie' Termansen | ce2238c3d3 | |
Jonas 'Sortie' Termansen | 3a80f6eb76 | |
Jonas 'Sortie' Termansen | 312edb6a27 | |
Jonas 'Sortie' Termansen | 8955c6b85c | |
Jonas 'Sortie' Termansen | 1534a67b8d | |
Jonas 'Sortie' Termansen | 47ef7c7109 | |
Jonas 'Sortie' Termansen | 701f9025c9 | |
Jonas 'Sortie' Termansen | b4665bc8ce | |
Jonas 'Sortie' Termansen | 2465f9b5dc | |
Jonas 'Sortie' Termansen | 95cf3fba98 | |
Jonas 'Sortie' Termansen | dc98bcf0ca | |
Jonas 'Sortie' Termansen | 4aadc182a6 |
8
Makefile
8
Makefile
|
@ -20,6 +20,7 @@ display \
|
|||
dnsconfig \
|
||||
editor \
|
||||
ext \
|
||||
fat \
|
||||
games \
|
||||
host \
|
||||
hostname \
|
||||
|
@ -255,7 +256,7 @@ sysroot-system: sysroot-fsh sysroot-base-headers
|
|||
|| exit $$?; done)
|
||||
LC_ALL=C sort -u "$(SYSROOT)/tix/manifest/system" > "$(SYSROOT)/tix/manifest/system.new"
|
||||
mv "$(SYSROOT)/tix/manifest/system.new" "$(SYSROOT)/tix/manifest/system"
|
||||
printf 'TIX_VERSION=3\nNAME=system\nPLATFORM=x86_64-sortix\nPREFIX=\nSYSTEM=true\n' > "$(SYSROOT)/tix/tixinfo/system"
|
||||
printf 'TIX_VERSION=3\nNAME=system\nPLATFORM=$(HOST)\nPREFIX=\nSYSTEM=true\n' > "$(SYSROOT)/tix/tixinfo/system"
|
||||
|
||||
.PHONY: sysroot-source
|
||||
sysroot-source: sysroot-fsh
|
||||
|
@ -634,17 +635,12 @@ $(SORTIX_RELEASE_DIR)/$(RELEASE)/$(MACHINE)/boot/overlay.tar.xz: $(OVERLAY_INITR
|
|||
$(SORTIX_RELEASE_DIR)/$(RELEASE)/$(MACHINE)/boot/src.tar.xz: $(SRC_INITRD) $(SORTIX_RELEASE_DIR)/$(RELEASE)/$(MACHINE)/boot
|
||||
xz -c $< > $@
|
||||
|
||||
# TODO: Temporary compatibility.
|
||||
$(SORTIX_RELEASE_DIR)/$(RELEASE)/$(MACHINE)/boot/system.tar.xz: $(SYSTEM_INITRD) $(SORTIX_RELEASE_DIR)/$(RELEASE)/$(MACHINE)/boot
|
||||
xz -c $< > $@
|
||||
|
||||
.PHONY: release-boot
|
||||
release-boot: \
|
||||
$(SORTIX_RELEASE_DIR)/$(RELEASE)/$(MACHINE)/boot/sortix.bin.xz \
|
||||
$(SORTIX_RELEASE_DIR)/$(RELEASE)/$(MACHINE)/boot/live.tar.xz \
|
||||
$(SORTIX_RELEASE_DIR)/$(RELEASE)/$(MACHINE)/boot/overlay.tar.xz \
|
||||
$(SORTIX_RELEASE_DIR)/$(RELEASE)/$(MACHINE)/boot/src.tar.xz \
|
||||
$(SORTIX_RELEASE_DIR)/$(RELEASE)/$(MACHINE)/boot/system.tar.xz \
|
||||
|
||||
.PHONY: release-iso
|
||||
release-iso: $(SORTIX_RELEASE_DIR)/$(RELEASE)/builds/$(BUILD_NAME).iso
|
||||
|
|
|
@ -127,9 +127,9 @@ if $mount; then
|
|||
ports=
|
||||
else
|
||||
ports=$(ls repository |
|
||||
grep -E '\.tix\.tar\.xz$' |
|
||||
sed -E 's/\.tix\.tar\.xz$//' |
|
||||
(grep -Ev '^system$' || true))
|
||||
grep -E '\.tix\.tar\.xz$' |
|
||||
sed -E 's/\.tix\.tar\.xz$//' |
|
||||
(grep -Ev '^system$' || true))
|
||||
fi
|
||||
|
||||
mkdir -p boot/grub
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
set_minimal="cut dash e2fsprogs grep grub libssl mdocml sed signify tar wget xargs xz"
|
||||
set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip libcurl libcurses libstdc++ make m4 nano ntpd patch perl pkg-config python ssh texinfo vim"
|
||||
set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip libcurl libcurses libstdc++ m4 make nano ntpd patch perl pkg-config python ssh texinfo vim xorriso"
|
||||
sets="basic minimal"
|
||||
|
|
|
@ -2187,6 +2187,7 @@ static void on_mkpart(size_t argc, char** argv)
|
|||
const char* mkfs_argv[] =
|
||||
{
|
||||
"mformat",
|
||||
"-F", // TODO: Force FAT32 until FAT12/16 root dir writing is added.
|
||||
"-i",
|
||||
p->path,
|
||||
NULL
|
||||
|
|
|
@ -1,276 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2014, 2015 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* blockgroup.cpp
|
||||
* Filesystem block group.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ext-constants.h"
|
||||
#include "ext-structs.h"
|
||||
|
||||
#include "block.h"
|
||||
#include "blockgroup.h"
|
||||
#include "device.h"
|
||||
#include "filesystem.h"
|
||||
#include "util.h"
|
||||
|
||||
BlockGroup::BlockGroup(Filesystem* filesystem, uint32_t group_id)
|
||||
{
|
||||
this->data_block = NULL;
|
||||
this->data = NULL;
|
||||
this->filesystem = filesystem;
|
||||
this->block_bitmap_chunk = NULL;
|
||||
this->inode_bitmap_chunk = NULL;
|
||||
this->reference_count = 1;
|
||||
this->group_id = group_id;
|
||||
this->block_alloc_chunk = 0;
|
||||
this->inode_alloc_chunk = 0;
|
||||
this->block_bitmap_chunk_i = 0;
|
||||
this->inode_bitmap_chunk_i = 0;
|
||||
this->first_block_id = filesystem->sb->s_first_data_block +
|
||||
filesystem->sb->s_blocks_per_group * group_id;
|
||||
this->first_inode_id = 1 +
|
||||
filesystem->sb->s_inodes_per_group * group_id;
|
||||
this->num_blocks = group_id+1== filesystem->num_groups ?
|
||||
filesystem->num_blocks - first_block_id :
|
||||
filesystem->sb->s_blocks_per_group;
|
||||
this->num_inodes = group_id+1== filesystem->num_groups ?
|
||||
filesystem->num_inodes - first_inode_id :
|
||||
filesystem->sb->s_inodes_per_group;
|
||||
size_t num_chunk_bits = filesystem->block_size * 8UL;
|
||||
this->num_block_bitmap_chunks = divup(num_blocks, (uint32_t) num_chunk_bits);
|
||||
this->num_inode_bitmap_chunks = divup(num_inodes, (uint32_t) num_chunk_bits);
|
||||
this->dirty = false;
|
||||
}
|
||||
|
||||
BlockGroup::~BlockGroup()
|
||||
{
|
||||
Sync();
|
||||
if ( block_bitmap_chunk )
|
||||
block_bitmap_chunk->Unref();
|
||||
if ( inode_bitmap_chunk )
|
||||
inode_bitmap_chunk->Unref();
|
||||
if ( data_block )
|
||||
data_block->Unref();
|
||||
filesystem->block_groups[group_id] = NULL;
|
||||
}
|
||||
|
||||
uint32_t BlockGroup::AllocateBlock()
|
||||
{
|
||||
if ( !filesystem->device->write )
|
||||
return errno = EROFS, 0;
|
||||
if ( !data->bg_free_blocks_count )
|
||||
return errno = ENOSPC, 0;
|
||||
size_t num_chunk_bits = filesystem->block_size * 8UL;
|
||||
uint32_t begun_chunk = block_alloc_chunk;
|
||||
for ( uint32_t i = 0; i < num_block_bitmap_chunks; i++ )
|
||||
{
|
||||
block_alloc_chunk = (begun_chunk + i) % num_block_bitmap_chunks;
|
||||
bool last = block_alloc_chunk + 1 == num_block_bitmap_chunks;
|
||||
if ( !block_bitmap_chunk )
|
||||
{
|
||||
uint32_t block_id = data->bg_block_bitmap + block_alloc_chunk;
|
||||
block_bitmap_chunk = filesystem->device->GetBlock(block_id);
|
||||
if ( !block_bitmap_chunk )
|
||||
return 0;
|
||||
block_bitmap_chunk_i = 0;
|
||||
}
|
||||
uint32_t chunk_offset = block_alloc_chunk * num_chunk_bits;
|
||||
uint8_t* chunk_bits = block_bitmap_chunk->block_data;
|
||||
size_t num_bits = last ? num_blocks - chunk_offset : num_chunk_bits;
|
||||
// TODO: This can be made faster by caching if previous bits were set.
|
||||
for ( ; block_bitmap_chunk_i < num_bits; block_bitmap_chunk_i++ )
|
||||
{
|
||||
if ( !checkbit(chunk_bits, block_bitmap_chunk_i) )
|
||||
{
|
||||
block_bitmap_chunk->BeginWrite();
|
||||
setbit(chunk_bits, block_bitmap_chunk_i);
|
||||
block_bitmap_chunk->FinishWrite();
|
||||
BeginWrite();
|
||||
data->bg_free_blocks_count--;
|
||||
FinishWrite();
|
||||
filesystem->BeginWrite();
|
||||
filesystem->sb->s_free_blocks_count--;
|
||||
filesystem->FinishWrite();
|
||||
uint32_t group_block_id = chunk_offset + block_bitmap_chunk_i++;
|
||||
uint32_t block_id = first_block_id + group_block_id;
|
||||
return block_id;
|
||||
}
|
||||
}
|
||||
block_bitmap_chunk->Unref();
|
||||
block_bitmap_chunk = NULL;
|
||||
}
|
||||
BeginWrite();
|
||||
data->bg_free_blocks_count = 0;
|
||||
FinishWrite();
|
||||
return errno = ENOSPC, 0;
|
||||
}
|
||||
|
||||
uint32_t BlockGroup::AllocateInode()
|
||||
{
|
||||
if ( !filesystem->device->write )
|
||||
return errno = EROFS, 0;
|
||||
if ( !data->bg_free_inodes_count )
|
||||
return errno = ENOSPC, 0;
|
||||
size_t num_chunk_bits = filesystem->block_size * 8UL;
|
||||
uint32_t begun_chunk = inode_alloc_chunk;
|
||||
for ( uint32_t i = 0; i < num_inode_bitmap_chunks; i++ )
|
||||
{
|
||||
inode_alloc_chunk = (begun_chunk + i) % num_inode_bitmap_chunks;
|
||||
bool last = inode_alloc_chunk + 1 == num_inode_bitmap_chunks;
|
||||
if ( !inode_bitmap_chunk )
|
||||
{
|
||||
uint32_t block_id = data->bg_inode_bitmap + inode_alloc_chunk;
|
||||
inode_bitmap_chunk = filesystem->device->GetBlock(block_id);
|
||||
if ( !inode_bitmap_chunk )
|
||||
return 0;
|
||||
inode_bitmap_chunk_i = 0;
|
||||
}
|
||||
uint32_t chunk_offset = inode_alloc_chunk * num_chunk_bits;
|
||||
uint8_t* chunk_bits = inode_bitmap_chunk->block_data;
|
||||
size_t num_bits = last ? num_inodes - chunk_offset : num_chunk_bits;
|
||||
// TODO: This can be made faster by caching if previous bits were set.
|
||||
for ( ; inode_bitmap_chunk_i < num_bits; inode_bitmap_chunk_i++ )
|
||||
{
|
||||
if ( !checkbit(chunk_bits, inode_bitmap_chunk_i) )
|
||||
{
|
||||
inode_bitmap_chunk->BeginWrite();
|
||||
setbit(chunk_bits, inode_bitmap_chunk_i);
|
||||
inode_bitmap_chunk->FinishWrite();
|
||||
BeginWrite();
|
||||
data->bg_free_inodes_count--;
|
||||
FinishWrite();
|
||||
filesystem->BeginWrite();
|
||||
filesystem->sb->s_free_inodes_count--;
|
||||
filesystem->FinishWrite();
|
||||
uint32_t group_inode_id = chunk_offset + inode_bitmap_chunk_i++;
|
||||
uint32_t inode_id = first_inode_id + group_inode_id;
|
||||
return inode_id;
|
||||
}
|
||||
}
|
||||
inode_bitmap_chunk->Unref();
|
||||
inode_bitmap_chunk = NULL;
|
||||
}
|
||||
BeginWrite();
|
||||
data->bg_free_inodes_count = 0;
|
||||
FinishWrite();
|
||||
return errno = ENOSPC, 0;
|
||||
}
|
||||
|
||||
void BlockGroup::FreeBlock(uint32_t block_id)
|
||||
{
|
||||
assert(filesystem->device->write);
|
||||
block_id -= first_block_id;
|
||||
size_t num_chunk_bits = filesystem->block_size * 8UL;
|
||||
uint32_t chunk_id = block_id / num_chunk_bits;
|
||||
uint32_t chunk_bit = block_id % num_chunk_bits;
|
||||
if ( !block_bitmap_chunk || chunk_id != block_alloc_chunk )
|
||||
{
|
||||
if ( block_bitmap_chunk )
|
||||
block_bitmap_chunk->Unref();
|
||||
block_alloc_chunk = chunk_id;
|
||||
uint32_t block_id = data->bg_block_bitmap + block_alloc_chunk;
|
||||
block_bitmap_chunk = filesystem->device->GetBlock(block_id);
|
||||
block_bitmap_chunk_i = 0;
|
||||
}
|
||||
|
||||
block_bitmap_chunk->BeginWrite();
|
||||
uint8_t* chunk_bits = block_bitmap_chunk->block_data;
|
||||
clearbit(chunk_bits, chunk_bit);
|
||||
block_bitmap_chunk->FinishWrite();
|
||||
if ( chunk_bit < inode_bitmap_chunk_i )
|
||||
block_bitmap_chunk_i = chunk_bit;
|
||||
BeginWrite();
|
||||
data->bg_free_blocks_count++;
|
||||
FinishWrite();
|
||||
filesystem->BeginWrite();
|
||||
filesystem->sb->s_free_blocks_count++;
|
||||
filesystem->FinishWrite();
|
||||
}
|
||||
|
||||
void BlockGroup::FreeInode(uint32_t inode_id)
|
||||
{
|
||||
assert(filesystem->device->write);
|
||||
inode_id -= first_inode_id;
|
||||
size_t num_chunk_bits = filesystem->block_size * 8UL;
|
||||
uint32_t chunk_id = inode_id / num_chunk_bits;
|
||||
uint32_t chunk_bit = inode_id % num_chunk_bits;
|
||||
if ( !inode_bitmap_chunk || chunk_id != inode_alloc_chunk )
|
||||
{
|
||||
if ( inode_bitmap_chunk )
|
||||
inode_bitmap_chunk->Unref();
|
||||
inode_alloc_chunk = chunk_id;
|
||||
uint32_t block_id = data->bg_inode_bitmap + inode_alloc_chunk;
|
||||
inode_bitmap_chunk = filesystem->device->GetBlock(block_id);
|
||||
inode_bitmap_chunk_i = 0;
|
||||
}
|
||||
|
||||
inode_bitmap_chunk->BeginWrite();
|
||||
uint8_t* chunk_bits = inode_bitmap_chunk->block_data;
|
||||
clearbit(chunk_bits, chunk_bit);
|
||||
inode_bitmap_chunk->FinishWrite();
|
||||
if ( chunk_bit < inode_bitmap_chunk_i )
|
||||
inode_bitmap_chunk_i = chunk_bit;
|
||||
BeginWrite();
|
||||
data->bg_free_inodes_count++;
|
||||
FinishWrite();
|
||||
filesystem->BeginWrite();
|
||||
filesystem->sb->s_free_inodes_count++;
|
||||
filesystem->FinishWrite();
|
||||
}
|
||||
|
||||
void BlockGroup::Refer()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void BlockGroup::Unref()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void BlockGroup::Sync()
|
||||
{
|
||||
if ( block_bitmap_chunk )
|
||||
block_bitmap_chunk->Sync();
|
||||
if ( inode_bitmap_chunk )
|
||||
inode_bitmap_chunk->Sync();
|
||||
if ( dirty )
|
||||
data_block->Sync();
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
void BlockGroup::BeginWrite()
|
||||
{
|
||||
data_block->BeginWrite();
|
||||
}
|
||||
|
||||
void BlockGroup::FinishWrite()
|
||||
{
|
||||
dirty = true;
|
||||
data_block->FinishWrite();
|
||||
Use();
|
||||
}
|
||||
|
||||
void BlockGroup::Use()
|
||||
{
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2014, 2015 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* blockgroup.h
|
||||
* Filesystem block group.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKGROUP_H
|
||||
#define BLOCKGROUP_H
|
||||
|
||||
class Block;
|
||||
class Filesystem;
|
||||
|
||||
class BlockGroup
|
||||
{
|
||||
public:
|
||||
BlockGroup(Filesystem* filesystem, uint32_t group_id);
|
||||
~BlockGroup();
|
||||
|
||||
public:
|
||||
Block* data_block;
|
||||
struct ext_blockgrpdesc* data;
|
||||
Filesystem* filesystem;
|
||||
Block* block_bitmap_chunk;
|
||||
Block* inode_bitmap_chunk;
|
||||
size_t reference_count;
|
||||
uint32_t group_id;
|
||||
uint32_t block_alloc_chunk;
|
||||
uint32_t inode_alloc_chunk;
|
||||
uint32_t block_bitmap_chunk_i;
|
||||
uint32_t inode_bitmap_chunk_i;
|
||||
uint32_t first_block_id;
|
||||
uint32_t first_inode_id;
|
||||
uint32_t num_blocks;
|
||||
uint32_t num_inodes;
|
||||
uint32_t num_block_bitmap_chunks;
|
||||
uint32_t num_inode_bitmap_chunks;
|
||||
bool dirty;
|
||||
|
||||
public:
|
||||
uint32_t AllocateBlock();
|
||||
uint32_t AllocateInode();
|
||||
void FreeBlock(uint32_t block_id);
|
||||
void FreeInode(uint32_t inode_id);
|
||||
void Refer();
|
||||
void Unref();
|
||||
void Sync();
|
||||
void BeginWrite();
|
||||
void FinishWrite();
|
||||
void Use();
|
||||
void Unlink();
|
||||
void Prelink();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2015 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ext-constants.h
|
||||
* Constants for the extended filesystem.
|
||||
*/
|
||||
|
||||
#ifndef EXT_CONSTANTS_H
|
||||
#define EXT_CONSTANTS_H
|
||||
|
||||
static const uint16_t FAT_SUPER_MAGIC = 0xEF53;
|
||||
static const uint16_t FAT_VALID_FS = 1;
|
||||
static const uint16_t FAT_ERROR_FS = 2;
|
||||
static const uint16_t FAT_ERRORS_CONTINUE = 1;
|
||||
static const uint16_t FAT_ERRORS_RO = 2;
|
||||
static const uint16_t FAT_ERRORS_PANIC = 3;
|
||||
static const uint32_t FAT_OS_LINUX = 0;
|
||||
static const uint32_t FAT_OS_HURD = 1;
|
||||
static const uint32_t FAT_OS_MASIX = 2;
|
||||
static const uint32_t FAT_OS_FREEBSD = 3;
|
||||
static const uint32_t FAT_OS_LITES = 4;
|
||||
static const uint32_t FAT_GOOD_OLD_REV = 0;
|
||||
static const uint32_t FAT_DYNAMIC_REV = 1;
|
||||
static const uint16_t FAT_DEF_RESUID = 0;
|
||||
static const uint16_t FAT_DEF_RESGID = 0;
|
||||
static const uint16_t FAT_GOOD_OLD_FIRST_INO = 11;
|
||||
static const uint16_t FAT_GOOD_OLD_INODE_SIZE = 128;
|
||||
static const uint32_t FAT_FEATURE_COMPAT_DIR_PREALLOC = 1U << 0U;
|
||||
static const uint32_t FAT_FEATURE_COMPAT_IMAGIC_INODES = 1U << 1U;
|
||||
static const uint32_t EXT3_FEATURE_COMPAT_HAS_JOURNAL = 1U << 2U;
|
||||
static const uint32_t FAT_FEATURE_COMPAT_EXT_ATTR = 1U << 3U;
|
||||
static const uint32_t FAT_FEATURE_COMPAT_RESIZE_INO = 1U << 4U;
|
||||
static const uint32_t FAT_FEATURE_COMPAT_DIR_INDEX = 1U << 5U;
|
||||
static const uint32_t FAT_FEATURE_INCOMPAT_COMPRESSION = 1U << 0U;
|
||||
static const uint32_t FAT_FEATURE_INCOMPAT_FILETYPE = 1U << 1U;
|
||||
static const uint32_t FAT_FEATURE_INCOMPAT_RECOVER = 1U << 2U;
|
||||
static const uint32_t FAT_FEATURE_INCOMPAT_JOURNAL_DEV = 1U << 3U;
|
||||
static const uint32_t FAT_FEATURE_INCOMPAT_META_BG = 1U << 4U;
|
||||
static const uint32_t FAT_FEATURE_RO_COMPAT_SPARSE_SUPER = 1U << 0U;
|
||||
static const uint32_t FAT_FEATURE_RO_COMPAT_LARGE_FILE = 1U << 1U;
|
||||
static const uint32_t FAT_FEATURE_RO_COMPAT_BTREE_DIR = 1U << 2U;
|
||||
static const uint32_t FAT_LZV1_ALG = 1U << 0U;
|
||||
static const uint32_t FAT_LZRW3A_ALG = 1U << 1U;
|
||||
static const uint32_t FAT_GZIP_ALG = 1U << 2U;
|
||||
static const uint32_t FAT_BZIP2_ALG = 1U << 3U;
|
||||
static const uint32_t FAT_LZO_ALG = 1U << 4U;
|
||||
static const uint16_t FAT_S_IFMT = 0xF000;
|
||||
static const uint16_t FAT_S_IFSOCK = 0xC000;
|
||||
static const uint16_t FAT_S_IFLNK = 0xA000;
|
||||
static const uint16_t FAT_S_IFREG = 0x8000;
|
||||
static const uint16_t FAT_S_IFBLK = 0x6000;
|
||||
static const uint16_t FAT_S_IFDIR = 0x4000;
|
||||
static const uint16_t FAT_S_IFCHR = 0x2000;
|
||||
static const uint16_t FAT_S_IFIFO = 0x1000;
|
||||
static const uint16_t FAT_S_ISUID = 0x0800;
|
||||
static const uint16_t FAT_S_ISGID = 0x0400;
|
||||
static const uint16_t FAT_S_ISVTX = 0x0200;
|
||||
static const uint16_t FAT_S_IRUSR = 0x0100;
|
||||
static const uint16_t FAT_S_IWUSR = 0x0080;
|
||||
static const uint16_t FAT_S_IXUSR = 0x0040;
|
||||
static const uint16_t FAT_S_IRGRP = 0x0020;
|
||||
static const uint16_t FAT_S_IWGRP = 0x0010;
|
||||
static const uint16_t FAT_S_IXGRP = 0x0008;
|
||||
static const uint16_t FAT_S_IROTH = 0x0004;
|
||||
static const uint16_t FAT_S_IWOTH = 0x0002;
|
||||
static const uint16_t FAT_S_IXOTH = 0x0001;
|
||||
#define FAT_S_ISSOCK(mode) (((mode) & FAT_S_IFMT) == FAT_S_IFSOCK)
|
||||
#define FAT_S_ISLNK(mode) (((mode) & FAT_S_IFMT) == FAT_S_IFLNK)
|
||||
#define FAT_S_ISREG(mode) (((mode) & FAT_S_IFMT) == FAT_S_IFREG)
|
||||
#define FAT_S_ISBLK(mode) (((mode) & FAT_S_IFMT) == FAT_S_IFBLK)
|
||||
#define FAT_S_ISDIR(mode) (((mode) & FAT_S_IFMT) == FAT_S_IFDIR)
|
||||
#define FAT_S_ISCHR(mode) (((mode) & FAT_S_IFMT) == FAT_S_IFCHR)
|
||||
#define FAT_S_ISFIFO(mode) (((mode) & FAT_S_IFMT) == FAT_S_IFIFO)
|
||||
static const uint32_t FAT_SECRM_FL = 0x00000001U;
|
||||
static const uint32_t FAT_UNRM_FL = 0x00000002U;
|
||||
static const uint32_t FAT_COMPR_FL = 0x00000004U;
|
||||
static const uint32_t FAT_SYNC_FL = 0x00000008U;
|
||||
static const uint32_t FAT_IMMUTABLE_FL = 0x00000010U;
|
||||
static const uint32_t FAT_APPEND_FL = 0x00000020U;
|
||||
static const uint32_t FAT_NODUMP_FL = 0x00000040U;
|
||||
static const uint32_t FAT_NOATIME_FL = 0x00000080U;
|
||||
static const uint32_t FAT_DIRTY_FL = 0x00000100U;
|
||||
static const uint32_t FAT_COMPRBLK_FL = 0x00000200U;
|
||||
static const uint32_t FAT_NOCOMPR_FL = 0x00000400U;
|
||||
static const uint32_t FAT_ECOMPR_FL = 0x00000800U;
|
||||
static const uint32_t FAT_BTREE_FL = 0x00001000U;
|
||||
static const uint32_t FAT_INDEX_FL = 0x00001000U;
|
||||
static const uint32_t FAT_IMAGIC_FL = 0x00002000U;
|
||||
static const uint32_t EXT3_JOURNAL_DATA_FL = 0x00004000U;
|
||||
static const uint32_t FAT_RESERVED_FL = 0x80000000U;
|
||||
static const uint32_t FAT_ROOT_INO = 2;
|
||||
static const uint8_t FAT_FT_UNKNOWN = 0;
|
||||
static const uint8_t FAT_FT_REG_FILE = 1;
|
||||
static const uint8_t FAT_FT_DIR = 2;
|
||||
static const uint8_t FAT_FT_CHRDEV = 3;
|
||||
static const uint8_t FAT_FT_BLKDEV = 4;
|
||||
static const uint8_t FAT_FT_FIFO = 5;
|
||||
static const uint8_t FAT_FT_SOCK = 6;
|
||||
static const uint8_t FAT_FT_SYMLINK = 7;
|
||||
|
||||
static inline uint8_t FAT_FT_OF_MODE(mode_t mode)
|
||||
{
|
||||
if ( FAT_S_ISREG(mode) )
|
||||
return FAT_FT_REG_FILE;
|
||||
if ( FAT_S_ISDIR(mode) )
|
||||
return FAT_FT_DIR;
|
||||
if ( FAT_S_ISCHR(mode) )
|
||||
return FAT_FT_CHRDEV;
|
||||
if ( FAT_S_ISBLK(mode) )
|
||||
return FAT_FT_BLKDEV;
|
||||
if ( FAT_S_ISFIFO(mode) )
|
||||
return FAT_FT_FIFO;
|
||||
if ( FAT_S_ISSOCK(mode) )
|
||||
return FAT_FT_SOCK;
|
||||
if ( FAT_S_ISLNK(mode) )
|
||||
return FAT_FT_SYMLINK;
|
||||
return FAT_FT_UNKNOWN;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,128 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ext-structs.h
|
||||
* Data structures for the extended filesystem.
|
||||
*/
|
||||
|
||||
#ifndef EXT_STRUCTS_H
|
||||
#define EXT_STRUCTS_H
|
||||
|
||||
struct ext_superblock
|
||||
{
|
||||
uint32_t s_inodes_count;
|
||||
uint32_t s_blocks_count;
|
||||
uint32_t s_r_blocks_count;
|
||||
uint32_t s_free_blocks_count;
|
||||
uint32_t s_free_inodes_count;
|
||||
uint32_t s_first_data_block;
|
||||
uint32_t s_log_block_size;
|
||||
int32_t s_log_frag_size;
|
||||
uint32_t s_blocks_per_group;
|
||||
uint32_t s_frags_per_group;
|
||||
uint32_t s_inodes_per_group;
|
||||
uint32_t s_mtime;
|
||||
uint32_t s_wtime;
|
||||
uint16_t s_mnt_count;
|
||||
uint16_t s_max_mnt_count;
|
||||
uint16_t s_magic;
|
||||
uint16_t s_state;
|
||||
uint16_t s_errors;
|
||||
uint16_t s_minor_rev_level;
|
||||
uint32_t s_lastcheck;
|
||||
uint32_t s_checkinterval;
|
||||
uint32_t s_creator_os;
|
||||
uint32_t s_rev_level;
|
||||
uint16_t s_def_resuid;
|
||||
uint16_t s_def_resgid;
|
||||
// FAT_DYNAMIC_REV
|
||||
uint32_t s_first_ino;
|
||||
uint16_t s_inode_size;
|
||||
uint16_t s_block_group_nr;
|
||||
uint32_t s_feature_compat;
|
||||
uint32_t s_feature_incompat;
|
||||
uint32_t s_feature_ro_compat;
|
||||
uint8_t s_uuid[16];
|
||||
/*uint8_t*/ char s_volume_name[16];
|
||||
/*uint8_t*/ char s_last_mounted[64];
|
||||
uint32_t s_algo_bitmap;
|
||||
// Performance Hints
|
||||
uint8_t s_prealloc_blocks;
|
||||
uint8_t s_prealloc_dir_blocks;
|
||||
uint16_t alignment0;
|
||||
// Journaling Support
|
||||
uint8_t s_journal_uuid[16];
|
||||
uint32_t s_journal_inum;
|
||||
uint32_t s_journal_dev;
|
||||
uint32_t s_last_orphan;
|
||||
// Directory Indexing Support
|
||||
uint32_t s_hash_seed[4];
|
||||
uint8_t s_def_hash_version;
|
||||
uint8_t alignment1[3];
|
||||
// Other options
|
||||
uint32_t s_default_mount_options;
|
||||
uint32_t s_first_meta_bg;
|
||||
uint8_t alignment2[760];
|
||||
};
|
||||
|
||||
struct ext_blockgrpdesc
|
||||
{
|
||||
uint32_t bg_block_bitmap;
|
||||
uint32_t bg_inode_bitmap;
|
||||
uint32_t bg_inode_table;
|
||||
uint16_t bg_free_blocks_count;
|
||||
uint16_t bg_free_inodes_count;
|
||||
uint16_t bg_used_dirs_count;
|
||||
uint16_t alignment0;
|
||||
uint8_t alignment1[12];
|
||||
};
|
||||
|
||||
struct ext_inode
|
||||
{
|
||||
uint16_t i_mode;
|
||||
uint16_t i_uid;
|
||||
uint32_t i_size;
|
||||
uint32_t i_atime;
|
||||
uint32_t i_ctime;
|
||||
uint32_t i_mtime;
|
||||
uint32_t i_dtime;
|
||||
uint16_t i_gid;
|
||||
uint16_t i_links_count;
|
||||
uint32_t i_blocks;
|
||||
uint32_t i_flags;
|
||||
uint32_t i_osd1;
|
||||
uint32_t i_block[15];
|
||||
uint32_t i_generation;
|
||||
uint32_t i_file_acl;
|
||||
uint32_t i_dir_acl;
|
||||
uint32_t i_faddr;
|
||||
uint8_t i_frag;
|
||||
uint8_t i_fsize;
|
||||
uint16_t i_mode_high;
|
||||
uint16_t i_uid_high;
|
||||
uint16_t i_gid_high;
|
||||
uint32_t i_osd2_alignment0;
|
||||
};
|
||||
|
||||
struct ext_dirent
|
||||
{
|
||||
uint32_t inode;
|
||||
uint16_t reclen;
|
||||
uint8_t name_len;
|
||||
uint8_t file_type;
|
||||
char name[0];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, 2014, 2015, 2016, 2023 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
|
@ -41,11 +39,6 @@
|
|||
#include "fuse.h"
|
||||
#endif
|
||||
|
||||
// TODO: Remove.
|
||||
#include "ext-constants.h"
|
||||
#include "ext-structs.h"
|
||||
|
||||
#include "blockgroup.h"
|
||||
#include "block.h"
|
||||
#include "device.h"
|
||||
#include "fat.h"
|
||||
|
@ -55,64 +48,9 @@
|
|||
#include "ioleast.h"
|
||||
#include "util.h"
|
||||
|
||||
// These must be kept up to date with libmount/fat.c.
|
||||
static const uint32_t FAT_FEATURE_COMPAT_SUPPORTED = 0;
|
||||
static const uint32_t FAT_FEATURE_INCOMPAT_SUPPORTED = \
|
||||
FAT_FEATURE_INCOMPAT_FILETYPE;
|
||||
static const uint32_t FAT_FEATURE_RO_COMPAT_SUPPORTED = \
|
||||
FAT_FEATURE_RO_COMPAT_LARGE_FILE;
|
||||
|
||||
uid_t request_uid;
|
||||
uid_t request_gid;
|
||||
|
||||
mode_t HostModeFromExtMode(uint32_t extmode)
|
||||
{
|
||||
mode_t hostmode = extmode & 0777;
|
||||
if ( extmode & FAT_S_ISVTX ) hostmode |= S_ISVTX;
|
||||
if ( extmode & FAT_S_ISGID ) hostmode |= S_ISGID;
|
||||
if ( extmode & FAT_S_ISUID ) hostmode |= S_ISUID;
|
||||
if ( FAT_S_ISSOCK(extmode) ) hostmode |= S_IFSOCK;
|
||||
if ( FAT_S_ISLNK(extmode) ) hostmode |= S_IFLNK;
|
||||
if ( FAT_S_ISREG(extmode) ) hostmode |= S_IFREG;
|
||||
if ( FAT_S_ISBLK(extmode) ) hostmode |= S_IFBLK;
|
||||
if ( FAT_S_ISDIR(extmode) ) hostmode |= S_IFDIR;
|
||||
if ( FAT_S_ISCHR(extmode) ) hostmode |= S_IFCHR;
|
||||
if ( FAT_S_ISFIFO(extmode) ) hostmode |= S_IFIFO;
|
||||
return hostmode;
|
||||
}
|
||||
|
||||
uint32_t ExtModeFromHostMode(mode_t hostmode)
|
||||
{
|
||||
uint32_t extmode = hostmode & 0777;
|
||||
if ( hostmode & S_ISVTX ) extmode |= FAT_S_ISVTX;
|
||||
if ( hostmode & S_ISGID ) extmode |= FAT_S_ISGID;
|
||||
if ( hostmode & S_ISUID ) extmode |= FAT_S_ISUID;
|
||||
if ( S_ISSOCK(hostmode) ) extmode |= FAT_S_IFSOCK;
|
||||
if ( S_ISLNK(hostmode) ) extmode |= FAT_S_IFLNK;
|
||||
if ( S_ISREG(hostmode) ) extmode |= FAT_S_IFREG;
|
||||
if ( S_ISBLK(hostmode) ) extmode |= FAT_S_IFBLK;
|
||||
if ( S_ISDIR(hostmode) ) extmode |= FAT_S_IFDIR;
|
||||
if ( S_ISCHR(hostmode) ) extmode |= FAT_S_IFCHR;
|
||||
if ( S_ISFIFO(hostmode) ) extmode |= FAT_S_IFIFO;
|
||||
return extmode;
|
||||
}
|
||||
|
||||
uint8_t HostDTFromExtDT(uint8_t extdt)
|
||||
{
|
||||
switch ( extdt )
|
||||
{
|
||||
case FAT_FT_UNKNOWN: return DT_UNKNOWN;
|
||||
case FAT_FT_REG_FILE: return DT_REG;
|
||||
case FAT_FT_DIR: return DT_DIR;
|
||||
case FAT_FT_CHRDEV: return DT_CHR;
|
||||
case FAT_FT_BLKDEV: return DT_BLK;
|
||||
case FAT_FT_FIFO: return DT_FIFO;
|
||||
case FAT_FT_SOCK: return DT_SOCK;
|
||||
case FAT_FT_SYMLINK: return DT_LNK;
|
||||
}
|
||||
return DT_UNKNOWN;
|
||||
}
|
||||
|
||||
// TODO: Encapsulate.
|
||||
void StatInode(Inode* inode, struct stat* st)
|
||||
{
|
||||
|
@ -326,7 +264,8 @@ int main(int argc, char* argv[])
|
|||
if ( !fs ) // TODO: Use operator new nothrow!
|
||||
err(1, "malloc");
|
||||
|
||||
printf("So far so good, data_offset=%u, data_sectors=%u, cluster_count=%u, sectors_per_cluster=%u, fat_type=%i\n", data_offset, data_sectors, cluster_count, bpb.sectors_per_cluster, fat_type);
|
||||
// TODO: Remove this debug stuff.
|
||||
printf("Mounted FAT data_offset=%u, data_sectors=%u, cluster_count=%u, sectors_per_cluster=%u, fat_type=%i\n", data_offset, data_sectors, cluster_count, bpb.sectors_per_cluster, fat_type);
|
||||
|
||||
if ( !mount_path )
|
||||
return 0;
|
||||
|
|
|
@ -22,20 +22,15 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <endian.h>
|
||||
#include <err.h> // TODO: Remove.
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h> // TODO: Debug.
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "ext-constants.h"
|
||||
#include "ext-structs.h"
|
||||
#include "fat.h"
|
||||
|
||||
#include "block.h"
|
||||
#include "blockgroup.h"
|
||||
#include "device.h"
|
||||
#include "filesystem.h"
|
||||
#include "inode.h"
|
||||
|
@ -140,14 +135,24 @@ uint16_t timespec_to_fat_date(struct timespec* ts)
|
|||
return tm.tm_mday << 0 | (tm.tm_mon + 1) << 5 | (tm.tm_year - 80) << 9;
|
||||
}
|
||||
|
||||
// TODO: Rename tenths to a better name.
|
||||
void timespec_to_fat(const struct timespec* ts, uint16_t* date, uint16_t* time,
|
||||
uint8_t* tenths)
|
||||
{
|
||||
struct tm tm;
|
||||
gmtime_r(&ts->tv_sec, &tm);
|
||||
// TODO: Endian.
|
||||
*date = tm.tm_mday << 0 | (tm.tm_mon + 1) << 5 | (tm.tm_year - 80) << 9;
|
||||
*time = (tm.tm_sec / 2) << 0 | tm.tm_min << 5 | tm.tm_hour << 11;
|
||||
*tenths = ts->tv_nsec / 10000000 + (tm.tm_sec & 1 ? 100 : 0);
|
||||
}
|
||||
|
||||
Filesystem::Filesystem(Device* device, const char* mount_path)
|
||||
{
|
||||
this->bpb_block = device->GetBlock(0);
|
||||
assert(bpb_block); // TODO: This can fail.
|
||||
this->bpb = (struct fat_bpb*) bpb_block->block_data;
|
||||
this->sb = NULL; // TODO: Remove.
|
||||
this->device = device;
|
||||
this->block_groups = NULL; // TODO: Remove.
|
||||
this->mount_path = mount_path;
|
||||
this->mode_reg = S_IFREG | 0644;
|
||||
this->mode_dir = S_IFDIR | 0755;
|
||||
|
@ -181,8 +186,6 @@ Filesystem::Filesystem(Device* device, const char* mount_path)
|
|||
fat_type == 12 ? 0xFFF : fat_type == 16 ? 0xFFFF : 0xFFFFFFF;
|
||||
// TODO: Obtain and verify this from the fsinfo.
|
||||
this->free_search = 0;
|
||||
// TODO: Update to FAT:
|
||||
//this->num_blocks = this->sb->s_blocks_count;
|
||||
this->mru_inode = NULL;
|
||||
this->lru_inode = NULL;
|
||||
this->dirty_inode = NULL;
|
||||
|
@ -238,30 +241,6 @@ void Filesystem::Sync()
|
|||
device->Sync();
|
||||
}
|
||||
|
||||
BlockGroup* Filesystem::GetBlockGroup(uint32_t group_id)
|
||||
{
|
||||
err(1, "deleteme: %s\n", __func__);
|
||||
assert(group_id < num_groups);
|
||||
if ( block_groups[group_id] )
|
||||
return block_groups[group_id]->Refer(), block_groups[group_id];
|
||||
|
||||
size_t group_size = sizeof(ext_blockgrpdesc);
|
||||
uint32_t first_block_id = sb->s_first_data_block + 1 /* superblock */;
|
||||
uint32_t block_id = first_block_id + (group_id * group_size) / block_size;
|
||||
uint32_t offset = (group_id * group_size) % block_size;
|
||||
|
||||
Block* block = device->GetBlock(block_id);
|
||||
if ( !block )
|
||||
return (BlockGroup*) NULL;
|
||||
BlockGroup* group = new BlockGroup(this, group_id);
|
||||
if ( !group ) // TODO: Use operator new nothrow!
|
||||
return block->Unref(), (BlockGroup*) NULL;
|
||||
group->data_block = block;
|
||||
uint8_t* buf = group->data_block->block_data + offset;
|
||||
group->data = (struct ext_blockgrpdesc*) buf;
|
||||
return block_groups[group_id] = group;
|
||||
}
|
||||
|
||||
Inode* Filesystem::GetInode(uint32_t inode_id, Block* dirent_block,
|
||||
struct fat_dirent* dirent)
|
||||
{
|
||||
|
@ -329,7 +308,7 @@ void Filesystem::FreeCluster(uint32_t cluster)
|
|||
if ( fat_type != 32 )
|
||||
return;
|
||||
Block* block = device->GetBlock(bpb->fat32_fsinfo);
|
||||
if ( block )
|
||||
if ( !block )
|
||||
return;
|
||||
struct fat_fsinfo* fsinfo = (struct fat_fsinfo*) block->block_data;
|
||||
block->BeginWrite();
|
||||
|
@ -346,86 +325,6 @@ void Filesystem::FreeCluster(uint32_t cluster)
|
|||
block->Unref();
|
||||
}
|
||||
|
||||
uint32_t Filesystem::AllocateBlock(BlockGroup* preferred)
|
||||
{
|
||||
err(1, "deleteme: %s\n", __func__);
|
||||
if ( !device->write )
|
||||
return errno = EROFS, 0;
|
||||
if ( !sb->s_free_blocks_count )
|
||||
return errno = ENOSPC, 0;
|
||||
if ( preferred )
|
||||
if ( uint32_t block_id = preferred->AllocateBlock() )
|
||||
return block_id;
|
||||
// TODO: This can be made faster by maintaining a linked list of block
|
||||
// groups that definitely have free blocks.
|
||||
for ( uint32_t group_id = 0; group_id < num_groups; group_id++ )
|
||||
if ( uint32_t block_id = GetBlockGroup(group_id)->AllocateBlock() )
|
||||
return block_id;
|
||||
// TODO: This case should only be fit in the event of corruption. We should
|
||||
// rebuild all these values upon filesystem mount instead so we know
|
||||
// this can't happen. That also allows us to make the linked list
|
||||
// requested above.
|
||||
BeginWrite();
|
||||
sb->s_free_blocks_count = 0;
|
||||
FinishWrite();
|
||||
return errno = ENOSPC, 0;
|
||||
}
|
||||
|
||||
uint32_t Filesystem::AllocateInode(BlockGroup* preferred)
|
||||
{
|
||||
err(1, "deleteme: %s\n", __func__);
|
||||
if ( !device->write )
|
||||
return errno = EROFS, 0;
|
||||
if ( !sb->s_free_inodes_count )
|
||||
return errno = ENOSPC, 0;
|
||||
if ( preferred )
|
||||
if ( uint32_t inode_id = preferred->AllocateInode() )
|
||||
return inode_id;
|
||||
// TODO: This can be made faster by maintaining a linked list of block
|
||||
// groups that definitely have free inodes.
|
||||
for ( uint32_t group_id = 0; group_id < num_groups; group_id++ )
|
||||
if ( uint32_t inode_id = GetBlockGroup(group_id)->AllocateInode() )
|
||||
return inode_id;
|
||||
// TODO: This case should only be fit in the event of corruption. We should
|
||||
// rebuild all these values upon filesystem mount instead so we know
|
||||
// this can't happen. That also allows us to make the linked list
|
||||
// requested above.
|
||||
BeginWrite();
|
||||
sb->s_free_inodes_count = 0;
|
||||
FinishWrite();
|
||||
return errno = ENOSPC, 0;
|
||||
}
|
||||
|
||||
void Filesystem::FreeBlock(uint32_t block_id)
|
||||
{
|
||||
err(1, "deleteme: %s\n", __func__);
|
||||
assert(device->write);
|
||||
assert(block_id);
|
||||
assert(block_id < num_blocks);
|
||||
uint32_t group_id = (block_id - sb->s_first_data_block) / sb->s_blocks_per_group;
|
||||
assert(group_id < num_groups);
|
||||
BlockGroup* group = GetBlockGroup(group_id);
|
||||
if ( !group )
|
||||
return;
|
||||
group->FreeBlock(block_id);
|
||||
group->Unref();
|
||||
}
|
||||
|
||||
void Filesystem::FreeInode(uint32_t inode_id)
|
||||
{
|
||||
err(1, "deleteme: %s\n", __func__);
|
||||
assert(device->write);
|
||||
assert(inode_id);
|
||||
assert(inode_id < num_inodes);
|
||||
uint32_t group_id = (inode_id-1) / sb->s_inodes_per_group;
|
||||
assert(group_id < num_groups);
|
||||
BlockGroup* group = GetBlockGroup(group_id);
|
||||
if ( !group )
|
||||
return;
|
||||
group->FreeInode(inode_id);
|
||||
group->Unref();
|
||||
}
|
||||
|
||||
uint32_t Filesystem::ReadFAT(uint32_t cluster)
|
||||
{
|
||||
// TODO: Bounds check.
|
||||
|
|
|
@ -23,11 +23,13 @@
|
|||
bool is_8_3(const char* name);
|
||||
void encode_8_3(const char* decoded, char encoded[8 + 3]);
|
||||
void decode_8_3(const char encoded[8 + 3], char decoded[8 + 1 + 3 + 1]);
|
||||
void timespec_to_fat(const struct timespec* ts, uint16_t* date, uint16_t* time,
|
||||
uint8_t* tenths);
|
||||
// TODO: Unify into the above.
|
||||
uint8_t timespec_to_fat_tenths(struct timespec* ts);
|
||||
uint16_t timespec_to_fat_time(struct timespec* ts);
|
||||
uint16_t timespec_to_fat_date(struct timespec* ts);
|
||||
|
||||
class BlockGroup;
|
||||
class Device;
|
||||
class Inode;
|
||||
|
||||
|
@ -42,16 +44,13 @@ public:
|
|||
public:
|
||||
Block* bpb_block;
|
||||
struct fat_bpb* bpb;
|
||||
struct ext_superblock* sb; //TODO: Remove.
|
||||
Device* device;
|
||||
BlockGroup** block_groups;
|
||||
const char* mount_path;
|
||||
mode_t mode_reg;
|
||||
mode_t mode_dir;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
uint32_t block_size;
|
||||
uint32_t inode_size; // TODO: Remove.
|
||||
uint16_t bytes_per_sector;
|
||||
uint16_t root_dirent_count;
|
||||
uint32_t sectors_per_fat;
|
||||
|
@ -66,9 +65,6 @@ public:
|
|||
uint32_t eio_cluster;
|
||||
uint32_t eof_cluster;
|
||||
uint32_t free_search;
|
||||
uint32_t num_blocks; // TODO: Remove, probably.
|
||||
uint32_t num_groups; // TODO: Remove.
|
||||
uint32_t num_inodes; // TODO: Remove, probably.
|
||||
Inode* mru_inode;
|
||||
Inode* lru_inode;
|
||||
Inode* dirty_inode;
|
||||
|
@ -76,15 +72,10 @@ public:
|
|||
bool dirty;
|
||||
|
||||
public:
|
||||
BlockGroup* GetBlockGroup(uint32_t group_id);
|
||||
Inode* GetInode(uint32_t inode_id, Block* dirent_block = NULL,
|
||||
struct fat_dirent* dirent = NULL);
|
||||
uint32_t AllocateCluster();
|
||||
void FreeCluster(uint32_t cluster);
|
||||
uint32_t AllocateBlock(BlockGroup* preferred = NULL);
|
||||
uint32_t AllocateInode(BlockGroup* preferred = NULL);
|
||||
void FreeBlock(uint32_t block_id);
|
||||
void FreeInode(uint32_t inode_id);
|
||||
uint32_t ReadFAT(uint32_t cluster);
|
||||
bool WriteFAT(uint32_t cluster, uint32_t value);
|
||||
uint32_t CalculateFreeCount();
|
||||
|
|
|
@ -42,10 +42,6 @@
|
|||
|
||||
#include <fsmarshall.h>
|
||||
|
||||
#include "ext-constants.h"
|
||||
#include "ext-structs.h" // TODO: Remove.
|
||||
|
||||
#include "blockgroup.h"
|
||||
#include "block.h"
|
||||
#include "device.h"
|
||||
#include "fat.h"
|
||||
|
@ -169,7 +165,6 @@ Inode* SafeGetInode(Filesystem* fs, ino_t ino)
|
|||
{
|
||||
if ( (uint32_t) ino != ino )
|
||||
return errno = EBADF, (Inode*) NULL;
|
||||
// TODO: Should check if the inode is not deleted.
|
||||
return fs->GetInode((uint32_t) ino);
|
||||
}
|
||||
|
||||
|
@ -178,7 +173,10 @@ void HandleRefer(int chl, struct fsm_req_refer* msg, Filesystem* fs)
|
|||
(void) chl;
|
||||
if ( Inode* inode = SafeGetInode(fs, (uint32_t) msg->ino) )
|
||||
{
|
||||
inode->RemoteRefer();
|
||||
if ( inode->implied_reference )
|
||||
inode->implied_reference--;
|
||||
else
|
||||
inode->RemoteRefer();
|
||||
inode->Unref();
|
||||
}
|
||||
}
|
||||
|
@ -195,9 +193,6 @@ void HandleUnref(int chl, struct fsm_req_unref* msg, Filesystem* fs)
|
|||
|
||||
void HandleSync(int chl, struct fsm_req_sync* msg, Filesystem* fs)
|
||||
{
|
||||
printf("ENOTSUP %s\n", __func__);
|
||||
RespondError(chl, ENOTSUP); // TODO
|
||||
return;
|
||||
Inode* inode = SafeGetInode(fs, msg->ino);
|
||||
if ( !inode ) { RespondError(chl, errno); return; }
|
||||
inode->Sync();
|
||||
|
@ -217,59 +212,33 @@ void HandleStat(int chl, struct fsm_req_stat* msg, Filesystem* fs)
|
|||
|
||||
void HandleChangeMode(int chl, struct fsm_req_chmod* msg, Filesystem* fs)
|
||||
{
|
||||
printf("ENOTSUP %s\n", __func__);
|
||||
RespondError(chl, ENOTSUP); // TODO
|
||||
return;
|
||||
if ( !fs->device->write ) { RespondError(chl, EROFS); return; }
|
||||
Inode* inode = SafeGetInode(fs, msg->ino);
|
||||
if ( !inode ) { RespondError(chl, errno); return; }
|
||||
uint32_t req_mode = ExtModeFromHostMode(msg->mode);
|
||||
uint32_t old_mode = inode->Mode();
|
||||
uint32_t new_mode = (old_mode & ~S_SETABLE) | (req_mode & S_SETABLE);
|
||||
inode->SetMode(new_mode);
|
||||
if ( !inode->ChangeMode(msg->mode) )
|
||||
RespondError(chl, errno);
|
||||
else
|
||||
RespondSuccess(chl);
|
||||
inode->Unref();
|
||||
RespondSuccess(chl);
|
||||
}
|
||||
|
||||
void HandleChangeOwner(int chl, struct fsm_req_chown* msg, Filesystem* fs)
|
||||
{
|
||||
printf("ENOTSUP %s\n", __func__);
|
||||
RespondError(chl, ENOTSUP); // TODO
|
||||
return;
|
||||
if ( !fs->device->write ) { RespondError(chl, EROFS); return; }
|
||||
Inode* inode = SafeGetInode(fs, msg->ino);
|
||||
if ( !inode ) { RespondError(chl, errno); return; }
|
||||
if ( msg->uid != (uid_t) -1 )
|
||||
inode->SetUserId((uint32_t) msg->uid);
|
||||
if ( msg->gid != (gid_t) -1 )
|
||||
inode->SetGroupId((uint32_t) msg->gid);
|
||||
if ( !inode->ChangeOwner(msg->uid, msg->gid) )
|
||||
RespondError(chl, errno);
|
||||
else
|
||||
RespondSuccess(chl);
|
||||
inode->Unref();
|
||||
RespondSuccess(chl);
|
||||
}
|
||||
|
||||
void HandleUTimens(int chl, struct fsm_req_utimens* msg, Filesystem* fs)
|
||||
{
|
||||
printf("ENOTSUP %s\n", __func__);
|
||||
RespondError(chl, ENOTSUP); // TODO
|
||||
return;
|
||||
if ( !fs->device->write ) { RespondError(chl, EROFS); return; }
|
||||
Inode* inode = SafeGetInode(fs, msg->ino);
|
||||
if ( !inode ) { RespondError(chl, errno); return; }
|
||||
if ( msg->times[0].tv_nsec != UTIME_OMIT ||
|
||||
msg->times[1].tv_nsec != UTIME_OMIT )
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
inode->BeginWrite();
|
||||
if ( msg->times[0].tv_nsec == UTIME_NOW )
|
||||
inode->data->i_atime = now;
|
||||
else if ( msg->times[0].tv_nsec != UTIME_OMIT )
|
||||
inode->data->i_atime = msg->times[0].tv_sec;
|
||||
if ( msg->times[1].tv_nsec == UTIME_NOW )
|
||||
inode->data->i_mtime = now;
|
||||
else if ( msg->times[1].tv_nsec != UTIME_OMIT )
|
||||
inode->data->i_mtime = msg->times[1].tv_sec;
|
||||
inode->FinishWrite();
|
||||
}
|
||||
inode->UTimens(msg->times);
|
||||
inode->Unref();
|
||||
RespondSuccess(chl);
|
||||
}
|
||||
|
@ -353,11 +322,11 @@ void HandleOpen(int chl, struct fsm_req_open* msg, Filesystem* fs)
|
|||
if ( !result ) { RespondError(chl, errno); return; }
|
||||
|
||||
RespondOpen(chl, result->inode_id, result->Mode() & S_IFMT);
|
||||
// TODO: This leaks a reference so the Inode keeps existing with meta data
|
||||
// since unfortunately the automatic Refer() in the kernel is not implied.
|
||||
// idk how to best solve that just yet, maybe add a count to the inode
|
||||
// that causes that many Unrefs() to happen on the next HandleRefer().
|
||||
//result->Unref();
|
||||
// TODO: Unfortunately Open does not implicitly imply RemoteRefer so we need
|
||||
// to try and pretend that it does so the inode isn't destroyed early.
|
||||
result->implied_reference++;
|
||||
result->RemoteRefer();
|
||||
result->Unref();
|
||||
}
|
||||
|
||||
void HandleMakeDir(int chl, struct fsm_req_mkdir* msg, Filesystem* fs)
|
||||
|
@ -387,6 +356,7 @@ void HandleMakeDir(int chl, struct fsm_req_mkdir* msg, Filesystem* fs)
|
|||
result->Unref();
|
||||
}
|
||||
|
||||
// TODO: Encapsulate.
|
||||
void HandleReadDir(int chl, struct fsm_req_readdirents* msg, Filesystem* fs)
|
||||
{
|
||||
Inode* inode = SafeGetInode(fs, msg->ino);
|
||||
|
@ -483,9 +453,6 @@ void HandleIsATTY(int chl, struct fsm_req_isatty* msg, Filesystem* fs)
|
|||
|
||||
void HandleUnlink(int chl, struct fsm_req_unlink* msg, Filesystem* fs)
|
||||
{
|
||||
printf("ENOTSUP %s\n", __func__);
|
||||
RespondError(chl, ENOTSUP); // TODO
|
||||
return;
|
||||
Inode* inode = SafeGetInode(fs, msg->dirino);
|
||||
if ( !inode ) { RespondError(chl, errno); return; }
|
||||
|
||||
|
@ -511,9 +478,6 @@ void HandleUnlink(int chl, struct fsm_req_unlink* msg, Filesystem* fs)
|
|||
|
||||
void HandleRemoveDir(int chl, struct fsm_req_rmdir* msg, Filesystem* fs)
|
||||
{
|
||||
printf("ENOTSUP %s\n", __func__);
|
||||
RespondError(chl, ENOTSUP); // TODO
|
||||
return;
|
||||
Inode* inode = SafeGetInode(fs, msg->dirino);
|
||||
if ( !inode ) { RespondError(chl, errno); return; }
|
||||
|
||||
|
@ -539,9 +503,6 @@ void HandleRemoveDir(int chl, struct fsm_req_rmdir* msg, Filesystem* fs)
|
|||
|
||||
void HandleLink(int chl, struct fsm_req_link* msg, Filesystem* fs)
|
||||
{
|
||||
printf("ENOTSUP %s\n", __func__);
|
||||
RespondError(chl, ENOTSUP); // TODO
|
||||
return;
|
||||
Inode* inode = SafeGetInode(fs, msg->dirino);
|
||||
if ( !inode ) { RespondError(chl, errno); return; }
|
||||
Inode* dest = SafeGetInode(fs, msg->linkino);
|
||||
|
@ -571,9 +532,6 @@ void HandleLink(int chl, struct fsm_req_link* msg, Filesystem* fs)
|
|||
|
||||
void HandleSymlink(int chl, struct fsm_req_symlink* msg, Filesystem* fs)
|
||||
{
|
||||
printf("ENOTSUP %s\n", __func__);
|
||||
RespondError(chl, ENOTSUP); // TODO
|
||||
return;
|
||||
Inode* inode = SafeGetInode(fs, msg->dirino);
|
||||
if ( !inode ) { RespondError(chl, errno); return; }
|
||||
|
||||
|
@ -620,8 +578,6 @@ void HandleReadlink(int chl, struct fsm_req_readlink* msg, Filesystem* fs)
|
|||
|
||||
void HandleRename(int chl, struct fsm_req_rename* msg, Filesystem* fs)
|
||||
{
|
||||
RespondError(chl, ENOTSUP); // TODO
|
||||
return;
|
||||
char* pathraw = (char*) &(msg[1]);
|
||||
char* path = (char*) malloc(msg->oldnamelen+1 + msg->newnamelen+1);
|
||||
if ( !path ) { RespondError(chl, errno); return; }
|
||||
|
@ -679,29 +635,51 @@ void HandleTCGetBlob(int chl, struct fsm_req_tcgetblob* msg, Filesystem* fs)
|
|||
memcpy(name, nameraw, msg->namelen);
|
||||
name[msg->namelen] = '\0';
|
||||
|
||||
static const char index[] = "device-path\0filesystem-type\0filesystem-uuid\0mount-path\0";
|
||||
static const char index[] =
|
||||
"device-path\0filesystem-type\0filesystem-uuid\0mount-path\0"
|
||||
"fat-size\0volume-id\0volume-label\0";
|
||||
if ( !strcmp(name, "") )
|
||||
RespondTCGetBlob(chl, index, sizeof(index) - 1);
|
||||
else if ( !strcmp(name, "device-path") )
|
||||
RespondTCGetBlob(chl, fs->device->path, strlen(fs->device->path));
|
||||
else if ( !strcmp(name, "filesystem-type") )
|
||||
RespondTCGetBlob(chl, "fat", strlen("fat"));
|
||||
else if ( !strcmp(name, "fat-size") )
|
||||
{
|
||||
const char* str = fs->fat_type == 32 ? "32" :
|
||||
fs->fat_type == 16 ? "16" : "12";
|
||||
RespondTCGetBlob(chl, str, strlen(str));
|
||||
}
|
||||
else if ( !strcmp(name, "filesystem-uuid") )
|
||||
{
|
||||
unsigned char uuid[16];
|
||||
if ( fs->fat_type == 32 )
|
||||
{
|
||||
memcpy(uuid, &fs->bpb->fat32_volume_id, 4);
|
||||
memcpy(uuid + 4, &fs->bpb->fat32_volume_id, 11);
|
||||
memcpy(uuid + 4, &fs->bpb->fat32_volume_label, 11);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(uuid, &fs->bpb->fat12_volume_id, 4);
|
||||
memcpy(uuid + 4, &fs->bpb->fat12_volume_id, 11);
|
||||
memcpy(uuid + 4, &fs->bpb->fat12_volume_label, 11);
|
||||
}
|
||||
uuid[15] = '\0';
|
||||
RespondTCGetBlob(chl, uuid, sizeof(uuid));
|
||||
}
|
||||
else if ( !strcmp(name, "volume-id") )
|
||||
{
|
||||
if ( fs->fat_type == 32 )
|
||||
RespondTCGetBlob(chl, &fs->bpb->fat32_volume_id, 4);
|
||||
else
|
||||
RespondTCGetBlob(chl, &fs->bpb->fat12_volume_id, 4);
|
||||
}
|
||||
else if ( !strcmp(name, "volume-label") )
|
||||
{
|
||||
if ( fs->fat_type == 32 )
|
||||
RespondTCGetBlob(chl, &fs->bpb->fat32_volume_label, 11);
|
||||
else
|
||||
RespondTCGetBlob(chl, &fs->bpb->fat12_volume_label, 11);
|
||||
}
|
||||
else if ( !strcmp(name, "mount-path") )
|
||||
RespondTCGetBlob(chl, fs->mount_path, strlen(fs->mount_path));
|
||||
else
|
||||
|
@ -714,14 +692,6 @@ void HandleIncomingMessage(int chl, struct fsm_msg_header* hdr, Filesystem* fs)
|
|||
{
|
||||
request_uid = hdr->uid;
|
||||
request_gid = hdr->gid;
|
||||
if ( (uint16_t) request_uid != request_uid ||
|
||||
(uint16_t) request_gid != request_gid )
|
||||
{
|
||||
warn("id exceeded 16-bit: uid=%ju gid=%ju\n",
|
||||
(uintmax_t) request_uid, (uintmax_t) request_gid);
|
||||
RespondError(chl, EOVERFLOW);
|
||||
return;
|
||||
}
|
||||
typedef void (*handler_t)(int, void*, Filesystem*);
|
||||
handler_t handlers[FSM_MSG_NUM] = { NULL };
|
||||
handlers[FSM_REQ_SYNC] = (handler_t) HandleSync;
|
||||
|
|
796
fat/inode.cpp
796
fat/inode.cpp
File diff suppressed because it is too large
Load Diff
18
fat/inode.h
18
fat/inode.h
|
@ -37,29 +37,26 @@ public:
|
|||
Inode* prev_dirty;
|
||||
Inode* next_dirty;
|
||||
Block* data_block;
|
||||
struct fat_dirent* dirent; // TODO: Rename to data?
|
||||
struct ext_inode* data; // TODO: Remove?
|
||||
struct fat_dirent* dirent;
|
||||
struct fat_dirent deleted_dirent;
|
||||
uint32_t first_cluster;
|
||||
Filesystem* filesystem;
|
||||
size_t reference_count;
|
||||
size_t remote_reference_count;
|
||||
size_t implied_reference;
|
||||
uint32_t inode_id;
|
||||
bool dirty;
|
||||
bool deleted;
|
||||
|
||||
public:
|
||||
uint32_t Mode();
|
||||
uint32_t UserId();
|
||||
uint32_t GroupId();
|
||||
uint64_t Size();
|
||||
void SetMode(uint32_t mode);
|
||||
void SetUserId(uint32_t user);
|
||||
void SetGroupId(uint32_t group);
|
||||
void SetSize(uint64_t new_size);
|
||||
void UTimens(const struct timespec times[2]);
|
||||
bool ChangeMode(mode_t mode);
|
||||
bool ChangeOwner(uid_t uid, gid_t gid);
|
||||
bool Truncate(uint64_t new_size);
|
||||
bool FreeIndirect(uint64_t from, uint64_t offset, uint32_t block_id,
|
||||
int indirection, uint64_t entry_span);
|
||||
Block* GetBlock(uint64_t offset);
|
||||
Block* GetBlockFromTable(Block* table, uint32_t index);
|
||||
Block* GetClusterSector(uint32_t cluster, uint8_t sector);
|
||||
bool Iterate(Block** block_ptr, uint32_t* cluster_ptr,
|
||||
uint8_t* sector_ptr, uint16_t* offset);
|
||||
|
@ -71,7 +68,6 @@ public:
|
|||
Inode* UnlinkKeep(const char* elem, bool directories, bool force=false);
|
||||
ssize_t ReadAt(uint8_t* buffer, size_t count, off_t offset);
|
||||
ssize_t WriteAt(const uint8_t* buffer, size_t count, off_t offset);
|
||||
bool UnembedInInode();
|
||||
bool Rename(Inode* olddir, const char* oldname, const char* newname);
|
||||
Inode* CreateDirectory(const char* path, mode_t mode);
|
||||
bool RemoveDirectory(const char* path);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2018, 2021-2022 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2011-2018, 2021-2023 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -233,6 +233,13 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo_p)
|
|||
|
||||
if ( !(kernel_options = strdup(cmdline ? cmdline : "")) )
|
||||
Panic("Failed to allocate kernel command line");
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
// TODO: Detect EFI.
|
||||
kernel_firmware = "bios";
|
||||
#else
|
||||
#warning "Name your system firmware here"
|
||||
kernel_firmware = "unknown";
|
||||
#endif
|
||||
|
||||
int argmax = 1;
|
||||
argv = new char*[argmax + 1];
|
||||
|
@ -288,6 +295,20 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo_p)
|
|||
enable_network_drivers = true;
|
||||
else if ( !strcmp(arg, "--no-random-seed") )
|
||||
no_random_seed = true;
|
||||
else if ( !strncmp(arg, "--firmware=", strlen("--firmware=")) )
|
||||
{
|
||||
const char* firmware = arg + strlen("--firmware=");
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
if ( !strcmp(firmware, "bios") || !strcmp(firmware, "pc") )
|
||||
kernel_firmware = "bios";
|
||||
else if ( !strcmp(firmware, "efi") )
|
||||
kernel_firmware = "efi";
|
||||
else
|
||||
#endif
|
||||
{
|
||||
PanicF("Unsupported firmware option: %s", firmware);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::PrintF("\r\e[J");
|
||||
|
|
|
@ -34,20 +34,17 @@
|
|||
namespace Sortix {
|
||||
|
||||
char* kernel_options;
|
||||
const char* kernel_firmware;
|
||||
|
||||
static const char* KernelInfo(const char* req)
|
||||
{
|
||||
if ( strcmp(req, "name") == 0 ) { return BRAND_KERNEL_NAME; }
|
||||
if ( strcmp(req, "version") == 0 ) { return VERSIONSTR; }
|
||||
if ( strcmp(req, "tagline") == 0 ) { return BRAND_RELEASE_TAGLINE; }
|
||||
if ( strcmp(req, "options") == 0 ) { return kernel_options; }
|
||||
if ( strcmp(req, "builddate") == 0 ) { return __DATE__; }
|
||||
if ( strcmp(req, "buildtime") == 0 ) { return __TIME__; }
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
if ( strcmp(req, "firmware") == 0 ) { return "bios"; }
|
||||
#else
|
||||
#warning "Name your system firmware here"
|
||||
#endif
|
||||
if ( strcmp(req, "name") == 0 ) return BRAND_KERNEL_NAME;
|
||||
if ( strcmp(req, "version") == 0 ) return VERSIONSTR;
|
||||
if ( strcmp(req, "tagline") == 0 ) return BRAND_RELEASE_TAGLINE;
|
||||
if ( strcmp(req, "options") == 0 ) return kernel_options;
|
||||
if ( strcmp(req, "builddate") == 0 ) return __DATE__;
|
||||
if ( strcmp(req, "buildtime") == 0 ) return __TIME__;
|
||||
if ( strcmp(req, "firmware") == 0 ) return kernel_firmware;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
namespace Sortix {
|
||||
|
||||
extern char* kernel_options;
|
||||
extern const char* kernel_firmware;
|
||||
|
||||
} // namespace Sortix
|
||||
|
||||
|
|
|
@ -82,6 +82,33 @@ diff -Paur --no-dereference -- mtools.upstream/mcopy.c mtools/mcopy.c
|
|||
}
|
||||
return;
|
||||
}
|
||||
diff -Paur --no-dereference -- mtools.upstream/plain_io.c mtools/plain_io.c
|
||||
--- mtools.upstream/plain_io.c
|
||||
+++ mtools/plain_io.c
|
||||
@@ -145,7 +145,10 @@
|
||||
static int init_geom_with_reg(int fd, struct device *dev,
|
||||
struct device *orig_dev,
|
||||
struct MT_STAT *statbuf) {
|
||||
+ // TODO: Actually use the geometry but the partition has to report it.
|
||||
+#ifndef __sortix__
|
||||
if(S_ISREG(statbuf->st_mode)) {
|
||||
+#endif
|
||||
/* Regular file (image file) */
|
||||
mt_off_t sectors;
|
||||
if(statbuf->st_size == 0) {
|
||||
@@ -161,10 +164,12 @@
|
||||
? UINT32_MAX
|
||||
: (uint32_t) sectors;
|
||||
return 0;
|
||||
+#ifndef __sortix__
|
||||
} else {
|
||||
/* All the rest (devices, etc.) */
|
||||
return init_geom(fd, dev, orig_dev, statbuf);
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
|
||||
static int file_geom(Stream_t *Stream, struct device *dev,
|
||||
diff -Paur --no-dereference -- mtools.upstream/sysincludes.h mtools/sysincludes.h
|
||||
--- mtools.upstream/sysincludes.h
|
||||
+++ mtools/sysincludes.h
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
.Op Fl \-enable-em
|
||||
.Op Fl \-disable-network-drivers
|
||||
.Op Fl \-enable-network-drivers
|
||||
.Op Fl \-firmware Ns = Ns Oo Sy bios "|" Sy efi "|" pc Oc
|
||||
.Op Fl \-no-random-seed
|
||||
.Op Fl \-
|
||||
.Op Ar init ...
|
||||
|
@ -64,6 +65,14 @@ driver.
|
|||
.It Fl \-enable-network-drivers
|
||||
Do initialize network drivers.
|
||||
This is the default behavior.
|
||||
.It Fl \-firmware Ns = Ns Oo Sy bios "|" Sy efi "|" pc Oc
|
||||
Informs the kernel the system is booted using
|
||||
.Sy bios or
|
||||
.Sy efi .
|
||||
The
|
||||
.Sy pc
|
||||
value is a synonym for
|
||||
.Sy bios .
|
||||
.It Fl \-no-random-seed
|
||||
Don't warn if no random seed file was loaded by the bootloader (usually from
|
||||
.Pa /boot/random.seed ) .
|
||||
|
|
|
@ -312,7 +312,7 @@ int main(int argc, char* argv[])
|
|||
fetch_argv[0] = (char*) "tix-fetch";
|
||||
fetch_argv[1] = (char*) "--collection";
|
||||
fetch_argv[2] = params.collection;
|
||||
fetch_argv[3] = (char*) "--port";
|
||||
fetch_argv[3] = (char*) "--package";
|
||||
fetch_argv[4] = (char*) "--";
|
||||
int offset = 5;
|
||||
for ( int i = 0; i < argc-2; i++ )
|
||||
|
|
|
@ -30,7 +30,7 @@ The date on which the current kernel was built.
|
|||
.It Sy buildtime
|
||||
The time at which the current kernel was built.
|
||||
.It Sy firmware
|
||||
The firmware of the system (e.g. "bios" or "uefi")
|
||||
The firmware of the system (e.g. "bios" or "efi")
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Nm
|
||||
|
|
Loading…
Reference in New Issue