From 9171521752b0b382f1f70453b4f24915999144b9 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 17 Oct 2018 10:55:43 +0200 Subject: [PATCH] Integrate ext2 from VFS into Kernel. --- AK/Buffer.h | 3 +- AK/DoublyLinkedList.h | 4 +- AK/Function.h | 111 +++++ AK/HashMap.h | 13 +- AK/HashTable.h | 44 +- AK/StdLib.h | 86 +++- AK/String.cpp | 2 +- AK/String.h | 10 +- AK/StringImpl.cpp | 9 +- AK/Traits.h | 8 +- AK/Vector.h | 1 - AK/kmalloc.cpp | 2 +- AK/kmalloc.h | 9 +- AK/ktime.h | 15 + Kernel/.bochsrc | 54 +++ Kernel/Boot/boot.asm | 134 +++++- Kernel/Ext2FileSystem.h | 74 --- ...{DoublyLinkedList.h => InlineLinkedList.h} | 34 +- Kernel/Makefile | 13 +- Kernel/OwnPtr.h | 78 --- Kernel/StdLib.cpp | 9 + Kernel/StdLib.h | 13 +- Kernel/String.cpp | 86 ---- Kernel/String.h | 31 -- Kernel/Task.cpp | 8 +- Kernel/Task.h | 10 +- Kernel/Vector.h | 90 ---- Kernel/fs.cpp | 451 ------------------ Kernel/init.cpp | 6 +- Kernel/run | 4 +- VirtualFileSystem/DiskBackedFileSystem.cpp | 8 +- VirtualFileSystem/DiskDevice.cpp | 14 +- VirtualFileSystem/DiskDevice.h | 11 +- VirtualFileSystem/Ext2FileSystem.cpp | 168 +++---- VirtualFileSystem/Ext2FileSystem.h | 4 +- VirtualFileSystem/FileBackedDiskDevice.cpp | 8 +- VirtualFileSystem/FileBackedDiskDevice.h | 6 +- VirtualFileSystem/FileSystem.cpp | 8 +- VirtualFileSystem/FileSystem.h | 7 +- VirtualFileSystem/Limits.h | 2 +- VirtualFileSystem/SyntheticFileSystem.cpp | 2 +- VirtualFileSystem/SyntheticFileSystem.h | 2 +- VirtualFileSystem/UnixTypes.h | 7 + VirtualFileSystem/VirtualFileSystem.cpp | 86 ++-- VirtualFileSystem/test.cpp | 2 + 45 files changed, 662 insertions(+), 1085 deletions(-) create mode 100644 AK/Function.h create mode 100644 AK/ktime.h create mode 100644 Kernel/.bochsrc delete mode 100644 Kernel/Ext2FileSystem.h rename Kernel/{DoublyLinkedList.h => InlineLinkedList.h} (71%) delete mode 100644 Kernel/OwnPtr.h delete mode 100644 Kernel/String.cpp delete mode 100644 Kernel/String.h delete mode 100644 Kernel/Vector.h delete mode 100644 Kernel/fs.cpp diff --git a/AK/Buffer.h b/AK/Buffer.h index 91ef48cda23..efed0313b44 100644 --- a/AK/Buffer.h +++ b/AK/Buffer.h @@ -3,8 +3,7 @@ #include "Assertions.h" #include "Retainable.h" #include "RetainPtr.h" -#include -#include +#include "StdLib.h" #include "kmalloc.h" namespace AK { diff --git a/AK/DoublyLinkedList.h b/AK/DoublyLinkedList.h index fe65bb6264f..a5a72562d6b 100644 --- a/AK/DoublyLinkedList.h +++ b/AK/DoublyLinkedList.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "StdLib.h" namespace AK { @@ -38,7 +38,7 @@ public: void append(T&& value) { - auto* node = new Node(std::move(value)); + auto* node = new Node(move(value)); if (!m_head) { ASSERT(!m_tail); m_head = node; diff --git a/AK/Function.h b/AK/Function.h new file mode 100644 index 00000000000..0fef35abe84 --- /dev/null +++ b/AK/Function.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "OwnPtr.h" +#include "StdLib.h" + +namespace AK { + +template class Function; + +template +class Function { +public: + Function() = default; + Function(std::nullptr_t) { } + + template::value && IsFunction::Type>::value) && IsRvalueReference::value>::Type> + Function(CallableType&& callable) + : m_callableWrapper(make>(move(callable))) + { + } + + template::value && IsFunction::Type>::value>::Type> + Function(FunctionType f) + : m_callableWrapper(make>(move(f))) + { + } + + Out operator()(In... in) + { + ASSERT(m_callableWrapper); + return m_callableWrapper->call(forward(in)...); + } + + explicit operator bool() const { return !!m_callableWrapper; } + + template::value && IsFunction::Type>::value) && IsRvalueReference::value>::Type> + Function& operator=(CallableType&& callable) + { + m_callableWrapper = make>(move(callable)); + return *this; + } + + template::value && IsFunction::Type>::value>::Type> + Function& operator=(FunctionType f) + { + m_callableWrapper = make>(move(f)); + return *this; + } + + Function& operator=(std::nullptr_t) + { + m_callableWrapper = nullptr; + return *this; + } + +private: + class CallableWrapperBase { + public: + virtual ~CallableWrapperBase() { } + virtual Out call(In...) = 0; + }; + + template + class CallableWrapper : public CallableWrapperBase { + public: + explicit CallableWrapper(CallableType&& callable) + : m_callable(move(callable)) + { + } + + CallableWrapper(const CallableWrapper&) = delete; + CallableWrapper& operator=(const CallableWrapper&) = delete; + + Out call(In... in) final { return m_callable(forward(in)...); } + + private: + CallableType m_callable; + }; + + OwnPtr m_callableWrapper; +}; + +} + +using AK::Function; + diff --git a/AK/HashMap.h b/AK/HashMap.h index 751f2dbb1ab..70f4259e055 100644 --- a/AK/HashMap.h +++ b/AK/HashMap.h @@ -1,7 +1,8 @@ #pragma once #include "HashTable.h" -#include +#include "StdLib.h" +#include "kstdio.h" namespace AK { @@ -22,9 +23,9 @@ private: static unsigned hash(const Entry& entry) { return Traits::hash(entry.key); } static void dump(const Entry& entry) { - printf("key="); + kprintf("key="); Traits::dump(entry.key); - printf(" value="); + kprintf(" value="); Traits::dump(entry.value); } }; @@ -33,14 +34,14 @@ public: HashMap() { } HashMap(HashMap&& other) - : m_table(std::move(other.m_table)) + : m_table(move(other.m_table)) { } HashMap& operator=(HashMap&& other) { if (this != &other) { - m_table = std::move(other.m_table); + m_table = move(other.m_table); } return *this; } @@ -73,7 +74,7 @@ private: template void HashMap::set(const K& key, V&& value) { - m_table.set(Entry{key, std::move(value)}); + m_table.set(Entry{key, move(value)}); } template diff --git a/AK/HashTable.h b/AK/HashTable.h index e42c3c4dbe0..807b1e845ba 100644 --- a/AK/HashTable.h +++ b/AK/HashTable.h @@ -3,8 +3,8 @@ #include "Assertions.h" #include "DoublyLinkedList.h" #include "Traits.h" -#include -#include +#include "StdLib.h" +#include "kstdio.h" //#define HASHTABLE_DEBUG @@ -68,7 +68,7 @@ public: T& operator*() { #ifdef HASHTABLE_DEBUG - printf("retrieve { bucketIndex: %u, isEnd: %u }\n", m_bucketIndex, m_isEnd); + kprintf("retrieve { bucketIndex: %u, isEnd: %u }\n", m_bucketIndex, m_isEnd); #endif return *m_bucketIterator; } @@ -86,7 +86,7 @@ public: while (!m_isEnd) { #ifdef HASHTABLE_DEBUG ++pass; - printf("skipToNext pass %u, m_bucketIndex=%u\n", pass, m_bucketIndex); + kprintf("skipToNext pass %u, m_bucketIndex=%u\n", pass, m_bucketIndex); #endif if (m_bucketIterator.isEnd()) { ++m_bucketIndex; @@ -112,7 +112,7 @@ public: { if (!isEnd && !m_table.isEmpty() && !(m_bucketIterator != DoublyLinkedList::Iterator::universalEnd())) { #ifdef HASHTABLE_DEBUG - printf("bucket iterator init!\n"); + kprintf("bucket iterator init!\n"); #endif m_bucketIterator = m_table.m_buckets[0].chain.begin(); if (m_bucketIterator.isEnd()) @@ -143,7 +143,7 @@ public: const T& operator*() const { #ifdef HASHTABLE_DEBUG - printf("retrieve { bucketIndex: %u, isEnd: %u }\n", m_bucketIndex, m_isEnd); + kprintf("retrieve { bucketIndex: %u, isEnd: %u }\n", m_bucketIndex, m_isEnd); #endif return *m_bucketIterator; } @@ -161,7 +161,7 @@ public: while (!m_isEnd) { #ifdef HASHTABLE_DEBUG ++pass; - printf("skipToNext pass %u, m_bucketIndex=%u\n", pass, m_bucketIndex); + kprintf("skipToNext pass %u, m_bucketIndex=%u\n", pass, m_bucketIndex); #endif if (m_bucketIterator.isEnd()) { ++m_bucketIndex; @@ -188,7 +188,7 @@ public: { if (!isEnd && !m_table.isEmpty() && !(m_bucketIterator != DoublyLinkedList::ConstIterator::universalEnd())) { #ifdef HASHTABLE_DEBUG - printf("const bucket iterator init!\n"); + kprintf("const bucket iterator init!\n"); #endif const DoublyLinkedList& chain = m_table.m_buckets[0].chain; m_bucketIterator = chain.begin(); @@ -242,9 +242,9 @@ void HashTable::set(T&& value) } if (size() >= capacity()) { rehash(size() + 1); - insert(std::move(value)); + insert(move(value)); } else { - bucket.chain.append(std::move(value)); + bucket.chain.append(move(value)); } m_size++; } @@ -254,7 +254,7 @@ void HashTable::rehash(unsigned newCapacity) { newCapacity *= 2; #ifdef HASHTABLE_DEBUG - printf("rehash to %u buckets\n", newCapacity); + kprintf("rehash to %u buckets\n", newCapacity); #endif auto* newBuckets = new Bucket[newCapacity]; auto* oldBuckets = m_buckets; @@ -263,11 +263,11 @@ void HashTable::rehash(unsigned newCapacity) m_capacity = newCapacity; #ifdef HASHTABLE_DEBUG - printf("reinsert %u buckets\n", oldCapacity); + kprintf("reinsert %u buckets\n", oldCapacity); #endif for (unsigned i = 0; i < oldCapacity; ++i) { for (auto& value : oldBuckets[i].chain) { - insert(std::move(value)); + insert(move(value)); } } @@ -286,7 +286,7 @@ template void HashTable::insert(T&& value) { auto& bucket = lookup(value); - bucket.chain.append(std::move(value)); + bucket.chain.append(move(value)); } template @@ -341,9 +341,9 @@ typename HashTable::Bucket& HashTable::lookup(cons { unsigned hash = TraitsForT::hash(value); #ifdef HASHTABLE_DEBUG - printf("hash for "); + kprintf("hash for "); TraitsForT::dump(value); - printf(" is %u\n", hash); + kprintf(" is %u\n", hash); #endif if (bucketIndex) *bucketIndex = hash % m_capacity; @@ -355,9 +355,9 @@ const typename HashTable::Bucket& HashTable::looku { unsigned hash = TraitsForT::hash(value); #ifdef HASHTABLE_DEBUG - printf("hash for "); + kprintf("hash for "); TraitsForT::dump(value); - printf(" is %u\n", hash); + kprintf(" is %u\n", hash); #endif if (bucketIndex) *bucketIndex = hash % m_capacity; @@ -367,14 +367,14 @@ const typename HashTable::Bucket& HashTable::looku template void HashTable::dump() const { - printf("HashTable{%p} m_size=%u, m_capacity=%u, m_buckets=%p\n", this, m_size, m_capacity, m_buckets); + kprintf("HashTable{%p} m_size=%u, m_capacity=%u, m_buckets=%p\n", this, m_size, m_capacity, m_buckets); for (unsigned i = 0; i < m_capacity; ++i) { auto& bucket = m_buckets[i]; - printf("Bucket %u\n", i); + kprintf("Bucket %u\n", i); for (auto& e : bucket.chain) { - printf(" > "); + kprintf(" > "); TraitsForT::dump(e); - printf("\n"); + kprintf("\n"); } } } diff --git a/AK/StdLib.h b/AK/StdLib.h index 20d32e8139d..ca7196432cd 100644 --- a/AK/StdLib.h +++ b/AK/StdLib.h @@ -4,6 +4,7 @@ #include #else #include +#include #include #endif @@ -38,11 +39,12 @@ T&& move(T& arg) } template -struct identity { - typedef T type; +struct Identity { + typedef T Type; }; + template -constexpr T&& forward(typename identity::type& param) +constexpr T&& forward(typename Identity::Type& param) { return static_cast(param); } @@ -63,6 +65,84 @@ void swap(T& a, U& b) b = move(tmp); } +template +struct EnableIf +{ +}; + +template +struct EnableIf +{ + typedef T Type; +}; + +template struct RemoveConst { typedef T Type; }; +template struct RemoveConst { typedef T Type; }; +template struct RemoveVolatile { typedef T Type; }; +template struct RemoveVolatile { typedef T Type; }; +template struct RemoveCV { + typedef typename RemoveVolatile::Type>::Type Type; +}; + +template +struct IntegralConstant { + static constexpr T value = v; + typedef T ValueType; + typedef IntegralConstant Type; + constexpr operator ValueType() const { return value; } + constexpr ValueType operator()() const { return value; } +}; + +typedef IntegralConstant FalseType; +typedef IntegralConstant TrueType; + +template +struct __IsPointerHelper : FalseType { }; + +template +struct __IsPointerHelper : TrueType { }; + +template +struct IsPointer : __IsPointerHelper::Type> { }; + +template struct IsFunction : FalseType { }; + +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; + +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; + +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; +template struct IsFunction : TrueType { }; + +template struct IsRvalueReference : FalseType { }; +template struct IsRvalueReference : TrueType { }; + +template struct RemovePointer { typedef T Type; }; +template struct RemovePointer { typedef T Type; }; +template struct RemovePointer { typedef T Type; }; +template struct RemovePointer { typedef T Type; }; +template struct RemovePointer { typedef T Type; }; + } using AK::min; diff --git a/AK/String.cpp b/AK/String.cpp index 601076d7ff6..201bc8d7c12 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -1,5 +1,5 @@ #include "String.h" -#include +#include "StdLib.h" namespace AK { diff --git a/AK/String.h b/AK/String.h index bb184949862..4def06f2e6c 100644 --- a/AK/String.h +++ b/AK/String.h @@ -5,7 +5,7 @@ #include "StringImpl.h" #include "Traits.h" #include "Vector.h" -#include +#include "kstdio.h" namespace AK { @@ -20,7 +20,7 @@ public: } String(String&& other) - : m_impl(std::move(other.m_impl)) + : m_impl(move(other.m_impl)) { } @@ -40,7 +40,7 @@ public: } String(RetainPtr&& impl) - : m_impl(std::move(impl)) + : m_impl(move(impl)) { } @@ -77,7 +77,7 @@ public: String& operator=(String&& other) { if (this != &other) { - m_impl = std::move(other.m_impl); + m_impl = move(other.m_impl); } return *this; } @@ -91,7 +91,7 @@ private: template<> struct Traits { static unsigned hash(const String& s) { return s.impl() ? s.impl()->hash() : 0; } - static void dump(const String& s) { printf("%s", s.characters()); } + static void dump(const String& s) { kprintf("%s", s.characters()); } }; } diff --git a/AK/StringImpl.cpp b/AK/StringImpl.cpp index 6276c20a0e8..1c00f5a35e4 100644 --- a/AK/StringImpl.cpp +++ b/AK/StringImpl.cpp @@ -1,15 +1,14 @@ #include "StringImpl.h" -#include -#include -#include -#include +#include "StdLib.h" #include "kmalloc.h" namespace AK { StringImpl& StringImpl::theEmptyStringImpl() { - static StringImpl* s = new StringImpl(ConstructTheEmptyStringImpl); + static StringImpl* s = nullptr; + if (!s) + s = new StringImpl(ConstructTheEmptyStringImpl); return *s; } diff --git a/AK/Traits.h b/AK/Traits.h index 1dfe3c4c192..aa0d307e57f 100644 --- a/AK/Traits.h +++ b/AK/Traits.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "kstdio.h" namespace AK { @@ -12,19 +12,19 @@ struct Traits template<> struct Traits { static unsigned hash(int i) { return i; } - static void dump(int i) { printf("%d", i); } + static void dump(int i) { kprintf("%d", i); } }; template<> struct Traits { static unsigned hash(unsigned u) { return u; } - static void dump(unsigned u) { printf("%u", u); } + static void dump(unsigned u) { kprintf("%u", u); } }; template struct Traits { static unsigned hash(const T* p) { return (unsigned)p; } - static void dump(const T* p) { printf("%p", p); } + static void dump(const T* p) { kprintf("%p", p); } }; } diff --git a/AK/Vector.h b/AK/Vector.h index 971e45f192e..959b5c9b023 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -3,7 +3,6 @@ #include "Assertions.h" #include "OwnPtr.h" #include "kmalloc.h" -#include namespace AK { diff --git a/AK/kmalloc.cpp b/AK/kmalloc.cpp index 5540bfa0911..448b2ca6db8 100644 --- a/AK/kmalloc.cpp +++ b/AK/kmalloc.cpp @@ -1,6 +1,6 @@ #include #include "SimpleMalloc.h" -#include +#include "kmalloc.h" #include #define USE_SYSTEM_MALLOC diff --git a/AK/kmalloc.h b/AK/kmalloc.h index 2c30774456b..d90e6150e0d 100644 --- a/AK/kmalloc.h +++ b/AK/kmalloc.h @@ -1,13 +1,20 @@ #pragma once +#ifdef SERENITY_KERNEL +#include +#else +#include + #include "Types.h" extern "C" { void* kcalloc(size_t nmemb, size_t size); -void* kmalloc(size_t size); +void* kmalloc(size_t size) __attribute__ ((malloc)); void kfree(void* ptr); void* krealloc(void* ptr, size_t size); } +#endif + diff --git a/AK/ktime.h b/AK/ktime.h new file mode 100644 index 00000000000..b5f5e639a88 --- /dev/null +++ b/AK/ktime.h @@ -0,0 +1,15 @@ +#pragma once + +#ifdef SERENITY_KERNEL +inline time_t time(time_t* tloc) +{ + if (tloc) + *tloc = 123; + return 123; +} +#else +#include +#define ktime time +#define klocaltime localtime +#endif + diff --git a/Kernel/.bochsrc b/Kernel/.bochsrc new file mode 100644 index 00000000000..16e4fb79d72 --- /dev/null +++ b/Kernel/.bochsrc @@ -0,0 +1,54 @@ +# configuration file generated by Bochs +plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true +config_interface: textconfig +display_library: x +memory: host=32, guest=32 +romimage: file="/usr/local/share/bochs/BIOS-bochs-latest", address=0x00000000, options=none +vgaromimage: file="/usr/local/share/bochs/VGABIOS-lgpl-latest" +boot: floppy +floppy_bootsig_check: disabled=0 +floppya: type=1_44, 1_44=".floppy-image", status=inserted, write_protected=0 +# no floppyb +ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +ata0-master: type=disk, path="_fs_contents", mode=flat, cylinders=0, heads=0, spt=0, model="Generic 1234", biosdetect=auto, translation=auto +ata0-slave: type=none +ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15 +ata1-master: type=none +ata1-slave: type=none +ata2: enabled=false +ata3: enabled=false +optromimage1: file=none +optromimage2: file=none +optromimage3: file=none +optromimage4: file=none +optramimage1: file=none +optramimage2: file=none +optramimage3: file=none +optramimage4: file=none +pci: enabled=1, chipset=i440fx +vga: extension=vbe, update_freq=5, realtime=1 +cpu: count=1, ips=4000000, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 +cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU " +cpuid: mmx=true, apic=xapic, simd=sse2, sse4a=false, misaligned_sse=false, sep=true +cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, smep=false +cpuid: smap=false, mwait=true +print_timestamps: enabled=0 +port_e9_hack: enabled=0 +private_colormap: enabled=0 +clock: sync=none, time0=local, rtc_sync=0 +# no cmosimage +log: - +logprefix: %t%e%d +debug: action=ignore +info: action=report +error: action=report +panic: action=ask +keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none +mouse: type=ps2, enabled=false, toggle=ctrl+mbutton +speaker: enabled=true, mode=system +parport1: enabled=true, file=none +parport2: enabled=false +com1: enabled=true, mode=null +com2: enabled=false +com3: enabled=false +com4: enabled=false diff --git a/Kernel/Boot/boot.asm b/Kernel/Boot/boot.asm index 10f7f49c956..7a7569583e6 100755 --- a/Kernel/Boot/boot.asm +++ b/Kernel/Boot/boot.asm @@ -4,42 +4,57 @@ [bits 16] boot: - push cs - pop ds - xor bx, bx - mov ah, 0x0e - mov si, message + cli + mov ax, 0x8000 + mov ss, ax + mov sp, 0xffff + + push cs + pop ds + xor bx, bx + mov ah, 0x0e + mov si, message lodsb .lewp: - int 0x10 + int 0x10 lodsb - cmp al, 0 - jne .lewp + cmp al, 0 + jne .lewp - mov bx, 0x1000 - mov es, bx - xor bx, bx ; Load kernel @ 0x10000 + mov bx, 0x1000 + mov es, bx + xor bx, bx ; Load kernel @ 0x10000 + + mov cx, word [cur_lba] +.sector_loop: + call convert_lba_to_chs mov ah, 0x02 ; cmd 0x02 - Read Disk Sectors - mov al, 72 ; 72 sectors (max allowed by bochs BIOS) - mov ch, 0 ; track 0 - mov cl, 10 ; sector 10 - mov dh, 0 ; head 0 + mov al, 1 ; 1 sector at a time mov dl, 0 ; drive 0 (fd0) int 0x13 jc fug - mov ah, 0x02 - mov al, 32 - add bx, 0x9000 - mov ch, 2 - mov cl, 10 - mov dh, 0 - mov dl, 0 - int 0x13 + mov ah, 0x0e + mov al, '.' + int 0x10 - jc fug + inc word [cur_lba] + mov cx, word [cur_lba] + cmp cx, 300 + jz .sector_loop_end + + mov bx, es + add bx, 0x20 + mov es, bx + xor bx, bx + + jmp .sector_loop + +.sector_loop_end: + + call durk lgdt [cs:test_gdt_ptr] @@ -49,6 +64,20 @@ boot: jmp 0x08:pmode +durk: + push cs + pop ds + xor bx, bx + mov ah, 0x0e + mov si, msg_sectors_loaded + lodsb +.lewp: + int 0x10 + lodsb + cmp al, 0 + jne .lewp + ret + pmode: [bits 32] mov ax, 0x10 @@ -60,6 +89,14 @@ pmode: mov ss, ax mov esp, 0x2000 + xor eax, eax + xor ebx, ebx + xor ecx, ecx + xor edx, edx + xor ebp, ebp + xor esi, esi + xor edi, edi + jmp 0x10000 hlt @@ -95,7 +132,56 @@ fug: cli hlt + +; Input: +; +; AX = LBA +; +; Output: +; +; CX and DH = C/H/S address formatted for Int13,2 + +; CL = sector (LBA % sectors_per_track) + 1 +; +; 1.44M floppy stats: +; (sectors_per_track: 18) +; (heads: 2) +; (sectors: 2880) + +convert_lba_to_chs: + mov ax, cx + + ; AX = LBA/spt, DX = LBA%spt + xor dx, dx + div word [sectors_per_track] + + ; CL = sector (LBA % sectors_per_track) + 1 + mov cl, dl + inc cl + + ; CH = track (LBA / sectors_per_track) / heads + mov ch, al + shr ch, 1 + + ; AX = (LBA/spt)/heads, DX = (LBA/spt)%heads + xor dx, dx + div word [heads] + + ; DH = sector (LBA / sectors_per_track) % heads + mov dh, dl + + ret +cur_lba: + dw 9 +sectors_per_track: + dw 18 +heads: + dw 2 + +msg_sectors_loaded: + db "sectors loaded", 0x0d, 0x0a, 0 + message: db "boot!", 0x0d, 0x0a, 0 diff --git a/Kernel/Ext2FileSystem.h b/Kernel/Ext2FileSystem.h deleted file mode 100644 index 9509531d484..00000000000 --- a/Kernel/Ext2FileSystem.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include "ext2fs.h" -#include "OwnPtr.h" -#include "DataBuffer.h" -#include "FileSystem.h" - -static const size_t bytesPerSector = 512; - -class Ext2VirtualNode; - -class Ext2FileSystem { -public: - Ext2FileSystem() { } - ~Ext2FileSystem(); - - void initialize(); - RefPtr loadFile(ext2_dir_entry*); - - ext2_inode* findInode(DWORD index); - ext2_inode* findPath(const String& path, DWORD& inodeIndex); - -private: - friend class Ext2VirtualNode; - - void readSuperBlock(); - void readBlockGroup(DWORD); - void readInodeTable(DWORD); - void dumpDirectory(ext2_inode&); - void dumpFile(ext2_inode&); - - template void forEachBlockIn(ext2_inode&, F func); - template void traverseDirectory(ext2_dir_entry&, DWORD blockCount, F); - template void traverseDirectory(ext2_inode&, F); - RefPtr readFile(ext2_inode&); - - RefPtr readBlocks(DWORD blockIndex, BYTE count); - void readDiskSector(DWORD sectorIndex, BYTE* buffer); - - size_t blockSize() const { return 1024 << m_superBlock->s_log_frag_size; } - size_t sectorsPerBlock() const { return blockSize() / bytesPerSector; } - DWORD blockGroupForInode(DWORD inode) const; - DWORD toInodeTableIndex(DWORD inode) const; - - ext2_super_block& superBlock() { ASSERT(m_superBlock); return *m_superBlock; } - - OwnPtr m_superBlock; - ext2_inode* m_root { nullptr }; // raw pointer into one of the m_inodeTables - - size_t m_blockGroupCount { 0 }; - ext2_group_descriptor* m_groupTable { nullptr }; - ext2_inode** m_inodeTables { nullptr }; -}; - -class Ext2VirtualNode final : public FileSystem::VirtualNode { -public: - static RefPtr create(DWORD index, String&& path, Ext2FileSystem&, DWORD inodeNumber); - - virtual ~Ext2VirtualNode(); - - virtual size_t size() const override { return m_inode.i_size; } - virtual uid_t uid() const override { return m_inode.i_uid; } - virtual gid_t gid() const override { return m_inode.i_gid; } - virtual size_t mode() const override { return m_inode.i_mode; } - - virtual size_t read(BYTE* outbuf, size_t start, size_t maxLength) override; - -private: - Ext2VirtualNode(DWORD index, String&& path, Ext2FileSystem&, ext2_inode&, DWORD inodeNumber); - - Ext2FileSystem& m_fileSystem; - ext2_inode& m_inode; - DWORD m_inodeNumber { 0 }; -}; diff --git a/Kernel/DoublyLinkedList.h b/Kernel/InlineLinkedList.h similarity index 71% rename from Kernel/DoublyLinkedList.h rename to Kernel/InlineLinkedList.h index 5184e34d298..2c83a710e19 100644 --- a/Kernel/DoublyLinkedList.h +++ b/Kernel/InlineLinkedList.h @@ -3,9 +3,9 @@ #include "Assertions.h" #include "types.h" -template class DoublyLinkedListNode { +template class InlineLinkedListNode { public: - DoublyLinkedListNode(); + InlineLinkedListNode(); void setPrev(T*); void setNext(T*); @@ -14,35 +14,35 @@ public: T* next() const; }; -template inline DoublyLinkedListNode::DoublyLinkedListNode() +template inline InlineLinkedListNode::InlineLinkedListNode() { setPrev(0); setNext(0); } -template inline void DoublyLinkedListNode::setPrev(T* prev) +template inline void InlineLinkedListNode::setPrev(T* prev) { static_cast(this)->m_prev = prev; } -template inline void DoublyLinkedListNode::setNext(T* next) +template inline void InlineLinkedListNode::setNext(T* next) { static_cast(this)->m_next = next; } -template inline T* DoublyLinkedListNode::prev() const +template inline T* InlineLinkedListNode::prev() const { return static_cast(this)->m_prev; } -template inline T* DoublyLinkedListNode::next() const +template inline T* InlineLinkedListNode::next() const { return static_cast(this)->m_next; } -template class DoublyLinkedList { +template class InlineLinkedList { public: - DoublyLinkedList() { } + InlineLinkedList() { } bool isEmpty() const { return !m_head; } size_t size() const; @@ -56,14 +56,14 @@ public: void prepend(T*); void append(T*); void remove(T*); - void append(DoublyLinkedList&); + void append(InlineLinkedList&); private: T* m_head { nullptr }; T* m_tail { nullptr }; }; -template inline size_t DoublyLinkedList::size() const +template inline size_t InlineLinkedList::size() const { size_t size = 0; for (T* node = m_head; node; node = node->next()) @@ -71,13 +71,13 @@ template inline size_t DoublyLinkedList::size() const return size; } -template inline void DoublyLinkedList::clear() +template inline void InlineLinkedList::clear() { m_head = 0; m_tail = 0; } -template inline void DoublyLinkedList::prepend(T* node) +template inline void InlineLinkedList::prepend(T* node) { if (!m_head) { ASSERT(!m_tail); @@ -95,7 +95,7 @@ template inline void DoublyLinkedList::prepend(T* node) m_head = node; } -template inline void DoublyLinkedList::append(T* node) +template inline void InlineLinkedList::append(T* node) { if (!m_tail) { ASSERT(!m_head); @@ -113,7 +113,7 @@ template inline void DoublyLinkedList::append(T* node) m_tail = node; } -template inline void DoublyLinkedList::remove(T* node) +template inline void InlineLinkedList::remove(T* node) { if (node->prev()) { ASSERT(node != m_head); @@ -132,7 +132,7 @@ template inline void DoublyLinkedList::remove(T* node) } } -template inline T* DoublyLinkedList::removeHead() +template inline T* InlineLinkedList::removeHead() { T* node = head(); if (node) @@ -140,7 +140,7 @@ template inline T* DoublyLinkedList::removeHead() return node; } -template inline void DoublyLinkedList::append(DoublyLinkedList& other) +template inline void InlineLinkedList::append(InlineLinkedList& other) { if (!other.head()) return; diff --git a/Kernel/Makefile b/Kernel/Makefile index 93a28f5515a..330b6582148 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -14,10 +14,8 @@ KERNEL_OBJS = \ PIC.o \ Syscall.o \ DataBuffer.o \ - String.o \ panel.o \ Disk.o \ - fs.o \ Userspace.o \ IDEDiskDevice.o @@ -27,9 +25,16 @@ VFS_OBJS = \ ../VirtualFileSystem/NullDevice.o \ ../VirtualFileSystem/FullDevice.o \ ../VirtualFileSystem/ZeroDevice.o \ - ../VirtualFileSystem/RandomDevice.o + ../VirtualFileSystem/RandomDevice.o \ + ../VirtualFileSystem/FileSystem.o \ + ../VirtualFileSystem/DiskBackedFileSystem.o \ + ../VirtualFileSystem/Ext2FileSystem.o -OBJS = $(KERNEL_OBJS) $(VFS_OBJS) +AK_OBJS = \ + ../AK/String.o \ + ../AK/StringImpl.o + +OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS) NASM = nasm KERNEL = kernel diff --git a/Kernel/OwnPtr.h b/Kernel/OwnPtr.h deleted file mode 100644 index 855bafcf01e..00000000000 --- a/Kernel/OwnPtr.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include "types.h" - -template -class OwnPtr { -public: - OwnPtr() { } - explicit OwnPtr(T* ptr) : m_ptr(ptr) { } - OwnPtr(OwnPtr&& other) : m_ptr(other.leakPtr()) { } - template OwnPtr(OwnPtr&& other) : m_ptr(static_cast(other.leakPtr())) { } - ~OwnPtr() { clear(); } - - OwnPtr& operator=(OwnPtr&& other) - { - if (this != &other) { - delete m_ptr; - m_ptr = other.leakPtr(); - } - return *this; - } - - template - OwnPtr& operator=(OwnPtr&& other) - { - if (this != static_cast(&other)) { - delete m_ptr; - m_ptr = other.leakPtr(); - } - return *this; - } - - OwnPtr& operator=(T* ptr) - { - if (m_ptr != ptr) - delete m_ptr; - m_ptr = ptr; - return *this; - } - - void clear() - { - delete m_ptr; - m_ptr = nullptr; - } - - bool operator!() const { return !m_ptr; } - - typedef T* OwnPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : nullptr; } - - T* leakPtr() - { - T* leakedPtr = m_ptr; - m_ptr = nullptr; - return leakedPtr; - } - - T* ptr() { return m_ptr; } - const T* ptr() const { return m_ptr; } - - T* operator->() { return m_ptr; } - const T* operator->() const { return m_ptr; } - - T& operator*() { return *m_ptr; } - const T& operator*() const { return *m_ptr; } - - operator bool() { return !!m_ptr; } - -private: - T* m_ptr = nullptr; -}; - -template inline OwnPtr -make(Args&&... args) -{ - return OwnPtr(new T(forward(args)...)); -} diff --git a/Kernel/StdLib.cpp b/Kernel/StdLib.cpp index 50759b4c2dd..1ecdc6c9af2 100644 --- a/Kernel/StdLib.cpp +++ b/Kernel/StdLib.cpp @@ -49,6 +49,15 @@ char* strdup(const char *str) return s; } +int memcmp(const void* v1, const void* v2, size_t n) +{ + size_t m; + const char* s1 = (const char*)v1; + const char* s2 = (const char*)v2; + for (m = 0; m < n && *s1 == *s2; ++s1, ++s2); + return m == n ? 0 : -1; +} + extern "C" void __cxa_pure_virtual() { ASSERT_NOT_REACHED(); diff --git a/Kernel/StdLib.h b/Kernel/StdLib.h index 177fdde0eb8..f507773e55c 100644 --- a/Kernel/StdLib.h +++ b/Kernel/StdLib.h @@ -2,9 +2,10 @@ #include "types.h" -void memcpy(void *, const void *, DWORD); -void strcpy(char *, const char *); -int strcmp(char const *, const char *); -DWORD strlen(const char *) PURE; -void *memset(void *, BYTE, DWORD); -char *strdup(const char *); +void memcpy(void*, const void*, DWORD); +void strcpy(char*, const char*); +int strcmp(char const*, const char*); +DWORD strlen(const char*); +void *memset(void*, BYTE, DWORD); +char *strdup(const char*); +int memcmp(const void*, const void*, size_t); diff --git a/Kernel/String.cpp b/Kernel/String.cpp deleted file mode 100644 index e8a199226fc..00000000000 --- a/Kernel/String.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "String.h" -#include - -String::String() -{ -} - -String::String(const char* characters) - : m_data(DataBuffer::copy((const BYTE*)characters, strlen(characters) + 1)) -{ -} - -String::String(const char* characters, size_t length) - : m_data(DataBuffer::createUninitialized(length + 1)) -{ - memcpy(m_data->data(), characters, length); - m_data->data()[length] = '\0'; -} - -String::String(String&& other) - : m_data(move(other.m_data)) -{ -} - -String::String(const String& other) - : m_data(other.m_data) -{ -} - -String& String::operator=(const String& other) -{ - if (this == &other) - return *this; - m_data = other.m_data; - return *this; -} - -String& String::operator=(const String&& other) -{ - if (this == &other) - return *this; - m_data = move(other.m_data); - return *this; -} - -String::~String() -{ -} - -bool String::operator==(const String& other) const -{ - if (length() != other.length()) - return false; - return strcmp(characters(), other.characters()) == 0; -} - -String String::substring(size_t start, size_t length) const -{ - ASSERT(start + length <= m_data->length()); - // FIXME: This needs some input bounds checking. - auto buffer = DataBuffer::createUninitialized(length + 1); - memcpy(buffer->data(), characters() + start, length); - buffer->data()[length] = '\0'; - String s; - s.m_data = move(buffer); - return s; -} - -Vector String::split(char separator) const -{ - Vector v; - size_t substart = 0; - for (size_t i = 0; i < length(); ++i) { - char ch = characters()[i]; - if (ch == separator) { - size_t sublen = i - substart; - if (sublen != 0) - v.append(substring(substart, sublen)); - substart = i + 1; - } - } - size_t taillen = length() - 1 - substart; - if (taillen != 0) - v.append(substring(substart, taillen)); - return v; -} diff --git a/Kernel/String.h b/Kernel/String.h deleted file mode 100644 index c55b6e89966..00000000000 --- a/Kernel/String.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "DataBuffer.h" -#include "Vector.h" - -class String { -public: - String(); - String(const char* characters); - String(const char* characters, size_t length); - String(String&&); - String(const String&); - String& operator=(const String&); - String& operator=(const String&&); - ~String(); - - bool isEmpty() const { return m_data ? m_data->isEmpty() : true; } - size_t length() const { return m_data ? m_data->length() : 0; } - - char operator[](size_t i) const { return (char)m_data->data()[i]; } - - const char* characters() const { return m_data ? (const char*)m_data->data() : nullptr; } - - bool operator==(const String&) const; - - Vector split(char separator) const; - String substring(size_t start, size_t length) const; - -private: - RefPtr m_data; -}; diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index b38b37335fb..32f06d57e26 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -11,7 +11,7 @@ Task* current; Task* s_kernelTask; static pid_t next_pid; -static DoublyLinkedList* s_tasks; +static InlineLinkedList* s_tasks; static bool contextSwitch(Task*); @@ -46,7 +46,7 @@ void Task::initialize() { current = nullptr; next_pid = 0; - s_tasks = new DoublyLinkedList; + s_tasks = new InlineLinkedList; s_kernelTask = new Task(0, "idle", IPC::Handle::Any, Task::Ring0); redoKernelTaskTSS(); loadTaskRegister(s_kernelTask->selector()); @@ -415,12 +415,14 @@ int Task::sys$open(const char* path, size_t pathLength) FileHandle* Task::openFile(String&& path) { +#if 0 auto vnode = FileSystem::createVirtualNode(move(path)); if (!vnode) { kprintf("createVirtualNode failed\n"); return nullptr; } -#if 1 +#endif +#if 0 FileHandle* fh = new FileHandle; kprintf("made new FileHandle\n"); fh->m_fd = m_fileHandles.size(); diff --git a/Kernel/Task.h b/Kernel/Task.h index 7078a94c25f..9929da4b7fd 100644 --- a/Kernel/Task.h +++ b/Kernel/Task.h @@ -2,18 +2,18 @@ #include "types.h" #include "IPC.h" -#include "DoublyLinkedList.h" -#include "String.h" +#include "InlineLinkedList.h" +#include #include "TSS.h" -#include "Vector.h" +#include #include "i386.h" //#define TASK_SANITY_CHECKS class FileHandle; -class Task : public DoublyLinkedListNode { - friend class DoublyLinkedListNode; +class Task : public InlineLinkedListNode { + friend class InlineLinkedListNode; public: #ifdef TASK_SANITY_CHECKS static void checkSanity(const char* msg = nullptr); diff --git a/Kernel/Vector.h b/Kernel/Vector.h deleted file mode 100644 index 7b5fbded389..00000000000 --- a/Kernel/Vector.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include "Assertions.h" -#include "kmalloc.h" - -#define SANITIZE_VECTOR - -template -class Vector { -public: - Vector() { } - ~Vector(); - - Vector(const Vector&&); - Vector& operator=(const Vector&&); - - bool isEmpty() const { return m_size == 0; } - size_t size() const { return m_size; } - size_t capacity() const { return m_capacity; } - - void append(T&&); - void clear(); - - const T& operator[](size_t i) const { return m_elements[i]; } - T& operator[](size_t i) { return m_elements[i]; } - -private: - Vector(const Vector&) = delete; - Vector& operator=(const Vector&) = delete; - - void ensureCapacity(size_t); - - T* m_elements { nullptr }; - size_t m_size { 0 }; - size_t m_capacity { 0 }; -}; - -template -Vector::~Vector() -{ - clear(); -#ifdef SANITIZE_VECTOR - m_elements = (T*)0xdddddddd; - m_size = 0x8a8a8a8a; - m_capacity = 0xa8a8a8a8; -#endif -} - -template -void Vector::clear() -{ - if (!m_elements) - return; - for (size_t i = 0; i < m_size; ++i) { - m_elements[i].~T(); - } - kfree(m_elements); - m_elements = nullptr; - m_size = 0; - m_capacity = 0; -} - -template -void Vector::append(T&& element) -{ - ensureCapacity(m_size + 1); - new (&m_elements[m_size]) T(move(element)); - ++m_size; -} - -template -void Vector::ensureCapacity(size_t neededCapacity) -{ - if (neededCapacity <= m_capacity) - return; - size_t newCapacity = (neededCapacity + 8) & ~7; - // FIXME: We need to support further growth here, jeez... - ASSERT(m_capacity == 0); - ASSERT(!m_elements); - m_capacity = newCapacity; - T* newElements = (T*)kmalloc(m_capacity * sizeof(T)); -#ifdef SANITIZE_VECTOR - memset(newElements, 0x66, m_capacity * sizeof(T)); -#endif - if (m_elements) { - memcpy(newElements, m_elements, m_size * sizeof(T)); - kfree(m_elements); - } - m_elements = newElements; -} diff --git a/Kernel/fs.cpp b/Kernel/fs.cpp deleted file mode 100644 index 23cadacfec9..00000000000 --- a/Kernel/fs.cpp +++ /dev/null @@ -1,451 +0,0 @@ -#include "Disk.h" -#include "Task.h" -#include "VGA.h" -#include "kmalloc.h" -#include "Ext2FileSystem.h" -#include "i386.h" -#include "StdLib.h" -#include "OwnPtr.h" -#include "FileSystem.h" -#include "String.h" - -//#define FS_DEBUG - -Ext2FileSystem::~Ext2FileSystem() -{ - kprintf("fs: kill Ext2FileSystem\n"); - ASSERT(false); - kfree(m_groupTable); - m_groupTable = nullptr; - if (m_inodeTables) { - for (DWORD i = 0; i < m_blockGroupCount; ++i) - delete [] m_inodeTables[i]; - } - delete [] m_inodeTables; - m_inodeTables = nullptr; -} - -static Ext2FileSystem* fileSystem; - -void Ext2FileSystem::readDiskSector(DWORD sectorIndex, BYTE* buffer) -{ - Task::checkSanity("Ext2FileSystem::readDiskSector"); - bool success = Disk::readSectors(sectorIndex, 1, buffer); - (void) success; -} - -RefPtr Ext2FileSystem::readBlocks(DWORD blockIndex, BYTE count) -{ - Task::checkSanity("readBlocks"); - if (!m_superBlock) { - kprintf("fs: Attempt to read blocks without superblock!\n"); - HANG; - } - -#ifdef FS_DEBUG - kprintf("Read %u block(s) starting at %u\n", count, blockIndex); -#endif - // FIXME: This is broken up into 1-sector reads because the disk task can't handle multi-sector reads yet. - auto buffer = DataBuffer::createUninitialized(count * sectorsPerBlock() * bytesPerSector); - BYTE* bufptr = (BYTE*)buffer->data(); - for (DWORD i = 0; i < count; ++i) { - readDiskSector(((blockIndex + i) * sectorsPerBlock()) + 0, bufptr); - readDiskSector(((blockIndex + i) * sectorsPerBlock()) + 1, bufptr + bytesPerSector); - bufptr += bytesPerSector * 2; - } - return buffer; -} - -void Ext2FileSystem::readSuperBlock() -{ - ASSERT(!m_superBlock); - ASSERT(!m_groupTable); - - m_superBlock = make(); - readDiskSector(2, (BYTE*)m_superBlock.ptr()); - - if (m_superBlock->s_magic != EXT2_MAGIC) { - kprintf("fs: PANIC! No ext2 filesystem found\n"); - HANG; - } - - kprintf("fs: ext2 filesystem found -- %u inodes, %u blocks\n", - m_superBlock->s_inodes_count, - m_superBlock->s_blocks_count); - - const BYTE* u = m_superBlock->s_uuid; - kprintf("fs: UUID: %b%b%b%b-%b%b-%b%b-%b%b-%b%b%b%b%b%b\n", - u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], - u[9], u[10], u[11], u[12], u[13], u[14], u[15], u[16]); - -#ifdef FS_DEBUG - kprintf("fs: Block size is %u bytes\n", 1024 << m_superBlock->s_log_frag_size); - kprintf("fs: Blocks per group: %u\n", m_superBlock->s_blocks_per_group); -#endif - - m_blockGroupCount = m_superBlock->s_blocks_count / m_superBlock->s_blocks_per_group; - if ((m_superBlock->s_blocks_count % m_superBlock->s_blocks_per_group) != 0) - ++m_blockGroupCount; - - m_inodeTables = new ext2_inode*[m_blockGroupCount]; - memset(m_inodeTables, 0, sizeof(ext2_inode*) * m_blockGroupCount); -} - -void Ext2FileSystem::readBlockGroup(DWORD index) -{ - Task::checkSanity("readBlockGroup"); - DWORD superBlockBI = m_superBlock->s_first_data_block + (m_superBlock->s_blocks_per_group * index); - DWORD descriptorTableBI = superBlockBI + 1; - //DWORD blockBitmapBI = descriptorTableBI + 1; - //DWORD inodeBitmapBI = blockBitmapBI + 1; - //DWORD inodeTableBI = inodeBitmapBI + 1; - - auto buffer = readBlocks(descriptorTableBI, 1); - -#ifdef FS_DEBUG - kprintf("Inodes per group = %u\n", superBlock().s_inodes_per_group); - kprintf("First data block = %u\n", superBlock().s_first_data_block); -#endif - - m_groupTable = (ext2_group_descriptor*)kmalloc(blockSize()); - memcpy(m_groupTable, buffer->data(), buffer->length()); - -#ifdef FS_DEBUG - kprintf("[%u] block bitmap: %u\n", index, m_groupTable[index].bg_block_bitmap); - kprintf("[%u] inode bitmap: %u\n", index, m_groupTable[index].bg_inode_bitmap); - kprintf("[%u] inode table: %u\n", index, m_groupTable[index].bg_inode_table); -#endif -} - -template -void Ext2FileSystem::traverseDirectory(ext2_dir_entry& firstEntry, DWORD blockCount, F func) -{ - Task::checkSanity("traverseDirectory1"); - auto* entry = &firstEntry; - char* name = new char[EXT2_NAME_LEN + 1]; - auto* end = (ext2_dir_entry*)((BYTE*)entry + blockCount * blockSize()); - - while (entry < end) { - if (entry->d_inode != 0) { - memcpy(name, entry->d_name, entry->d_name_len); - name[entry->d_name_len] = 0; - func(name, *entry); - } - entry = (ext2_dir_entry*)((BYTE *)entry + entry->d_rec_len); - } - - delete [] name; -} - -void Ext2FileSystem::readInodeTable(DWORD blockGroup) -{ - Task::checkSanity("readInodeTable"); - ext2_inode*& inodeTable = m_inodeTables[blockGroup]; - - if (!inodeTable) - inodeTable = new ext2_inode[m_superBlock->s_inodes_per_group]; - - DWORD inodeTableBlocks = (m_superBlock->s_inodes_per_group * sizeof(ext2_inode)) / blockSize(); -// kprintf("inode table blocks: %u\n", inodeTableBlocks); - - auto buffer = readBlocks(m_groupTable[blockGroup].bg_inode_table, inodeTableBlocks); - memcpy(inodeTable, buffer->data(), m_superBlock->s_inodes_per_group * sizeof(ext2_inode)); - m_root = &inodeTable[1]; - -#ifdef FS_DEBUG - kprintf("Root directory inode:\n"); - kprintf("sizeof(ext2_inode): %u\n", sizeof(ext2_inode)); - kprintf("sizeof(ext2_dir_entry): %u\n", sizeof(ext2_dir_entry)); - kprintf("Mode: %u, Owner: %u/%u, Size: %u\n", m_root->i_mode, m_root->i_uid, m_root->i_gid, m_root->i_size); - - kprintf("Directory blocks: { "); - for (DWORD i = 0; i < 12; ++i) { - kprintf( "%u ", m_root->i_block[i] ); - } - kprintf("}\n"); -#endif -} - -template -void Ext2FileSystem::forEachBlockIn(ext2_inode& inode, F func) -{ - Task::checkSanity("forEachBlockIn"); - DWORD blockCount = inode.i_blocks / (2 << m_superBlock->s_log_block_size); - // FIXME: Support indirect blocks - for (DWORD i = 0; i < blockCount; ++i) { - //kprintf(" [blk %u]\n", inode.i_block[i]); - auto buffer = readBlocks(inode.i_block[i], 1); - func(move(buffer)); - } -} - -DWORD Ext2FileSystem::blockGroupForInode(DWORD inode) const -{ - // FIXME: Implement - (void)inode; - return 0; -} - -DWORD Ext2FileSystem::toInodeTableIndex(DWORD inode) const -{ - // FIXME: Implement - return inode - 1; -} - -ext2_inode* Ext2FileSystem::findInode(DWORD index) -{ - if (index >= m_superBlock->s_inodes_count) - return nullptr; - return &m_inodeTables[blockGroupForInode(index)][toInodeTableIndex(index)]; -} - -ext2_inode* Ext2FileSystem::findPath(const String& path, DWORD& inodeIndex) -{ - Task::checkSanity("findPath entry"); - ASSERT(m_root); - Task::checkSanity("findPath entry2"); - - if (path.isEmpty()) - return nullptr; - if (path[0] != '/') - return nullptr; - - ext2_inode* dir = m_root; - - Task::checkSanity("findPath pre-vector"); - Vector pathParts = path.split('/'); - Task::checkSanity("findPath post-split"); - - for (size_t i = 0; i < pathParts.size(); ++i) { - //kprintf("[%u] %s\n", i, pathParts[i].characters()); - auto& part = pathParts[i]; - bool foundPart = false; - //kprintf("looking for part '%s' in inode{%p}\n", part.characters(), dir); - traverseDirectory(*dir, [&] (const char* name, ext2_dir_entry& entry) { - //kprintf(" ?= %s\n", name); - if (String(name) == part) { - foundPart = true; - //kprintf("found part ==> inode %u (type %b)\n", entry.d_inode, entry.d_file_type); - dir = findInode(entry.d_inode); - inodeIndex = entry.d_inode; - // FIXME: don't try to traverse files as if they're directories - // FIXME: need a way to skip the remaining traverseDirectory() callbacks - } - }); - if (!foundPart) - return nullptr; - } - - return dir; -} - -template -void Ext2FileSystem::traverseDirectory(ext2_inode& inode, F func) -{ - Task::checkSanity("traverseDirectory2"); - //kprintf("in traverseDir\n"); - forEachBlockIn(inode, [this, &func] (RefPtr&& data) { - auto* directory = (ext2_dir_entry*)data->data(); - traverseDirectory(*directory, 1, func); - }); - //kprintf("out traverseDir\n"); -} - -RefPtr Ext2FileSystem::readFile(ext2_inode& inode) -{ - auto buffer = DataBuffer::createUninitialized(inode.i_size + 1); - BYTE* bufptr = buffer->data(); - size_t dataRemaining = inode.i_size; - forEachBlockIn(inode, [this, &bufptr, &dataRemaining] (RefPtr&& data) { - memcpy(bufptr, data->data(), min(dataRemaining, data->length())); - dataRemaining -= blockSize(); - bufptr += blockSize(); - }); - // HACK: This is silly, but let's just null terminate here for comfort. - buffer->data()[buffer->length() - 1] = '\0'; - return buffer; -} - -void Ext2FileSystem::dumpFile(ext2_inode& inode) -{ - auto buffer = readFile(inode); - kprintf("%s", buffer->data()); -} - -void Ext2FileSystem::dumpDirectory(ext2_inode& inode) -{ - traverseDirectory(inode, [this] (const char* name, ext2_dir_entry& entry) { - bool isDirectory = entry.d_file_type == EXT2_FT_DIR; - ext2_inode& inode = m_inodeTables[blockGroupForInode(entry.d_inode)][toInodeTableIndex(entry.d_inode)]; - kprintf("i:%x %b %u:%u %x %s%s\n", - entry.d_inode, - entry.d_file_type, - inode.i_uid, - inode.i_gid, - inode.i_size, - name, - isDirectory ? "/" : ""); - }); -} - -#if 0 -void Ext2FileSystem::readRoot() -{ - auto buffer = readBlocks(m_root->i_block[0], 1); - auto* dir_block = (ext2_dir_entry*)buffer.data(); - - traverseDirectory(dir_block, [this] (const char* name, ext2_dir_entry* entry) { - if (!strcmp(name, "test2")) { - auto test2_entry = loadFile(entry); - new Task((void (*)())test2_entry.data(), "test2", IPC::Handle::Any, Task::Ring3); - // HACK: Don't delete the code we just started running :) - test2_entry.leak(); - } else if (!strcmp( name, "motd.txt")) { - auto motd_txt = loadFile(entry); - kprintf("===============================================\n\n"); - vga_set_attr(0x03); - kprintf("%s\n", motd_txt.data()); - vga_set_attr(0x07); - kprintf("===============================================\n"); - } - }); -} -#endif - -void Ext2FileSystem::initialize() -{ - readSuperBlock(); - readBlockGroup(0); - readInodeTable(0); - -#ifdef FS_DEBUG - dumpDirectory(*m_root); -#endif - - DWORD inodeIndex; - auto* file = findPath("/motd.txt", inodeIndex); - dumpFile(*file); -} - -RefPtr Ext2FileSystem::loadFile(ext2_dir_entry* dirent) -{ - Task::checkSanity("loadFile"); - DWORD inode_group = (dirent->d_inode - 1) / superBlock().s_inodes_per_group; - -#ifdef FS_DEBUG - kprintf("inode: %u (group %u)\n", dirent->d_inode, inode_group); - kprintf("inode table at block %u\n", m_groupTable[inode_group].bg_inode_table); -#endif - - // Calculate interesting offset into inode block. - DWORD inode_index = (dirent->d_inode - 1) % superBlock().s_inodes_per_group; - - // Load the relevant inode block. - auto buffer = readBlocks(m_groupTable[inode_group].bg_inode_table, 4); - auto* inode_table = (ext2_inode*)buffer->data(); - -#ifdef FS_DEBUG - kprintf("inode index: %u\n", inode_index); -#endif - - ext2_inode* inode = &inode_table[inode_index]; - -#ifdef FS_DEBUG - kprintf("Mode: %u UID: %u GID: %u Size: %u Block0: %u\n", inode->i_mode, inode->i_uid, inode->i_gid, inode->i_size, inode->i_block[0]); -#endif - - auto fileContents = readBlocks(inode->i_block[0], 1); - -#ifdef FS_DEBUG - kprintf("File @ %p\n", fileContents->data()); - kprintf("File contents: %b %b %b %b %b\n", - (*fileContents)[0], - (*fileContents)[1], - (*fileContents)[2], - (*fileContents)[3], - (*fileContents)[4]); -#endif - - return fileContents; -} - -RefPtr Ext2VirtualNode::create(DWORD index, String&& path, Ext2FileSystem& fs, DWORD inodeNumber) -{ - Task::checkSanity("enter E2VN::create"); - ext2_inode* inode = fs.findInode(inodeNumber); - Task::checkSanity("post findInode"); - if (!inode) - return nullptr; - auto* v = new Ext2VirtualNode(index, move(path), fs, *inode, inodeNumber); - kprintf("v=%p\n", v); - auto r = adoptRef(v); - kprintf("adopted(v)=%p\n", r.ptr()); - return r; -} - -Ext2VirtualNode::Ext2VirtualNode(DWORD index, String&& path, Ext2FileSystem& fs, ext2_inode& inode, DWORD inodeNumber) - : VirtualNode(index, move(path)) - , m_fileSystem(fs) - , m_inode(inode) - , m_inodeNumber(inodeNumber) -{ - Task::checkSanity("Ext2VirtualNode::Ext2VirtualNode"); -} - -Ext2VirtualNode::~Ext2VirtualNode() -{ - Task::checkSanity("Ext2VirtualNode::~Ext2VirtualNode"); -} - -size_t Ext2VirtualNode::read(BYTE* outbuf, size_t start, size_t maxLength) -{ - Task::checkSanity("Ext2VirtualNode::read"); - kprintf("Ext2VirtualNode::read\n"); - if (start >= size()) - return 0; - - auto fileContents = m_fileSystem.readFile(m_inode); - if (!fileContents) - return 0; - ASSERT(start < fileContents->length()); - size_t nread = min(maxLength, fileContents->length() - start); - memcpy(outbuf, fileContents->data(), nread); - return nread; -} - -namespace FileSystem { - -static DWORD nextVNodeIndex; - -void initialize() -{ - nextVNodeIndex = 0; - fileSystem = new Ext2FileSystem; - fileSystem->initialize(); -} - -VirtualNode::VirtualNode(DWORD index, String&& path) - : m_index(index) - , m_path(move(path)) -{ -} - -VirtualNode::~VirtualNode() -{ -} - -RefPtr createVirtualNode(String&& path) -{ - Task::checkSanity("createVirtualNode"); - DWORD inodeIndex = 0x12345678; - Task::checkSanity("pre-findPath"); - kprintf("path: '%s'\n", path.characters()); - auto* inode = fileSystem->findPath(path, inodeIndex); - Task::checkSanity("post-findPath"); - if (!inode) - return nullptr; - kprintf("creating e2vn\n"); - return Ext2VirtualNode::create(nextVNodeIndex++, move(path), *fileSystem, inodeIndex); -} - -} diff --git a/Kernel/init.cpp b/Kernel/init.cpp index bd3aee7755d..ba0bdee0ffc 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -12,13 +12,13 @@ #include "StdLib.h" #include "Syscall.h" #include "CMOS.h" -#include "FileSystem.h" #include "Userspace.h" #include "IDEDiskDevice.h" #include #include #include #include +#include #include #if 0 @@ -127,7 +127,6 @@ void init() banner(); Disk::initialize(); - FileSystem::initialize(); auto dev_hd0 = IDEDiskDevice::create(); auto dev_null = make(); @@ -135,6 +134,9 @@ void init() auto dev_zero = make(); auto dev_random = make(); + auto e2fs = Ext2FileSystem::create(dev_hd0.copyRef()); + e2fs->initialize(); + // new Task(motd_main, "motd", IPC::Handle::MotdTask, Task::Ring0); new Task(user_main, "user", IPC::Handle::UserTask, Task::Ring3); diff --git a/Kernel/run b/Kernel/run index 067e05dfead..f3454dbf4e1 100755 --- a/Kernel/run +++ b/Kernel/run @@ -1,5 +1,5 @@ #!/bin/sh -#bochs -q -f .bochs.conf +bochs -q -f .bochsrc -qemu-system-i386 -drive format=raw,file=.floppy-image,if=floppy -drive format=raw,file=_fs_contents $@ +#qemu-system-i386 -drive format=raw,file=.floppy-image,if=floppy -drive format=raw,file=_fs_contents $@ diff --git a/VirtualFileSystem/DiskBackedFileSystem.cpp b/VirtualFileSystem/DiskBackedFileSystem.cpp index 532f74a707a..19f4166ba0e 100644 --- a/VirtualFileSystem/DiskBackedFileSystem.cpp +++ b/VirtualFileSystem/DiskBackedFileSystem.cpp @@ -3,7 +3,7 @@ //#define DBFS_DEBUG DiskBackedFileSystem::DiskBackedFileSystem(RetainPtr&& 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(index) * static_cast(blockSize()); + DiskOffset baseOffset = static_cast(index) * static_cast(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(index) * static_cast(blockSize()); + DiskOffset baseOffset = static_cast(index) * static_cast(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(index) * static_cast(blockSize()); + DiskOffset baseOffset = static_cast(index) * static_cast(blockSize()); auto* bufferPointer = buffer.pointer(); device().read(baseOffset, blockSize(), bufferPointer); ASSERT(buffer.size() == blockSize()); diff --git a/VirtualFileSystem/DiskDevice.cpp b/VirtualFileSystem/DiskDevice.cpp index e7f0cce2066..235ec8da763 100644 --- a/VirtualFileSystem/DiskDevice.cpp +++ b/VirtualFileSystem/DiskDevice.cpp @@ -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; diff --git a/VirtualFileSystem/DiskDevice.h b/VirtualFileSystem/DiskDevice.h index 4ecce51bb18..5a366956207 100644 --- a/VirtualFileSystem/DiskDevice.h +++ b/VirtualFileSystem/DiskDevice.h @@ -3,6 +3,13 @@ #include #include +#ifdef SERENITY_KERNEL +// FIXME: Support 64-bit DiskOffset +typedef dword DiskOffset; +#else +typedef qword DiskOffset; +#endif + class DiskDevice : public Retainable { 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(); diff --git a/VirtualFileSystem/Ext2FileSystem.cpp b/VirtualFileSystem/Ext2FileSystem.cpp index 1d0159e56af..c42e929bc01 100644 --- a/VirtualFileSystem/Ext2FileSystem.cpp +++ b/VirtualFileSystem/Ext2FileSystem.cpp @@ -3,20 +3,20 @@ #include "UnixTypes.h" #include #include -#include -#include #include +#include +#include #include "sys-errno.h" -//#define EXT2_DEBUG +#define EXT2_DEBUG RetainPtr Ext2FileSystem::create(RetainPtr&& device) { - return adopt(*new Ext2FileSystem(std::move(device))); + return adopt(*new Ext2FileSystem(move(device))); } Ext2FileSystem::Ext2FileSystem(RetainPtr&& 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(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 Ext2FileSystem::blockListForInode(const ext2_inode& e2inode) co if (!blocksRemaining) return list; - auto processBlockArray = [&] (unsigned arrayBlockIndex, std::function callback) { + auto processBlockArray = [&] (unsigned arrayBlockIndex, Function callback) { auto arrayBlock = readBlock(arrayBlockIndex); ASSERT(arrayBlock); auto* array = reinterpret_cast(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(count)); + Unix::ssize_t nread = min((Unix::off_t)e2inode->i_size - offset, static_cast(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 callback) const +bool Ext2FileSystem::enumerateDirectoryInode(InodeIdentifier inode, Function 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 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&& 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, Vectori_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::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::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::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(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(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 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(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]; } diff --git a/VirtualFileSystem/Ext2FileSystem.h b/VirtualFileSystem/Ext2FileSystem.h index 346ab91d766..f7b73465ef6 100644 --- a/VirtualFileSystem/Ext2FileSystem.h +++ b/VirtualFileSystem/Ext2FileSystem.h @@ -13,6 +13,7 @@ class Ext2FileSystem final : public DiskBackedFileSystem { public: static RetainPtr create(RetainPtr&&); 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) const override; + virtual bool enumerateDirectoryInode(InodeIdentifier, Function) 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; diff --git a/VirtualFileSystem/FileBackedDiskDevice.cpp b/VirtualFileSystem/FileBackedDiskDevice.cpp index 854b9329002..f47093c6fbd 100644 --- a/VirtualFileSystem/FileBackedDiskDevice.cpp +++ b/VirtualFileSystem/FileBackedDiskDevice.cpp @@ -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) diff --git a/VirtualFileSystem/FileBackedDiskDevice.h b/VirtualFileSystem/FileBackedDiskDevice.h index 10c4af69229..b6cb047a5b7 100644 --- a/VirtualFileSystem/FileBackedDiskDevice.h +++ b/VirtualFileSystem/FileBackedDiskDevice.h @@ -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 }; }; diff --git a/VirtualFileSystem/FileSystem.cpp b/VirtualFileSystem/FileSystem.cpp index 49b5af07b24..6b13854ece7 100644 --- a/VirtualFileSystem/FileSystem.cpp +++ b/VirtualFileSystem/FileSystem.cpp @@ -6,7 +6,9 @@ static dword s_lastFileSystemID = 0; static HashMap& fileSystems() { - static auto* map = new HashMap(); + static HashMap* map; + if (!map) + map = new HashMap(); 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; } diff --git a/VirtualFileSystem/FileSystem.h b/VirtualFileSystem/FileSystem.h index 74766675691..80c3021426c 100644 --- a/VirtualFileSystem/FileSystem.h +++ b/VirtualFileSystem/FileSystem.h @@ -11,7 +11,8 @@ #include #include #include -#include +#include +#include static const dword mepoch = 476763780; @@ -35,7 +36,7 @@ public: InodeIdentifier inode; byte fileType { 0 }; }; - virtual bool enumerateDirectoryInode(InodeIdentifier, std::function) const = 0; + virtual bool enumerateDirectoryInode(InodeIdentifier, Function) 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 { // FIXME: This is a shitty hash. static unsigned hash(const InodeIdentifier& inode) { return Traits::hash(inode.fileSystemID()) + Traits::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()); } }; } diff --git a/VirtualFileSystem/Limits.h b/VirtualFileSystem/Limits.h index 763e4c2c96c..b004b3ba9e6 100644 --- a/VirtualFileSystem/Limits.h +++ b/VirtualFileSystem/Limits.h @@ -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 inline static const Unix::off_t maxFileOffset = std::numeric_limits::max(); diff --git a/VirtualFileSystem/SyntheticFileSystem.cpp b/VirtualFileSystem/SyntheticFileSystem.cpp index 1940d2f724c..4da29bbf95a 100644 --- a/VirtualFileSystem/SyntheticFileSystem.cpp +++ b/VirtualFileSystem/SyntheticFileSystem.cpp @@ -62,7 +62,7 @@ InodeIdentifier SyntheticFileSystem::rootInode() const return { id(), 1 }; } -bool SyntheticFileSystem::enumerateDirectoryInode(InodeIdentifier inode, std::function callback) const +bool SyntheticFileSystem::enumerateDirectoryInode(InodeIdentifier inode, Function callback) const { ASSERT(inode.fileSystemID() == id()); #ifdef SYNTHFS_DEBUG diff --git a/VirtualFileSystem/SyntheticFileSystem.h b/VirtualFileSystem/SyntheticFileSystem.h index 2b698643f9e..97f48e883a4 100644 --- a/VirtualFileSystem/SyntheticFileSystem.h +++ b/VirtualFileSystem/SyntheticFileSystem.h @@ -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) const override; + virtual bool enumerateDirectoryInode(InodeIdentifier, Function) 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; diff --git a/VirtualFileSystem/UnixTypes.h b/VirtualFileSystem/UnixTypes.h index 738c07134a9..ca873e40a30 100644 --- a/VirtualFileSystem/UnixTypes.h +++ b/VirtualFileSystem/UnixTypes.h @@ -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; diff --git a/VirtualFileSystem/VirtualFileSystem.cpp b/VirtualFileSystem/VirtualFileSystem.cpp index 6495ce24061..b1884f7c4b4 100644 --- a/VirtualFileSystem/VirtualFileSystem.cpp +++ b/VirtualFileSystem/VirtualFileSystem.cpp @@ -2,8 +2,8 @@ #include "FileHandle.h" #include "FileSystem.h" #include -#include -#include +#include +#include //#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 @@ -39,7 +39,7 @@ auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr 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 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, 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(inode, std::move(fileSystem)); m_mounts.append(std::move(mount)); @@ -89,7 +89,7 @@ bool VirtualFileSystem::mount(RetainPtr&& fileSystem, const String& bool VirtualFileSystem::mountRoot(RetainPtr&& 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) 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) auto VirtualFileSystem::allocateNode() -> RetainPtr { 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 { }; } } diff --git a/VirtualFileSystem/test.cpp b/VirtualFileSystem/test.cpp index 24fb4370037..9ad43f34703 100644 --- a/VirtualFileSystem/test.cpp +++ b/VirtualFileSystem/test.cpp @@ -9,7 +9,9 @@ #include "RandomDevice.h" #include #include +#include #include +#include static RetainPtr makeFileSystem(const char* imagePath);