mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 01:37:36 +00:00
Integrate ext2 from VFS into Kernel.
This commit is contained in:
parent
aec8ab0a60
commit
9171521752
45 changed files with 662 additions and 1085 deletions
|
@ -3,7 +3,7 @@
|
|||
//#define DBFS_DEBUG
|
||||
|
||||
DiskBackedFileSystem::DiskBackedFileSystem(RetainPtr<DiskDevice>&& device)
|
||||
: m_device(std::move(device))
|
||||
: m_device(move(device))
|
||||
{
|
||||
ASSERT(m_device);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ bool DiskBackedFileSystem::writeBlock(unsigned index, const ByteBuffer& data)
|
|||
#ifdef DBFS_DEBUG
|
||||
printf("DiskBackedFileSystem::writeBlock %u\n", index);
|
||||
#endif
|
||||
qword baseOffset = static_cast<qword>(index) * static_cast<qword>(blockSize());
|
||||
DiskOffset baseOffset = static_cast<DiskOffset>(index) * static_cast<DiskOffset>(blockSize());
|
||||
return device().write(baseOffset, blockSize(), data.pointer());
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ bool DiskBackedFileSystem::writeBlocks(unsigned index, unsigned count, const Byt
|
|||
#ifdef DBFS_DEBUG
|
||||
printf("DiskBackedFileSystem::writeBlocks %u x%u\n", index, count);
|
||||
#endif
|
||||
qword baseOffset = static_cast<qword>(index) * static_cast<qword>(blockSize());
|
||||
DiskOffset baseOffset = static_cast<DiskOffset>(index) * static_cast<DiskOffset>(blockSize());
|
||||
return device().write(baseOffset, count * blockSize(), data.pointer());
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ ByteBuffer DiskBackedFileSystem::readBlock(unsigned index) const
|
|||
printf("DiskBackedFileSystem::readBlock %u\n", index);
|
||||
#endif
|
||||
auto buffer = ByteBuffer::createUninitialized(blockSize());
|
||||
qword baseOffset = static_cast<qword>(index) * static_cast<qword>(blockSize());
|
||||
DiskOffset baseOffset = static_cast<DiskOffset>(index) * static_cast<DiskOffset>(blockSize());
|
||||
auto* bufferPointer = buffer.pointer();
|
||||
device().read(baseOffset, blockSize(), bufferPointer);
|
||||
ASSERT(buffer.size() == blockSize());
|
||||
|
|
|
@ -8,14 +8,12 @@ DiskDevice::~DiskDevice()
|
|||
{
|
||||
}
|
||||
|
||||
bool DiskDevice::read(qword offset, unsigned length, byte* out) const
|
||||
bool DiskDevice::read(DiskOffset offset, unsigned length, byte* out) const
|
||||
{
|
||||
ASSERT((offset % blockSize()) == 0);
|
||||
ASSERT((length % blockSize()) == 0);
|
||||
qword firstBlock = offset / blockSize();
|
||||
qword endBlock = (offset + length) / blockSize();
|
||||
ASSERT(firstBlock <= 0xffffffff);
|
||||
ASSERT(endBlock <= 0xffffffff);
|
||||
dword firstBlock = offset / blockSize();
|
||||
dword endBlock = (offset + length) / blockSize();
|
||||
byte* outptr = out;
|
||||
unsigned remainingCount = length;
|
||||
for (unsigned bi = firstBlock; bi < endBlock; ++bi) {
|
||||
|
@ -26,12 +24,12 @@ bool DiskDevice::read(qword offset, unsigned length, byte* out) const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DiskDevice::write(qword offset, unsigned length, const byte* in)
|
||||
bool DiskDevice::write(DiskOffset offset, unsigned length, const byte* in)
|
||||
{
|
||||
ASSERT((offset % blockSize()) == 0);
|
||||
ASSERT((length % blockSize()) == 0);
|
||||
qword firstBlock = offset / blockSize();
|
||||
qword endBlock = (offset + length) / blockSize();
|
||||
dword firstBlock = offset / blockSize();
|
||||
dword endBlock = (offset + length) / blockSize();
|
||||
ASSERT(firstBlock <= 0xffffffff);
|
||||
ASSERT(endBlock <= 0xffffffff);
|
||||
const byte* inptr = in;
|
||||
|
|
|
@ -3,6 +3,13 @@
|
|||
#include <AK/Retainable.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
#ifdef SERENITY_KERNEL
|
||||
// FIXME: Support 64-bit DiskOffset
|
||||
typedef dword DiskOffset;
|
||||
#else
|
||||
typedef qword DiskOffset;
|
||||
#endif
|
||||
|
||||
class DiskDevice : public Retainable<DiskDevice> {
|
||||
public:
|
||||
virtual ~DiskDevice();
|
||||
|
@ -11,8 +18,8 @@ public:
|
|||
virtual bool readBlock(unsigned index, byte*) const = 0;
|
||||
virtual bool writeBlock(unsigned index, const byte*) = 0;
|
||||
virtual const char* className() const = 0;
|
||||
bool read(qword offset, unsigned length, byte*) const;
|
||||
bool write(qword offset, unsigned length, const byte*);
|
||||
bool read(DiskOffset, unsigned length, byte*) const;
|
||||
bool write(DiskOffset, unsigned length, const byte*);
|
||||
|
||||
protected:
|
||||
DiskDevice();
|
||||
|
|
|
@ -3,20 +3,20 @@
|
|||
#include "UnixTypes.h"
|
||||
#include <AK/Bitmap.h>
|
||||
#include <AK/StdLib.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <AK/kmalloc.h>
|
||||
#include <AK/ktime.h>
|
||||
#include <AK/kstdio.h>
|
||||
#include "sys-errno.h"
|
||||
|
||||
//#define EXT2_DEBUG
|
||||
#define EXT2_DEBUG
|
||||
|
||||
RetainPtr<Ext2FileSystem> Ext2FileSystem::create(RetainPtr<DiskDevice>&& device)
|
||||
{
|
||||
return adopt(*new Ext2FileSystem(std::move(device)));
|
||||
return adopt(*new Ext2FileSystem(move(device)));
|
||||
}
|
||||
|
||||
Ext2FileSystem::Ext2FileSystem(RetainPtr<DiskDevice>&& device)
|
||||
: DiskBackedFileSystem(std::move(device))
|
||||
: DiskBackedFileSystem(move(device))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -64,9 +64,9 @@ const ext2_group_desc& Ext2FileSystem::blockGroupDescriptor(unsigned groupIndex)
|
|||
|
||||
if (!m_cachedBlockGroupDescriptorTable) {
|
||||
unsigned blocksToRead = ceilDiv(m_blockGroupCount * (unsigned)sizeof(ext2_group_desc), blockSize());
|
||||
printf("[ext2fs] block group count: %u, blocks-to-read: %u\n", m_blockGroupCount, blocksToRead);
|
||||
kprintf("[ext2fs] block group count: %u, blocks-to-read: %u\n", m_blockGroupCount, blocksToRead);
|
||||
unsigned firstBlockOfBGDT = blockSize() == 1024 ? 2 : 1;
|
||||
printf("[ext2fs] first block of BGDT: %u\n", firstBlockOfBGDT);
|
||||
kprintf("[ext2fs] first block of BGDT: %u\n", firstBlockOfBGDT);
|
||||
m_cachedBlockGroupDescriptorTable = readBlocks(firstBlockOfBGDT, blocksToRead);
|
||||
}
|
||||
return reinterpret_cast<ext2_group_desc*>(m_cachedBlockGroupDescriptorTable.pointer())[groupIndex - 1];
|
||||
|
@ -75,32 +75,32 @@ const ext2_group_desc& Ext2FileSystem::blockGroupDescriptor(unsigned groupIndex)
|
|||
bool Ext2FileSystem::initialize()
|
||||
{
|
||||
auto& superBlock = this->superBlock();
|
||||
printf("[ext2fs] super block magic: %04x (super block size: %u)\n", superBlock.s_magic, sizeof(ext2_super_block));
|
||||
kprintf("[ext2fs] super block magic: %x (super block size: %u)\n", superBlock.s_magic, sizeof(ext2_super_block));
|
||||
if (superBlock.s_magic != EXT2_SUPER_MAGIC)
|
||||
return false;
|
||||
|
||||
printf("[ext2fs] %u inodes, %u blocks\n", superBlock.s_inodes_count, superBlock.s_blocks_count);
|
||||
printf("[ext2fs] block size = %u\n", EXT2_BLOCK_SIZE(&superBlock));
|
||||
printf("[ext2fs] first data block = %u\n", superBlock.s_first_data_block);
|
||||
printf("[ext2fs] inodes per block = %u\n", inodesPerBlock());
|
||||
printf("[ext2fs] inodes per group = %u\n", inodesPerGroup());
|
||||
printf("[ext2fs] free inodes = %u\n", superBlock.s_free_inodes_count);
|
||||
kprintf("[ext2fs] %u inodes, %u blocks\n", superBlock.s_inodes_count, superBlock.s_blocks_count);
|
||||
kprintf("[ext2fs] block size = %u\n", EXT2_BLOCK_SIZE(&superBlock));
|
||||
kprintf("[ext2fs] first data block = %u\n", superBlock.s_first_data_block);
|
||||
kprintf("[ext2fs] inodes per block = %u\n", inodesPerBlock());
|
||||
kprintf("[ext2fs] inodes per group = %u\n", inodesPerGroup());
|
||||
kprintf("[ext2fs] free inodes = %u\n", superBlock.s_free_inodes_count);
|
||||
|
||||
printf("[ext2fs] desc per block = %u\n", EXT2_DESC_PER_BLOCK(&superBlock));
|
||||
printf("[ext2fs] desc size = %u\n", EXT2_DESC_SIZE(&superBlock));
|
||||
kprintf("[ext2fs] desc per block = %u\n", EXT2_DESC_PER_BLOCK(&superBlock));
|
||||
kprintf("[ext2fs] desc size = %u\n", EXT2_DESC_SIZE(&superBlock));
|
||||
|
||||
setBlockSize(EXT2_BLOCK_SIZE(&superBlock));
|
||||
|
||||
m_blockGroupCount = ceilDiv(superBlock.s_blocks_count, superBlock.s_blocks_per_group);
|
||||
|
||||
if (m_blockGroupCount == 0) {
|
||||
printf("[ext2fs] no block groups :(\n");
|
||||
kprintf("[ext2fs] no block groups :(\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 1; i <= m_blockGroupCount; ++i) {
|
||||
auto& group = blockGroupDescriptor(i);
|
||||
printf("[ext2fs] group[%u] { block_bitmap: %u, inode_bitmap: %u, inode_table: %u }\n",
|
||||
kprintf("[ext2fs] group[%u] { block_bitmap: %u, inode_bitmap: %u, inode_table: %u }\n",
|
||||
i,
|
||||
group.bg_block_bitmap,
|
||||
group.bg_inode_bitmap,
|
||||
|
@ -123,12 +123,12 @@ InodeIdentifier Ext2FileSystem::rootInode() const
|
|||
#ifdef EXT2_DEBUG
|
||||
static void dumpExt2Inode(const ext2_inode& inode)
|
||||
{
|
||||
printf("Dump of ext2_inode:\n");
|
||||
printf(" i_size: %u\n", inode.i_size);
|
||||
printf(" i_mode: %u\n", inode.i_mode);
|
||||
printf(" i_blocks: %u\n", inode.i_blocks);
|
||||
printf(" i_uid: %u\n", inode.i_uid);
|
||||
printf(" i_gid: %u\n", inode.i_gid);
|
||||
kprintf("Dump of ext2_inode:\n");
|
||||
kprintf(" i_size: %u\n", inode.i_size);
|
||||
kprintf(" i_mode: %u\n", inode.i_mode);
|
||||
kprintf(" i_blocks: %u\n", inode.i_blocks);
|
||||
kprintf(" i_uid: %u\n", inode.i_uid);
|
||||
kprintf(" i_gid: %u\n", inode.i_gid);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -218,7 +218,7 @@ Vector<unsigned> Ext2FileSystem::blockListForInode(const ext2_inode& e2inode) co
|
|||
if (!blocksRemaining)
|
||||
return list;
|
||||
|
||||
auto processBlockArray = [&] (unsigned arrayBlockIndex, std::function<void(unsigned)> callback) {
|
||||
auto processBlockArray = [&] (unsigned arrayBlockIndex, Function<void(unsigned)> callback) {
|
||||
auto arrayBlock = readBlock(arrayBlockIndex);
|
||||
ASSERT(arrayBlock);
|
||||
auto* array = reinterpret_cast<const __u32*>(arrayBlock.pointer());
|
||||
|
@ -267,7 +267,7 @@ Unix::ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t
|
|||
|
||||
auto e2inode = lookupExt2Inode(inode.index());
|
||||
if (!e2inode) {
|
||||
printf("[ext2fs] readInodeBytes: metadata lookup for inode %u failed\n", inode.index());
|
||||
kprintf("[ext2fs] readInodeBytes: metadata lookup for inode %u failed\n", inode.index());
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -284,7 +284,7 @@ Unix::ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t
|
|||
// This avoids wasting an entire block on short links. (Most links are short.)
|
||||
static const unsigned maxInlineSymlinkLength = 60;
|
||||
if (isSymbolicLink(e2inode->i_mode) && e2inode->i_size < maxInlineSymlinkLength) {
|
||||
Unix::ssize_t nread = min(e2inode->i_size - offset, static_cast<Unix::off_t>(count));
|
||||
Unix::ssize_t nread = min((Unix::off_t)e2inode->i_size - offset, static_cast<Unix::off_t>(count));
|
||||
memcpy(buffer, e2inode->i_block + offset, nread);
|
||||
return nread;
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ Unix::ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t
|
|||
// It needs to be cached!
|
||||
auto list = blockListForInode(*e2inode);
|
||||
if (list.isEmpty()) {
|
||||
printf("[ext2fs] readInodeBytes: empty block list for inode %u\n", inode.index());
|
||||
kprintf("[ext2fs] readInodeBytes: empty block list for inode %u\n", inode.index());
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -305,17 +305,17 @@ Unix::ssize_t Ext2FileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t
|
|||
dword offsetIntoFirstBlock = offset % blockSize();
|
||||
|
||||
Unix::ssize_t nread = 0;
|
||||
Unix::size_t remainingCount = min((Unix::off_t)count, e2inode->i_size - offset);
|
||||
Unix::size_t remainingCount = min((Unix::off_t)count, (Unix::off_t)e2inode->i_size - offset);
|
||||
byte* out = buffer;
|
||||
|
||||
#ifdef EXT2_DEBUG
|
||||
printf("ok let's do it, read(%llu, %u) -> blocks %u thru %u, oifb: %u\n", offset, count, firstBlockLogicalIndex, lastBlockLogicalIndex, offsetIntoFirstBlock);
|
||||
kprintf("ok let's do it, read(%llu, %u) -> blocks %u thru %u, oifb: %u\n", offset, count, firstBlockLogicalIndex, lastBlockLogicalIndex, offsetIntoFirstBlock);
|
||||
#endif
|
||||
|
||||
for (dword bi = firstBlockLogicalIndex; bi <= lastBlockLogicalIndex; ++bi) {
|
||||
auto block = readBlock(list[bi]);
|
||||
if (!block) {
|
||||
printf("[ext2fs] readInodeBytes: readBlock(%u) failed (lbi: %u)\n", list[bi], bi);
|
||||
kprintf("[ext2fs] readInodeBytes: readBlock(%u) failed (lbi: %u)\n", list[bi], bi);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -342,7 +342,7 @@ bool Ext2FileSystem::writeInode(InodeIdentifier inode, const ByteBuffer& data)
|
|||
|
||||
auto e2inode = lookupExt2Inode(inode.index());
|
||||
if (!e2inode) {
|
||||
printf("[ext2fs] writeInode: metadata lookup for inode %u failed\n", inode.index());
|
||||
kprintf("[ext2fs] writeInode: metadata lookup for inode %u failed\n", inode.index());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -357,13 +357,13 @@ bool Ext2FileSystem::writeInode(InodeIdentifier inode, const ByteBuffer& data)
|
|||
|
||||
auto list = blockListForInode(*e2inode);
|
||||
if (list.isEmpty()) {
|
||||
printf("[ext2fs] writeInode: empty block list for inode %u\n", inode.index());
|
||||
kprintf("[ext2fs] writeInode: empty block list for inode %u\n", inode.index());
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < list.size(); ++i) {
|
||||
auto section = data.slice(i * blockSize(), blockSize());
|
||||
printf("section = %p (%u)\n", section.pointer(), section.size());
|
||||
kprintf("section = %p (%u)\n", section.pointer(), section.size());
|
||||
bool success = writeBlock(list[i], section);
|
||||
ASSERT(success);
|
||||
}
|
||||
|
@ -371,13 +371,13 @@ bool Ext2FileSystem::writeInode(InodeIdentifier inode, const ByteBuffer& data)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Ext2FileSystem::enumerateDirectoryInode(InodeIdentifier inode, std::function<bool(const DirectoryEntry&)> callback) const
|
||||
bool Ext2FileSystem::enumerateDirectoryInode(InodeIdentifier inode, Function<bool(const DirectoryEntry&)> callback) const
|
||||
{
|
||||
ASSERT(inode.fileSystemID() == id());
|
||||
ASSERT(isDirectoryInode(inode.index()));
|
||||
|
||||
#ifdef EXT2_DEBUG
|
||||
printf("[ext2fs] Enumerating directory contents of inode %u:\n", inode.index());
|
||||
kprintf("[ext2fs] Enumerating directory contents of inode %u:\n", inode.index());
|
||||
#endif
|
||||
|
||||
auto buffer = readEntireInode(inode);
|
||||
|
@ -391,7 +391,7 @@ bool Ext2FileSystem::enumerateDirectoryInode(InodeIdentifier inode, std::functio
|
|||
memcpy(namebuf, entry->name, entry->name_len);
|
||||
namebuf[entry->name_len] = 0;
|
||||
#ifdef EXT2_DEBUG
|
||||
printf("inode: %u, name_len: %u, rec_len: %u, file_type: %u, name: %s\n", entry->inode, entry->name_len, entry->rec_len, entry->file_type, namebuf);
|
||||
kprintf("inode: %u, name_len: %u, rec_len: %u, file_type: %u, name: %s\n", entry->inode, entry->name_len, entry->rec_len, entry->file_type, namebuf);
|
||||
#endif
|
||||
if (!callback({ namebuf, { id(), entry->inode }, entry->file_type }))
|
||||
break;
|
||||
|
@ -408,7 +408,7 @@ bool Ext2FileSystem::addInodeToDirectory(unsigned directoryInode, unsigned inode
|
|||
ASSERT(isDirectory(e2inodeForDirectory->i_mode));
|
||||
|
||||
//#ifdef EXT2_DEBUG
|
||||
printf("[ext2fs] Adding inode %u with name '%s' to directory %u\n", inode, name.characters(), directoryInode);
|
||||
kprintf("[ext2fs] Adding inode %u with name '%s' to directory %u\n", inode, name.characters(), directoryInode);
|
||||
//#endif
|
||||
|
||||
Vector<DirectoryEntry> entries;
|
||||
|
@ -422,13 +422,13 @@ bool Ext2FileSystem::addInodeToDirectory(unsigned directoryInode, unsigned inode
|
|||
return true;
|
||||
});
|
||||
if (nameAlreadyExists) {
|
||||
printf("[ext2fs] Name '%s' already exists in directory inode %u\n", name.characters(), directoryInode);
|
||||
kprintf("[ext2fs] Name '%s' already exists in directory inode %u\n", name.characters(), directoryInode);
|
||||
return false;
|
||||
}
|
||||
|
||||
entries.append({ name, { id(), inode }, fileType });
|
||||
|
||||
return writeDirectoryInode(directoryInode, std::move(entries));
|
||||
return writeDirectoryInode(directoryInode, move(entries));
|
||||
}
|
||||
|
||||
class BufferStream {
|
||||
|
@ -476,18 +476,18 @@ private:
|
|||
|
||||
bool Ext2FileSystem::writeDirectoryInode(unsigned directoryInode, Vector<DirectoryEntry>&& entries)
|
||||
{
|
||||
printf("[ext2fs] New directory inode %u contents to write:\n", directoryInode);
|
||||
kprintf("[ext2fs] New directory inode %u contents to write:\n", directoryInode);
|
||||
|
||||
unsigned directorySize = 0;
|
||||
for (auto& entry : entries) {
|
||||
printf(" - %08u %s\n", entry.inode.index(), entry.name.characters());
|
||||
kprintf(" - %08u %s\n", entry.inode.index(), entry.name.characters());
|
||||
directorySize += EXT2_DIR_REC_LEN(entry.name.length());
|
||||
}
|
||||
|
||||
unsigned blocksNeeded = ceilDiv(directorySize, blockSize());
|
||||
unsigned occupiedSize = blocksNeeded * blockSize();
|
||||
|
||||
printf("[ext2fs] directory size: %u (occupied: %u)\n", directorySize, occupiedSize);
|
||||
kprintf("[ext2fs] directory size: %u (occupied: %u)\n", directorySize, occupiedSize);
|
||||
|
||||
auto directoryData = ByteBuffer::createUninitialized(occupiedSize);
|
||||
|
||||
|
@ -499,11 +499,11 @@ bool Ext2FileSystem::writeDirectoryInode(unsigned directoryInode, Vector<Directo
|
|||
if (i == entries.size() - 1)
|
||||
recordLength += occupiedSize - directorySize;
|
||||
|
||||
printf("* inode: %u", entry.inode.index());
|
||||
printf(", name_len: %u", word(entry.name.length()));
|
||||
printf(", rec_len: %u", word(recordLength));
|
||||
printf(", file_type: %u", byte(entry.fileType));
|
||||
printf(", name: %s\n", entry.name.characters());
|
||||
kprintf("* inode: %u", entry.inode.index());
|
||||
kprintf(", name_len: %u", word(entry.name.length()));
|
||||
kprintf(", rec_len: %u", word(recordLength));
|
||||
kprintf(", file_type: %u", byte(entry.fileType));
|
||||
kprintf(", name: %s\n", entry.name.characters());
|
||||
|
||||
stream << dword(entry.inode.index());
|
||||
stream << word(recordLength);
|
||||
|
@ -512,7 +512,7 @@ bool Ext2FileSystem::writeDirectoryInode(unsigned directoryInode, Vector<Directo
|
|||
stream << entry.name;
|
||||
|
||||
unsigned padding = recordLength - entry.name.length() - 8;
|
||||
printf(" *** pad %u bytes\n", padding);
|
||||
kprintf(" *** pad %u bytes\n", padding);
|
||||
for (unsigned j = 0; j < padding; ++j) {
|
||||
stream << byte(0);
|
||||
}
|
||||
|
@ -521,15 +521,15 @@ bool Ext2FileSystem::writeDirectoryInode(unsigned directoryInode, Vector<Directo
|
|||
stream.fillToEnd(0);
|
||||
|
||||
#if 0
|
||||
printf("data to write (%u):\n", directoryData.size());
|
||||
kprintf("data to write (%u):\n", directoryData.size());
|
||||
for (unsigned i = 0; i < directoryData.size(); ++i) {
|
||||
printf("%02x ", directoryData[i]);
|
||||
kprintf("%02x ", directoryData[i]);
|
||||
if ((i + 1) % 8 == 0)
|
||||
printf(" ");
|
||||
kprintf(" ");
|
||||
if ((i + 1) % 16 == 0)
|
||||
printf("\n");
|
||||
kprintf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
kprintf("\n");
|
||||
#endif
|
||||
|
||||
writeInode({ id(), directoryInode }, directoryData);
|
||||
|
@ -568,20 +568,20 @@ void Ext2FileSystem::dumpBlockBitmap(unsigned groupIndex) const
|
|||
auto bitmapBlocks = readBlocks(bgd.bg_block_bitmap, blockCount);
|
||||
ASSERT(bitmapBlocks);
|
||||
|
||||
printf("[ext2fs] group[%u] block bitmap (bitmap occupies %u blocks):\n", groupIndex, blockCount);
|
||||
kprintf("[ext2fs] group[%u] block bitmap (bitmap occupies %u blocks):\n", groupIndex, blockCount);
|
||||
|
||||
auto bitmap = Bitmap::wrap(bitmapBlocks.pointer(), blocksInGroup);
|
||||
for (unsigned i = 0; i < blocksInGroup; ++i) {
|
||||
printf("%c", bitmap.get(i) ? '1' : '0');
|
||||
kprintf("%c", bitmap.get(i) ? '1' : '0');
|
||||
}
|
||||
printf("\n");
|
||||
kprintf("\n");
|
||||
}
|
||||
|
||||
void Ext2FileSystem::dumpInodeBitmap(unsigned groupIndex) const
|
||||
{
|
||||
traverseInodeBitmap(groupIndex, [] (unsigned, const Bitmap& bitmap) {
|
||||
for (unsigned i = 0; i < bitmap.size(); ++i)
|
||||
printf("%c", bitmap.get(i) ? '1' : '0');
|
||||
kprintf("%c", bitmap.get(i) ? '1' : '0');
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -630,7 +630,7 @@ bool Ext2FileSystem::modifyLinkCount(InodeIndex inode, int delta)
|
|||
return false;
|
||||
|
||||
auto newLinkCount = e2inode->i_links_count + delta;
|
||||
printf("changing inode %u link count from %u to %u\n", inode, e2inode->i_links_count, newLinkCount);
|
||||
kprintf("changing inode %u link count from %u to %u\n", inode, e2inode->i_links_count, newLinkCount);
|
||||
e2inode->i_links_count = newLinkCount;
|
||||
|
||||
return writeExt2Inode(inode, *e2inode);
|
||||
|
@ -644,7 +644,7 @@ bool Ext2FileSystem::setModificationTime(InodeIdentifier inode, dword timestamp)
|
|||
if (!e2inode)
|
||||
return false;
|
||||
|
||||
printf("changing inode %u mtime from %u to %u\n", inode.index(), e2inode->i_mtime, timestamp);
|
||||
kprintf("changing inode %u mtime from %u to %u\n", inode.index(), e2inode->i_mtime, timestamp);
|
||||
e2inode->i_mtime = timestamp;
|
||||
|
||||
return writeExt2Inode(inode.index(), *e2inode);
|
||||
|
@ -671,11 +671,11 @@ bool Ext2FileSystem::isDirectoryInode(unsigned inode) const
|
|||
|
||||
Vector<Ext2FileSystem::BlockIndex> Ext2FileSystem::allocateBlocks(unsigned group, unsigned count)
|
||||
{
|
||||
printf("[ext2fs] allocateBlocks(group: %u, count: %u)\n", group, count);
|
||||
kprintf("[ext2fs] allocateBlocks(group: %u, count: %u)\n", group, count);
|
||||
|
||||
auto& bgd = blockGroupDescriptor(group);
|
||||
if (bgd.bg_free_blocks_count < count) {
|
||||
printf("[ext2fs] allocateBlocks can't allocate out of group %u, wanted %u but only %u available\n", group, count, bgd.bg_free_blocks_count);
|
||||
kprintf("[ext2fs] allocateBlocks can't allocate out of group %u, wanted %u but only %u available\n", group, count, bgd.bg_free_blocks_count);
|
||||
return { };
|
||||
}
|
||||
|
||||
|
@ -691,9 +691,9 @@ Vector<Ext2FileSystem::BlockIndex> Ext2FileSystem::allocateBlocks(unsigned group
|
|||
}
|
||||
return true;
|
||||
});
|
||||
printf("[ext2fs] allocateBlock found these blocks:\n");
|
||||
kprintf("[ext2fs] allocateBlock found these blocks:\n");
|
||||
for (auto& bi : blocks) {
|
||||
printf(" > %u\n", bi);
|
||||
kprintf(" > %u\n", bi);
|
||||
}
|
||||
|
||||
return blocks;
|
||||
|
@ -701,11 +701,11 @@ Vector<Ext2FileSystem::BlockIndex> Ext2FileSystem::allocateBlocks(unsigned group
|
|||
|
||||
unsigned Ext2FileSystem::allocateInode(unsigned preferredGroup, unsigned expectedSize)
|
||||
{
|
||||
printf("[ext2fs] allocateInode(preferredGroup: %u, expectedSize: %u)\n", preferredGroup, expectedSize);
|
||||
kprintf("[ext2fs] allocateInode(preferredGroup: %u, expectedSize: %u)\n", preferredGroup, expectedSize);
|
||||
|
||||
unsigned neededBlocks = ceilDiv(expectedSize, blockSize());
|
||||
|
||||
printf("[ext2fs] minimum needed blocks: %u\n", neededBlocks);
|
||||
kprintf("[ext2fs] minimum needed blocks: %u\n", neededBlocks);
|
||||
|
||||
unsigned groupIndex = 0;
|
||||
|
||||
|
@ -724,11 +724,11 @@ unsigned Ext2FileSystem::allocateInode(unsigned preferredGroup, unsigned expecte
|
|||
}
|
||||
|
||||
if (!groupIndex) {
|
||||
printf("[ext2fs] allocateInode: no suitable group found for new inode with %u blocks needed :(\n", neededBlocks);
|
||||
kprintf("[ext2fs] allocateInode: no suitable group found for new inode with %u blocks needed :(\n", neededBlocks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("[ext2fs] allocateInode: found suitable group [%u] for new inode with %u blocks needed :^)\n", groupIndex, neededBlocks);
|
||||
kprintf("[ext2fs] allocateInode: found suitable group [%u] for new inode with %u blocks needed :^)\n", groupIndex, neededBlocks);
|
||||
|
||||
unsigned firstFreeInodeInGroup = 0;
|
||||
traverseInodeBitmap(groupIndex, [&firstFreeInodeInGroup] (unsigned firstInodeInBitmap, const Bitmap& bitmap) {
|
||||
|
@ -742,12 +742,12 @@ unsigned Ext2FileSystem::allocateInode(unsigned preferredGroup, unsigned expecte
|
|||
});
|
||||
|
||||
if (!firstFreeInodeInGroup) {
|
||||
printf("[ext2fs] firstFreeInodeInGroup returned no inode, despite bgd claiming there are inodes :(\n");
|
||||
kprintf("[ext2fs] firstFreeInodeInGroup returned no inode, despite bgd claiming there are inodes :(\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned inode = firstFreeInodeInGroup;
|
||||
printf("[ext2fs] found suitable inode %u\n", inode);
|
||||
kprintf("[ext2fs] found suitable inode %u\n", inode);
|
||||
|
||||
// FIXME: allocate blocks if needed!
|
||||
|
||||
|
@ -773,7 +773,7 @@ bool Ext2FileSystem::setInodeAllocationState(unsigned inode, bool newState)
|
|||
ASSERT(block);
|
||||
auto bitmap = Bitmap::wrap(block.pointer(), block.size());
|
||||
bool currentState = bitmap.get(bitIndex);
|
||||
printf("[ext2fs] setInodeAllocationState(%u) %u -> %u\n", inode, currentState, newState);
|
||||
kprintf("[ext2fs] setInodeAllocationState(%u) %u -> %u\n", inode, currentState, newState);
|
||||
|
||||
if (currentState == newState)
|
||||
return true;
|
||||
|
@ -783,7 +783,7 @@ bool Ext2FileSystem::setInodeAllocationState(unsigned inode, bool newState)
|
|||
|
||||
// Update superblock
|
||||
auto& sb = *reinterpret_cast<ext2_super_block*>(m_cachedSuperBlock.pointer());
|
||||
printf("[ext2fs] superblock free inode count %u -> %u\n", sb.s_free_inodes_count, sb.s_free_inodes_count - 1);
|
||||
kprintf("[ext2fs] superblock free inode count %u -> %u\n", sb.s_free_inodes_count, sb.s_free_inodes_count - 1);
|
||||
if (newState)
|
||||
--sb.s_free_inodes_count;
|
||||
else
|
||||
|
@ -796,7 +796,7 @@ bool Ext2FileSystem::setInodeAllocationState(unsigned inode, bool newState)
|
|||
--mutableBGD.bg_free_inodes_count;
|
||||
else
|
||||
++mutableBGD.bg_free_inodes_count;
|
||||
printf("[ext2fs] group free inode count %u -> %u\n", bgd.bg_free_inodes_count, bgd.bg_free_inodes_count - 1);
|
||||
kprintf("[ext2fs] group free inode count %u -> %u\n", bgd.bg_free_inodes_count, bgd.bg_free_inodes_count - 1);
|
||||
|
||||
unsigned blocksToWrite = ceilDiv(m_blockGroupCount * (unsigned)sizeof(ext2_group_desc), blockSize());
|
||||
unsigned firstBlockOfBGDT = blockSize() == 1024 ? 2 : 1;
|
||||
|
@ -817,7 +817,7 @@ bool Ext2FileSystem::setBlockAllocationState(GroupIndex group, BlockIndex bi, bo
|
|||
ASSERT(block);
|
||||
auto bitmap = Bitmap::wrap(block.pointer(), block.size());
|
||||
bool currentState = bitmap.get(bitIndex);
|
||||
printf("[ext2fs] setBlockAllocationState(%u) %u -> %u\n", block, currentState, newState);
|
||||
kprintf("[ext2fs] setBlockAllocationState(%u) %u -> %u\n", block, currentState, newState);
|
||||
|
||||
if (currentState == newState)
|
||||
return true;
|
||||
|
@ -827,7 +827,7 @@ bool Ext2FileSystem::setBlockAllocationState(GroupIndex group, BlockIndex bi, bo
|
|||
|
||||
// Update superblock
|
||||
auto& sb = *reinterpret_cast<ext2_super_block*>(m_cachedSuperBlock.pointer());
|
||||
printf("[ext2fs] superblock free block count %u -> %u\n", sb.s_free_blocks_count, sb.s_free_blocks_count - 1);
|
||||
kprintf("[ext2fs] superblock free block count %u -> %u\n", sb.s_free_blocks_count, sb.s_free_blocks_count - 1);
|
||||
if (newState)
|
||||
--sb.s_free_blocks_count;
|
||||
else
|
||||
|
@ -840,7 +840,7 @@ bool Ext2FileSystem::setBlockAllocationState(GroupIndex group, BlockIndex bi, bo
|
|||
--mutableBGD.bg_free_blocks_count;
|
||||
else
|
||||
++mutableBGD.bg_free_blocks_count;
|
||||
printf("[ext2fs] group free block count %u -> %u\n", bgd.bg_free_blocks_count, bgd.bg_free_blocks_count - 1);
|
||||
kprintf("[ext2fs] group free block count %u -> %u\n", bgd.bg_free_blocks_count, bgd.bg_free_blocks_count - 1);
|
||||
|
||||
unsigned blocksToWrite = ceilDiv(m_blockGroupCount * (unsigned)sizeof(ext2_group_desc), blockSize());
|
||||
unsigned firstBlockOfBGDT = blockSize() == 1024 ? 2 : 1;
|
||||
|
@ -865,13 +865,13 @@ InodeIdentifier Ext2FileSystem::makeDirectory(InodeIdentifier parentInode, const
|
|||
if (!inode.isValid())
|
||||
return { };
|
||||
|
||||
printf("[ext2fs] makeDirectory: created new directory named '%s' with inode %u\n", name.characters(), inode.index());
|
||||
kprintf("[ext2fs] makeDirectory: created new directory named '%s' with inode %u\n", name.characters(), inode.index());
|
||||
|
||||
Vector<DirectoryEntry> entries;
|
||||
entries.append({ ".", inode, EXT2_FT_DIR });
|
||||
entries.append({ "..", parentInode, EXT2_FT_DIR });
|
||||
|
||||
bool success = writeDirectoryInode(inode.index(), std::move(entries));
|
||||
bool success = writeDirectoryInode(inode.index(), move(entries));
|
||||
ASSERT(success);
|
||||
|
||||
success = modifyLinkCount(parentInode.index(), 1);
|
||||
|
@ -879,7 +879,7 @@ InodeIdentifier Ext2FileSystem::makeDirectory(InodeIdentifier parentInode, const
|
|||
|
||||
auto& bgd = const_cast<ext2_group_desc&>(blockGroupDescriptor(groupIndexFromInode(inode.index())));
|
||||
++bgd.bg_used_dirs_count;
|
||||
printf("[ext2fs] incremented bg_used_dirs_count %u -> %u\n", bgd.bg_used_dirs_count - 1, bgd.bg_used_dirs_count);
|
||||
kprintf("[ext2fs] incremented bg_used_dirs_count %u -> %u\n", bgd.bg_used_dirs_count - 1, bgd.bg_used_dirs_count);
|
||||
|
||||
unsigned blocksToWrite = ceilDiv(m_blockGroupCount * (unsigned)sizeof(ext2_group_desc), blockSize());
|
||||
unsigned firstBlockOfBGDT = blockSize() == 1024 ? 2 : 1;
|
||||
|
@ -894,19 +894,19 @@ InodeIdentifier Ext2FileSystem::createInode(InodeIdentifier parentInode, const S
|
|||
ASSERT(isDirectoryInode(parentInode.index()));
|
||||
|
||||
//#ifdef EXT2_DEBUG
|
||||
printf("[ext2fs] Adding inode '%s' (mode %o) to parent directory %u:\n", name.characters(), mode, parentInode.index());
|
||||
kprintf("[ext2fs] Adding inode '%s' (mode %o) to parent directory %u:\n", name.characters(), mode, parentInode.index());
|
||||
//#endif
|
||||
|
||||
// NOTE: This doesn't commit the inode allocation just yet!
|
||||
auto inode = allocateInode(0, 0);
|
||||
if (!inode) {
|
||||
printf("[ext2fs] createInode: allocateInode failed\n");
|
||||
kprintf("[ext2fs] createInode: allocateInode failed\n");
|
||||
return { };
|
||||
}
|
||||
|
||||
auto blocks = allocateBlocks(groupIndexFromInode(inode), ceilDiv(size, blockSize()));
|
||||
if (blocks.isEmpty()) {
|
||||
printf("[ext2fs] createInode: allocateBlocks failed\n");
|
||||
kprintf("[ext2fs] createInode: allocateBlocks failed\n");
|
||||
return { };
|
||||
}
|
||||
|
||||
|
@ -929,7 +929,7 @@ InodeIdentifier Ext2FileSystem::createInode(InodeIdentifier parentInode, const S
|
|||
// Try adding it to the directory first, in case the name is already in use.
|
||||
bool success = addInodeToDirectory(parentInode.index(), inode, name, fileType);
|
||||
if (!success) {
|
||||
printf("[ext2fs] failed to add inode to directory :(\n");
|
||||
kprintf("[ext2fs] failed to add inode to directory :(\n");
|
||||
return { };
|
||||
}
|
||||
|
||||
|
@ -965,7 +965,7 @@ InodeIdentifier Ext2FileSystem::createInode(InodeIdentifier parentInode, const S
|
|||
// FIXME: Implement writing out indirect blocks!
|
||||
ASSERT(blocks.size() < EXT2_NDIR_BLOCKS);
|
||||
|
||||
printf("[XXX] writing %u blocks to i_block array\n", min((size_t)EXT2_NDIR_BLOCKS, blocks.size()));
|
||||
kprintf("[XXX] writing %zu blocks to i_block array\n", min((size_t)EXT2_NDIR_BLOCKS, blocks.size()));
|
||||
for (unsigned i = 0; i < min((size_t)EXT2_NDIR_BLOCKS, blocks.size()); ++i) {
|
||||
e2inode->i_block[i] = blocks[i];
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ class Ext2FileSystem final : public DiskBackedFileSystem {
|
|||
public:
|
||||
static RetainPtr<Ext2FileSystem> create(RetainPtr<DiskDevice>&&);
|
||||
virtual ~Ext2FileSystem() override;
|
||||
virtual bool initialize() override;
|
||||
|
||||
private:
|
||||
typedef unsigned BlockIndex;
|
||||
|
@ -36,11 +37,10 @@ private:
|
|||
ByteBuffer readSuperBlock() const;
|
||||
bool writeSuperBlock(const ext2_super_block&);
|
||||
|
||||
virtual bool initialize() override;
|
||||
virtual const char* className() const override;
|
||||
virtual InodeIdentifier rootInode() const override;
|
||||
virtual bool writeInode(InodeIdentifier, const ByteBuffer&) override;
|
||||
virtual bool enumerateDirectoryInode(InodeIdentifier, std::function<bool(const DirectoryEntry&)>) const override;
|
||||
virtual bool enumerateDirectoryInode(InodeIdentifier, Function<bool(const DirectoryEntry&)>) const override;
|
||||
virtual InodeMetadata inodeMetadata(InodeIdentifier) const override;
|
||||
virtual bool setModificationTime(InodeIdentifier, dword timestamp) override;
|
||||
virtual InodeIdentifier createInode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size) override;
|
||||
|
|
|
@ -34,17 +34,17 @@ unsigned FileBackedDiskDevice::blockSize() const
|
|||
|
||||
bool FileBackedDiskDevice::readBlock(unsigned index, byte* out) const
|
||||
{
|
||||
qword offset = index * m_blockSize;
|
||||
DiskOffset offset = index * m_blockSize;
|
||||
return readInternal(offset, blockSize(), out);
|
||||
}
|
||||
|
||||
bool FileBackedDiskDevice::writeBlock(unsigned index, const byte* data)
|
||||
{
|
||||
qword offset = index * m_blockSize;
|
||||
DiskOffset offset = index * m_blockSize;
|
||||
return writeInternal(offset, blockSize(), data);
|
||||
}
|
||||
|
||||
bool FileBackedDiskDevice::readInternal(qword offset, unsigned length, byte* out) const
|
||||
bool FileBackedDiskDevice::readInternal(DiskOffset offset, unsigned length, byte* out) const
|
||||
{
|
||||
#ifndef IGNORE_FILE_LENGTH
|
||||
if (offset + length >= m_fileLength)
|
||||
|
@ -59,7 +59,7 @@ bool FileBackedDiskDevice::readInternal(qword offset, unsigned length, byte* out
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FileBackedDiskDevice::writeInternal(qword offset, unsigned length, const byte* data)
|
||||
bool FileBackedDiskDevice::writeInternal(DiskOffset offset, unsigned length, const byte* data)
|
||||
{
|
||||
#ifndef IGNORE_FILE_LENGTH
|
||||
if (offset + length >= m_fileLength)
|
||||
|
|
|
@ -20,14 +20,14 @@ public:
|
|||
private:
|
||||
virtual const char* className() const override;
|
||||
|
||||
bool readInternal(qword offset, unsigned length, byte* out) const;
|
||||
bool writeInternal(qword offset, unsigned length, const byte* data);
|
||||
bool readInternal(DiskOffset, unsigned length, byte* out) const;
|
||||
bool writeInternal(DiskOffset, unsigned length, const byte* data);
|
||||
|
||||
FileBackedDiskDevice(String&& imagePath, unsigned blockSize);
|
||||
|
||||
String m_imagePath;
|
||||
FILE* m_file { nullptr };
|
||||
qword m_fileLength { 0 };
|
||||
DiskOffset m_fileLength { 0 };
|
||||
unsigned m_blockSize { 0 };
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,9 @@ static dword s_lastFileSystemID = 0;
|
|||
|
||||
static HashMap<dword, FileSystem*>& fileSystems()
|
||||
{
|
||||
static auto* map = new HashMap<dword, FileSystem*>();
|
||||
static HashMap<dword, FileSystem*>* map;
|
||||
if (!map)
|
||||
map = new HashMap<dword, FileSystem*>();
|
||||
return *map;
|
||||
}
|
||||
|
||||
|
@ -48,7 +50,7 @@ ByteBuffer FileSystem::readEntireInode(InodeIdentifier inode) const
|
|||
|
||||
auto metadata = inodeMetadata(inode);
|
||||
if (!metadata.isValid()) {
|
||||
printf("[fs] readInode: metadata lookup for inode %u failed\n", inode.index());
|
||||
kprintf("[fs] readInode: metadata lookup for inode %u failed\n", inode.index());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -67,7 +69,7 @@ ByteBuffer FileSystem::readEntireInode(InodeIdentifier inode) const
|
|||
offset += nread;
|
||||
}
|
||||
if (nread < 0) {
|
||||
printf("[fs] readInode: ERROR: %d\n", nread);
|
||||
kprintf("[fs] readInode: ERROR: %d\n", nread);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
#include <AK/Retainable.h>
|
||||
#include <AK/RetainPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <functional>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/kstdio.h>
|
||||
|
||||
static const dword mepoch = 476763780;
|
||||
|
||||
|
@ -35,7 +36,7 @@ public:
|
|||
InodeIdentifier inode;
|
||||
byte fileType { 0 };
|
||||
};
|
||||
virtual bool enumerateDirectoryInode(InodeIdentifier, std::function<bool(const DirectoryEntry&)>) const = 0;
|
||||
virtual bool enumerateDirectoryInode(InodeIdentifier, Function<bool(const DirectoryEntry&)>) const = 0;
|
||||
|
||||
virtual bool setModificationTime(InodeIdentifier, dword timestamp) = 0;
|
||||
virtual InodeIdentifier createInode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size) = 0;
|
||||
|
@ -79,7 +80,7 @@ template<>
|
|||
struct Traits<InodeIdentifier> {
|
||||
// FIXME: This is a shitty hash.
|
||||
static unsigned hash(const InodeIdentifier& inode) { return Traits<unsigned>::hash(inode.fileSystemID()) + Traits<unsigned>::hash(inode.index()); }
|
||||
static void dump(const InodeIdentifier& inode) { printf("%02u:%08u", inode.fileSystemID(), inode.index()); }
|
||||
static void dump(const InodeIdentifier& inode) { kprintf("%02u:%08u", inode.fileSystemID(), inode.index()); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "UnixTypes.h"
|
||||
|
||||
#ifdef SERENITY_KERNEL
|
||||
inline static const Unix::off_t maxFileOffset = 9223372036854775807LL;
|
||||
inline static const Unix::off_t maxFileOffset = 2147483647;
|
||||
#else
|
||||
#include <limits>
|
||||
inline static const Unix::off_t maxFileOffset = std::numeric_limits<Unix::off_t>::max();
|
||||
|
|
|
@ -62,7 +62,7 @@ InodeIdentifier SyntheticFileSystem::rootInode() const
|
|||
return { id(), 1 };
|
||||
}
|
||||
|
||||
bool SyntheticFileSystem::enumerateDirectoryInode(InodeIdentifier inode, std::function<bool(const DirectoryEntry&)> callback) const
|
||||
bool SyntheticFileSystem::enumerateDirectoryInode(InodeIdentifier inode, Function<bool(const DirectoryEntry&)> callback) const
|
||||
{
|
||||
ASSERT(inode.fileSystemID() == id());
|
||||
#ifdef SYNTHFS_DEBUG
|
||||
|
|
|
@ -13,7 +13,7 @@ public:
|
|||
virtual const char* className() const override;
|
||||
virtual InodeIdentifier rootInode() const override;
|
||||
virtual bool writeInode(InodeIdentifier, const ByteBuffer&) override;
|
||||
virtual bool enumerateDirectoryInode(InodeIdentifier, std::function<bool(const DirectoryEntry&)>) const override;
|
||||
virtual bool enumerateDirectoryInode(InodeIdentifier, Function<bool(const DirectoryEntry&)>) const override;
|
||||
virtual InodeMetadata inodeMetadata(InodeIdentifier) const override;
|
||||
virtual bool setModificationTime(InodeIdentifier, dword timestamp) override;
|
||||
virtual InodeIdentifier createInode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size) override;
|
||||
|
|
|
@ -14,7 +14,14 @@ typedef dword mode_t;
|
|||
typedef dword nlink_t;
|
||||
typedef dword uid_t;
|
||||
typedef dword gid_t;
|
||||
|
||||
#ifdef SERENITY_KERNEL
|
||||
// FIXME: Support 64-bit offsets!
|
||||
typedef signed_dword off_t;
|
||||
#else
|
||||
typedef signed_qword off_t;
|
||||
#endif
|
||||
|
||||
typedef dword blksize_t;
|
||||
typedef dword blkcnt_t;
|
||||
typedef long int time_t;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#include "FileHandle.h"
|
||||
#include "FileSystem.h"
|
||||
#include <AK/kmalloc.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <AK/kstdio.h>
|
||||
#include <AK/ktime.h>
|
||||
|
||||
//#define VFS_DEBUG
|
||||
|
||||
|
@ -24,7 +24,7 @@ VirtualFileSystem::VirtualFileSystem()
|
|||
|
||||
VirtualFileSystem::~VirtualFileSystem()
|
||||
{
|
||||
printf("[VFS] ~VirtualFileSystem with %u nodes allocated\n", allocatedNodeCount());
|
||||
kprintf("[VFS] ~VirtualFileSystem with %u nodes allocated\n", allocatedNodeCount());
|
||||
}
|
||||
|
||||
auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr<Node>
|
||||
|
@ -39,7 +39,7 @@ auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr<Node>
|
|||
if (it != m_characterDevices.end()) {
|
||||
characterDevice = (*it).value;
|
||||
} else {
|
||||
printf("[VFS] makeNode() no such character device %u,%u\n", metadata.majorDevice, metadata.minorDevice);
|
||||
kprintf("[VFS] makeNode() no such character device %u,%u\n", metadata.majorDevice, metadata.minorDevice);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr<Node>
|
|||
vnode->inode = inode;
|
||||
|
||||
#ifdef VFS_DEBUG
|
||||
printf("makeNode: inode=%u, size=%u, mode=%o, uid=%u, gid=%u\n", inode.index(), metadata.size, metadata.mode, metadata.uid, metadata.gid);
|
||||
kprintf("makeNode: inode=%u, size=%u, mode=%o, uid=%u, gid=%u\n", inode.index(), metadata.size, metadata.mode, metadata.uid, metadata.gid);
|
||||
#endif
|
||||
|
||||
m_inode2vnode.set(inode, vnode.ptr());
|
||||
|
@ -75,11 +75,11 @@ bool VirtualFileSystem::mount(RetainPtr<FileSystem>&& fileSystem, const String&
|
|||
|
||||
auto inode = resolvePath(path);
|
||||
if (!inode.isValid()) {
|
||||
printf("[VFS] mount can't resolve mount point '%s'\n", path.characters());
|
||||
kprintf("[VFS] mount can't resolve mount point '%s'\n", path.characters());
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("mounting %s{%p} at %s (inode: %u)\n", fileSystem->className(), fileSystem.ptr(), path.characters(), inode.index());
|
||||
kprintf("mounting %s{%p} at %s (inode: %u)\n", fileSystem->className(), fileSystem.ptr(), path.characters(), inode.index());
|
||||
// FIXME: check that this is not already a mount point
|
||||
auto mount = make<Mount>(inode, std::move(fileSystem));
|
||||
m_mounts.append(std::move(mount));
|
||||
|
@ -89,7 +89,7 @@ bool VirtualFileSystem::mount(RetainPtr<FileSystem>&& fileSystem, const String&
|
|||
bool VirtualFileSystem::mountRoot(RetainPtr<FileSystem>&& fileSystem)
|
||||
{
|
||||
if (m_rootNode) {
|
||||
printf("[VFS] mountRoot can't mount another root\n");
|
||||
kprintf("[VFS] mountRoot can't mount another root\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -97,17 +97,17 @@ bool VirtualFileSystem::mountRoot(RetainPtr<FileSystem>&& fileSystem)
|
|||
|
||||
auto node = makeNode(mount->guest());
|
||||
if (!node->inUse()) {
|
||||
printf("[VFS] root inode for / is not in use :(\n");
|
||||
kprintf("[VFS] root inode for / is not in use :(\n");
|
||||
return false;
|
||||
}
|
||||
if (!node->inode.metadata().isDirectory()) {
|
||||
printf("[VFS] root inode for / is not in use :(\n");
|
||||
kprintf("[VFS] root inode for / is not in use :(\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_rootNode = std::move(node);
|
||||
|
||||
printf("[VFS] mountRoot mounted %s{%p}\n",
|
||||
kprintf("[VFS] mountRoot mounted %s{%p}\n",
|
||||
m_rootNode->fileSystem()->className(),
|
||||
m_rootNode->fileSystem());
|
||||
|
||||
|
@ -118,7 +118,7 @@ bool VirtualFileSystem::mountRoot(RetainPtr<FileSystem>&& fileSystem)
|
|||
auto VirtualFileSystem::allocateNode() -> RetainPtr<Node>
|
||||
{
|
||||
if (m_nodeFreeList.isEmpty()) {
|
||||
printf("[VFS] allocateNode has no nodes left\n");
|
||||
kprintf("[VFS] allocateNode has no nodes left\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto* node = m_nodeFreeList.takeLast();
|
||||
|
@ -200,7 +200,7 @@ void VirtualFileSystem::listDirectory(const String& path)
|
|||
if (!directoryInode.isValid())
|
||||
return;
|
||||
|
||||
printf("[VFS] ls %s -> %s %02u:%08u\n", path.characters(), directoryInode.fileSystem()->className(), directoryInode.fileSystemID(), directoryInode.index());
|
||||
kprintf("[VFS] ls %s -> %s %02u:%08u\n", path.characters(), directoryInode.fileSystem()->className(), directoryInode.fileSystemID(), directoryInode.index());
|
||||
enumerateDirectoryInode(directoryInode, [&] (const FileSystem::DirectoryEntry& entry) {
|
||||
const char* nameColorBegin = "";
|
||||
const char* nameColorEnd = "";
|
||||
|
@ -221,28 +221,28 @@ void VirtualFileSystem::listDirectory(const String& path)
|
|||
nameColorBegin = "\033[33;1m";
|
||||
nameColorEnd = "\033[0m";
|
||||
}
|
||||
printf("%02u:%08u ",
|
||||
kprintf("%02u:%08u ",
|
||||
metadata.inode.fileSystemID(),
|
||||
metadata.inode.index());
|
||||
|
||||
if (metadata.isDirectory())
|
||||
printf("d");
|
||||
kprintf("d");
|
||||
else if (metadata.isSymbolicLink())
|
||||
printf("l");
|
||||
kprintf("l");
|
||||
else if (metadata.isBlockDevice())
|
||||
printf("b");
|
||||
kprintf("b");
|
||||
else if (metadata.isCharacterDevice())
|
||||
printf("c");
|
||||
kprintf("c");
|
||||
else if (metadata.isSocket())
|
||||
printf("s");
|
||||
kprintf("s");
|
||||
else if (metadata.isFIFO())
|
||||
printf("f");
|
||||
kprintf("f");
|
||||
else if (metadata.isRegularFile())
|
||||
printf("-");
|
||||
kprintf("-");
|
||||
else
|
||||
printf("?");
|
||||
kprintf("?");
|
||||
|
||||
printf("%c%c%c%c%c%c%c%c",
|
||||
kprintf("%c%c%c%c%c%c%c%c",
|
||||
metadata.mode & 00400 ? 'r' : '-',
|
||||
metadata.mode & 00200 ? 'w' : '-',
|
||||
metadata.mode & 00100 ? 'x' : '-',
|
||||
|
@ -254,41 +254,41 @@ void VirtualFileSystem::listDirectory(const String& path)
|
|||
);
|
||||
|
||||
if (metadata.isSticky())
|
||||
printf("t");
|
||||
kprintf("t");
|
||||
else
|
||||
printf("%c", metadata.mode & 00001 ? 'x' : '-');
|
||||
kprintf("%c", metadata.mode & 00001 ? 'x' : '-');
|
||||
|
||||
if (metadata.isCharacterDevice() || metadata.isBlockDevice()) {
|
||||
char buf[16];
|
||||
sprintf(buf, "%u, %u", metadata.majorDevice, metadata.minorDevice);
|
||||
printf("%12s ", buf);
|
||||
kprintf("%12s ", buf);
|
||||
} else {
|
||||
printf("%12lld ", metadata.size);
|
||||
kprintf("%12lld ", metadata.size);
|
||||
}
|
||||
|
||||
printf("\033[30;1m");
|
||||
kprintf("\033[30;1m");
|
||||
auto tm = *localtime(&metadata.mtime);
|
||||
printf("%04u-%02u-%02u %02u:%02u:%02u ",
|
||||
kprintf("%04u-%02u-%02u %02u:%02u:%02u ",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec);
|
||||
printf("\033[0m");
|
||||
kprintf("\033[0m");
|
||||
|
||||
printf("%s%s%s",
|
||||
kprintf("%s%s%s",
|
||||
nameColorBegin,
|
||||
entry.name.characters(),
|
||||
nameColorEnd);
|
||||
|
||||
if (metadata.isDirectory()) {
|
||||
printf("/");
|
||||
kprintf("/");
|
||||
} else if (metadata.isSymbolicLink()) {
|
||||
auto symlinkContents = directoryInode.fileSystem()->readEntireInode(metadata.inode);
|
||||
printf(" -> %s", String((const char*)symlinkContents.pointer(), symlinkContents.size()).characters());
|
||||
kprintf(" -> %s", String((const char*)symlinkContents.pointer(), symlinkContents.size()).characters());
|
||||
}
|
||||
printf("\n");
|
||||
kprintf("\n");
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ void VirtualFileSystem::listDirectoryRecursively(const String& path)
|
|||
if (!directory.isValid())
|
||||
return;
|
||||
|
||||
printf("%s\n", path.characters());
|
||||
kprintf("%s\n", path.characters());
|
||||
|
||||
enumerateDirectoryInode(directory, [&] (const FileSystem::DirectoryEntry& entry) {
|
||||
auto metadata = entry.inode.metadata();
|
||||
|
@ -310,7 +310,7 @@ void VirtualFileSystem::listDirectoryRecursively(const String& path)
|
|||
listDirectoryRecursively(buf);
|
||||
}
|
||||
} else {
|
||||
printf("%s/%s\n", path.characters(), entry.name.characters());
|
||||
kprintf("%s/%s\n", path.characters(), entry.name.characters());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -368,35 +368,35 @@ InodeIdentifier VirtualFileSystem::resolvePath(const String& path)
|
|||
auto metadata = inode.metadata();
|
||||
if (!metadata.isValid()) {
|
||||
#ifdef VFS_DEBUG
|
||||
printf("invalid metadata\n");
|
||||
kprintf("invalid metadata\n");
|
||||
#endif
|
||||
return InodeIdentifier();
|
||||
}
|
||||
if (!metadata.isDirectory()) {
|
||||
#ifdef VFS_DEBUG
|
||||
printf("not directory\n");
|
||||
kprintf("not directory\n");
|
||||
#endif
|
||||
return InodeIdentifier();
|
||||
}
|
||||
inode = inode.fileSystem()->childOfDirectoryInodeWithName(inode, part);
|
||||
if (!inode.isValid()) {
|
||||
#ifdef VFS_DEBUG
|
||||
printf("bad child\n");
|
||||
kprintf("bad child\n");
|
||||
#endif
|
||||
return InodeIdentifier();
|
||||
}
|
||||
#ifdef VFS_DEBUG
|
||||
printf("<%s> %02u:%08u\n", part.characters(), inode.fileSystemID(), inode.index());
|
||||
kprintf("<%s> %02u:%08u\n", part.characters(), inode.fileSystemID(), inode.index());
|
||||
#endif
|
||||
if (auto mount = findMountForHost(inode)) {
|
||||
#ifdef VFS_DEBUG
|
||||
printf(" -- is host\n");
|
||||
kprintf(" -- is host\n");
|
||||
#endif
|
||||
inode = mount->guest();
|
||||
}
|
||||
if (inode.isRootInode() && !isRoot(inode) && part == "..") {
|
||||
#ifdef VFS_DEBUG
|
||||
printf(" -- is guest\n");
|
||||
kprintf(" -- is guest\n");
|
||||
#endif
|
||||
auto mount = findMountForGuest(inode);
|
||||
inode = mount->host();
|
||||
|
@ -411,7 +411,7 @@ InodeIdentifier VirtualFileSystem::resolvePath(const String& path)
|
|||
}
|
||||
inode = resolveSymbolicLink(buf, inode);
|
||||
if (!inode.isValid()) {
|
||||
printf("Symbolic link resolution failed :(\n");
|
||||
kprintf("Symbolic link resolution failed :(\n");
|
||||
return { };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#include "RandomDevice.h"
|
||||
#include <cstring>
|
||||
#include <AK/SimpleMalloc.h>
|
||||
#include <AK/StdLib.h>
|
||||
#include <AK/kmalloc.h>
|
||||
#include <AK/ktime.h>
|
||||
|
||||
static RetainPtr<FileSystem> makeFileSystem(const char* imagePath);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue