simplify file system device allocation

This commit is contained in:
nakst 2021-08-16 18:19:57 +01:00
parent 44f620c3e3
commit 23bc33d5b9
25 changed files with 295 additions and 285 deletions

View File

@ -1105,6 +1105,19 @@ enum EsClipboard {
ES_CLIPBOARD_PRIMARY
}
enum EsDeviceType {
ES_DEVICE_OTHER
ES_DEVICE_CONTROLLER
ES_DEVICE_FILE_SYSTEM
ES_DEVICE_GRAPHICS_TARGET
ES_DEVICE_BLOCK
ES_DEVICE_AUDIO
ES_DEVICE_HID
ES_DEVICE_NETWORK_CARD
ES_DEVICE_USB
ES_DEVICE_PCI_FUNCTION
}
function_pointer int EsUICallbackFunction(struct EsElement *element, struct EsMessage *message);
struct EsBuffer {

View File

@ -663,7 +663,7 @@ void ACPIInitialise2() {
if (AE_OK == AcpiEnableEvent(ACPI_EVENT_POWER_BUTTON, 0)
&& AE_OK == AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON, ACPIPowerButtonPressed, nullptr)) {
KDeviceCreate("ACPI power button", acpi.computer, sizeof(KDevice));
KDeviceCreate("ACPI power button", acpi.computer, sizeof(KDevice), ES_DEVICE_OTHER);
}
void *result;
@ -695,7 +695,7 @@ void KPS2SafeToInitialise() {
}
static void DeviceAttach(KDevice *parentDevice) {
acpi.computer = KDeviceCreate("ACPI computer", parentDevice, sizeof(KDevice));
acpi.computer = KDeviceCreate("ACPI computer", parentDevice, sizeof(KDevice), ES_DEVICE_OTHER);
#ifndef SERIAL_STARTUP
KThreadCreate("InitACPI", [] (uintptr_t) { ACPIInitialise2(); });

View File

@ -827,7 +827,7 @@ void AHCIController::Initialise() {
for (uintptr_t i = 0; i < MAX_PORTS; i++) {
if (!ports[i].connected) continue;
AHCIDrive *device = (AHCIDrive *) KDeviceCreate("AHCI drive", this, sizeof(AHCIDrive));
AHCIDrive *device = (AHCIDrive *) KDeviceCreate("AHCI drive", this, sizeof(AHCIDrive), ES_DEVICE_BLOCK);
if (!device) {
KernelLog(LOG_ERROR, "AHCI", "allocation failure", "Could not create device for port %d.\n", i);
@ -863,7 +863,7 @@ void AHCIController::Initialise() {
static void DeviceAttach(KDevice *_parent) {
KPCIDevice *parent = (KPCIDevice *) _parent;
AHCIController *device = (AHCIController *) KDeviceCreate("AHCI controller", parent, sizeof(AHCIController));
AHCIController *device = (AHCIController *) KDeviceCreate("AHCI controller", parent, sizeof(AHCIController), ES_DEVICE_CONTROLLER);
if (!device) return;
device->pci = parent;

View File

@ -29,7 +29,7 @@ void BGADebugClearScreen() {
void BGADeviceAttached(KDevice *_parent) {
KPCIDevice *parent = (KPCIDevice *) _parent;
BGADisplay *device = (BGADisplay *) KDeviceCreate("BGA", parent, sizeof(BGADisplay));
BGADisplay *device = (BGADisplay *) KDeviceCreate("BGA", parent, sizeof(BGADisplay), ES_DEVICE_GRAPHICS_TARGET);
if (!device) return;
parent->EnableFeatures(K_PCI_FEATURE_IO_PORT_ACCESS | K_PCI_FEATURE_MEMORY_SPACE_ACCESS | K_PCI_FEATURE_BAR_0);

View File

@ -17,9 +17,8 @@
#define ESFS_CHECK_FATAL(x, y) if (!(x)) { KernelLog(LOG_ERROR, "EsFS", "damaged file system", "Mount - " y "\n"); return false; }
#define ESFS_CHECK_READ_ONLY(x, y) if (!(x)) { KernelLog(LOG_ERROR, "EsFS", "mount read only", "Mount - " y " Mounting as read only.\n"); volume->readOnly = true; }
struct Volume : KDevice {
struct Volume : KFileSystem {
Superblock superblock;
KFileSystem *fileSystem;
struct FSNode *root;
bool readOnly;
KWriterLock blockBitmapLock;
@ -39,7 +38,7 @@ struct FSNode {
static bool AccessBlock(Volume *volume, uint64_t index, uint64_t count, void *buffer, uint64_t flags, int driveAccess) {
// TODO Return EsError.
Superblock *superblock = &volume->superblock;
bool result = volume->fileSystem->Access(index * superblock->blockSize, count * superblock->blockSize, driveAccess, buffer, flags, nullptr);
bool result = volume->Access(index * superblock->blockSize, count * superblock->blockSize, driveAccess, buffer, flags, nullptr);
ESFS_CHECK(result, "AccessBlock - Could not access blocks.");
return result;
}
@ -585,7 +584,7 @@ static bool AllocateExtent(Volume *volume, uint64_t nearby, uint64_t increaseBlo
*extentStart += (target - volume->groupDescriptorTable) * superblock->blocksPerGroup;
superblock->blocksUsed += *extentCount;
volume->fileSystem->spaceUsed += *extentCount * superblock->blockSize;
volume->spaceUsed += *extentCount * superblock->blockSize;
if (zero) {
// TODO This is really slow - introduce K_ACCESS_ZERO?
@ -659,7 +658,7 @@ static bool FreeExtent(Volume *volume, uint64_t extentStart, uint64_t extentCoun
target->checksum = 0;
target->checksum = CalculateCRC32(target, sizeof(GroupDescriptor));
superblock->blocksUsed -= extentCount;
volume->fileSystem->spaceUsed -= extentCount * superblock->blockSize;
volume->spaceUsed -= extentCount * superblock->blockSize;
return true;
}
@ -1829,12 +1828,12 @@ static bool Mount(Volume *volume, EsFileOffsetDifference *rootDirectoryChildren)
Superblock *superblock = &volume->superblock;
if (!volume->fileSystem->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE, K_ACCESS_READ, (uint8_t *) superblock, ES_FLAGS_DEFAULT)) {
if (!volume->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE, K_ACCESS_READ, (uint8_t *) superblock, ES_FLAGS_DEFAULT)) {
KernelLog(LOG_ERROR, "EsFS", "drive access failure", "Mount - Could not read superblock.\n");
return false;
}
if (volume->fileSystem->block->readOnly) {
if (volume->block->readOnly) {
volume->readOnly = true;
}
@ -1847,8 +1846,8 @@ static bool Mount(Volume *volume, EsFileOffsetDifference *rootDirectoryChildren)
ESFS_CHECK_FATAL(0 == EsMemoryCompare(volume->superblock.signature, ESFS_SIGNATURE_STRING, 16), "Invalid superblock signature.");
ESFS_CHECK_FATAL(volume->superblock.requiredReadVersion <= ESFS_DRIVER_VERSION, "Incompatible file system version.");
ESFS_CHECK_FATAL(superblock->blockSize >= 1024 && superblock->blockSize <= 16384 && (superblock->blockSize % volume->fileSystem->block->sectorSize) == 0, "Invalid block size.");
ESFS_CHECK_FATAL(superblock->blockCount * superblock->blockSize / volume->fileSystem->block->sectorSize <= volume->fileSystem->block->sectorCount, "More blocks than drive.");
ESFS_CHECK_FATAL(superblock->blockSize >= 1024 && superblock->blockSize <= 16384 && (superblock->blockSize % volume->block->sectorSize) == 0, "Invalid block size.");
ESFS_CHECK_FATAL(superblock->blockCount * superblock->blockSize / volume->block->sectorSize <= volume->block->sectorCount, "More blocks than drive.");
ESFS_CHECK_FATAL(superblock->blocksUsed <= superblock->blockCount, "More blocks used than exist.");
ESFS_CHECK_FATAL(superblock->blocksPerGroup <= 65536 && superblock->blocksPerGroup < superblock->blockCount && superblock->blocksPerGroup >= 1024, "Invalid block group size.");
ESFS_CHECK_FATAL((superblock->groupCount - 1) * superblock->blocksPerGroup <= superblock->blockCount, "Invalid number of block groups.");
@ -1870,7 +1869,7 @@ static bool Mount(Volume *volume, EsFileOffsetDifference *rootDirectoryChildren)
superblock->mounted = true;
superblock->checksum = 0;
superblock->checksum = CalculateCRC32(superblock, sizeof(Superblock));
ESFS_CHECK_READ_ONLY(volume->fileSystem->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE,
ESFS_CHECK_READ_ONLY(volume->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE,
K_ACCESS_WRITE, (uint8_t *) superblock, ES_FLAGS_DEFAULT), "Could not mark volume as mounted.");
}
@ -1936,7 +1935,7 @@ static bool Mount(Volume *volume, EsFileOffsetDifference *rootDirectoryChildren)
}
static void Unmount(KFileSystem *fileSystem) {
Volume *volume = (Volume *) fileSystem->driverData;
Volume *volume = (Volume *) fileSystem;
Superblock *superblock = &volume->superblock;
if (!volume->readOnly) {
@ -1946,7 +1945,7 @@ static void Unmount(KFileSystem *fileSystem) {
superblock->mounted = false;
superblock->checksum = 0;
superblock->checksum = CalculateCRC32(superblock, sizeof(Superblock));
volume->fileSystem->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE, K_ACCESS_WRITE,
volume->Access(ESFS_BOOT_SUPER_BLOCK_SIZE, ESFS_BOOT_SUPER_BLOCK_SIZE, K_ACCESS_WRITE,
(uint8_t *) superblock, ES_FLAGS_DEFAULT);
}
@ -1954,16 +1953,13 @@ static void Unmount(KFileSystem *fileSystem) {
}
static void Register(KDevice *_parent) {
KFileSystem *fileSystem = (KFileSystem *) _parent;
Volume *volume = (Volume *) KDeviceCreate("EssenceFS", fileSystem, sizeof(Volume));
Volume *volume = (Volume *) KDeviceCreate("EssenceFS", _parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
if (!volume) {
KernelLog(LOG_ERROR, "EsFS", "allocation failure", "Register - Could not allocate Volume structure.\n");
if (!volume || !FSFileSystemInitialise(volume)) {
KernelLog(LOG_ERROR, "EsFS", "allocation failure", "Register - Could not allocate file system.\n");
return;
}
volume->fileSystem = fileSystem;
EsFileOffsetDifference rootDirectoryChildren;
if (!Mount(volume, &rootDirectoryChildren)) {
@ -1972,36 +1968,35 @@ static void Register(KDevice *_parent) {
return;
}
fileSystem->spaceUsed = volume->superblock.blocksUsed * volume->superblock.blockSize;
fileSystem->spaceTotal = volume->superblock.blockCount * volume->superblock.blockSize;
volume->spaceUsed = volume->superblock.blocksUsed * volume->superblock.blockSize;
volume->spaceTotal = volume->superblock.blockCount * volume->superblock.blockSize;
fileSystem->read = Read;
fileSystem->scan = Scan;
fileSystem->load = Load;
fileSystem->enumerate = Enumerate;
fileSystem->unmount = Unmount;
fileSystem->close = Close;
volume->read = Read;
volume->scan = Scan;
volume->load = Load;
volume->enumerate = Enumerate;
volume->unmount = Unmount;
volume->close = Close;
if (!volume->readOnly) {
fileSystem->write = Write;
fileSystem->sync = Sync;
fileSystem->resize = Resize;
fileSystem->create = Create;
fileSystem->remove = Remove;
fileSystem->move = Move;
volume->write = Write;
volume->sync = Sync;
volume->resize = Resize;
volume->create = Create;
volume->remove = Remove;
volume->move = Move;
}
volume->superblock.volumeName[ESFS_MAXIMUM_VOLUME_NAME_LENGTH - 1] = 0;
fileSystem->nameBytes = EsCStringLength(volume->superblock.volumeName);
EsMemoryCopy(fileSystem->name, volume->superblock.volumeName, fileSystem->nameBytes);
volume->nameBytes = EsCStringLength(volume->superblock.volumeName);
EsMemoryCopy(volume->name, volume->superblock.volumeName, volume->nameBytes);
fileSystem->driverData = volume;
fileSystem->rootDirectory->driverNode = volume->root;
fileSystem->rootDirectoryInitialChildren = rootDirectoryChildren;
fileSystem->directoryEntryDataBytes = sizeof(DirectoryEntryReference);
fileSystem->nodeDataBytes = sizeof(FSNode);
volume->rootDirectory->driverNode = volume->root;
volume->rootDirectoryInitialChildren = rootDirectoryChildren;
volume->directoryEntryDataBytes = sizeof(DirectoryEntryReference);
volume->nodeDataBytes = sizeof(FSNode);
FSRegisterBootFileSystem(fileSystem, volume->superblock.osInstallation);
FSRegisterBootFileSystem(volume, volume->superblock.osInstallation);
}
KDriver driverEssenceFS = {

View File

@ -129,8 +129,7 @@ struct FSNode {
Inode inode;
};
struct Volume : KDevice {
KFileSystem *fileSystem;
struct Volume : KFileSystem {
SuperBlock superBlock;
BlockGroupDescriptor *blockGroupDescriptorTable;
size_t blockBytes;
@ -141,16 +140,16 @@ static bool Mount(Volume *volume) {
// Load the superblock.
uint8_t *sectorBuffer = (uint8_t *) EsHeapAllocate(volume->fileSystem->block->sectorSize, false, K_FIXED);
uint8_t *sectorBuffer = (uint8_t *) EsHeapAllocate(volume->block->sectorSize, false, K_FIXED);
if (!sectorBuffer) {
MOUNT_FAILURE("Could not allocate buffer.\n");
}
EsDefer(EsHeapFree(sectorBuffer, volume->fileSystem->block->sectorSize, K_FIXED));
EsDefer(EsHeapFree(sectorBuffer, volume->block->sectorSize, K_FIXED));
{
if (!volume->fileSystem->Access(1024, volume->fileSystem->block->sectorSize, K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
if (!volume->Access(1024, volume->block->sectorSize, K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
MOUNT_FAILURE("Could not read boot sector.\n");
}
@ -170,7 +169,7 @@ static bool Mount(Volume *volume) {
volume->blockBytes = 1024 << volume->superBlock.blockSizeExponent;
if (volume->blockBytes < volume->fileSystem->block->sectorSize) {
if (volume->blockBytes < volume->block->sectorSize) {
MOUNT_FAILURE("Block size smaller than drive sector size.\n");
}
}
@ -188,7 +187,7 @@ static bool Mount(Volume *volume) {
MOUNT_FAILURE("Could not allocate the block group descriptor table.\n");
}
if (!volume->fileSystem->Access(firstBlockContainingBlockGroupDescriptorTable * volume->blockBytes,
if (!volume->Access(firstBlockContainingBlockGroupDescriptorTable * volume->blockBytes,
blockGroupDescriptorTableLengthInBlocks * volume->blockBytes,
K_ACCESS_READ, volume->blockGroupDescriptorTable, ES_FLAGS_DEFAULT)) {
MOUNT_FAILURE("Could not read the block group descriptor table from the drive.\n");
@ -202,29 +201,29 @@ static bool Mount(Volume *volume) {
uint32_t blockGroup = (inode - 1) / volume->superBlock.inodesPerBlockGroup;
uint32_t indexInInodeTable = (inode - 1) % volume->superBlock.inodesPerBlockGroup;
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->fileSystem->block->sectorSize;
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->fileSystem->block->sectorSize;
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->block->sectorSize;
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->block->sectorSize;
BlockGroupDescriptor *blockGroupDescriptor = volume->blockGroupDescriptorTable + blockGroup;
if (!volume->fileSystem->Access(blockGroupDescriptor->inodeTable * volume->blockBytes
+ sectorInInodeTable * volume->fileSystem->block->sectorSize,
volume->fileSystem->block->sectorSize,
if (!volume->Access(blockGroupDescriptor->inodeTable * volume->blockBytes
+ sectorInInodeTable * volume->block->sectorSize,
volume->block->sectorSize,
K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
MOUNT_FAILURE("Could not read the inode table.\n");
}
volume->fileSystem->rootDirectory->driverNode = EsHeapAllocate(sizeof(FSNode), true, K_FIXED);
volume->rootDirectory->driverNode = EsHeapAllocate(sizeof(FSNode), true, K_FIXED);
if (!volume->fileSystem->rootDirectory->driverNode) {
if (!volume->rootDirectory->driverNode) {
MOUNT_FAILURE("Could not allocate root node.\n");
}
FSNode *root = (FSNode *) volume->fileSystem->rootDirectory->driverNode;
FSNode *root = (FSNode *) volume->rootDirectory->driverNode;
root->volume = volume;
EsMemoryCopy(&root->inode, sectorBuffer + offsetInSector, sizeof(Inode));
volume->fileSystem->rootDirectoryInitialChildren = root->inode.fileSizeLow / sizeof(DirectoryEntry); // TODO This is a terrible upper-bound!
volume->rootDirectoryInitialChildren = root->inode.fileSizeLow / sizeof(DirectoryEntry); // TODO This is a terrible upper-bound!
if ((root->inode.type & 0xF000) != INODE_TYPE_DIRECTORY) {
MOUNT_FAILURE("Root directory is not a directory.\n");
@ -235,7 +234,7 @@ static bool Mount(Volume *volume) {
}
static uint32_t GetDataBlock(Volume *volume, Inode *node, uint64_t blockIndex, uint8_t *blockBuffer) {
#define CHECK_BLOCK_INDEX() if (offset == 0 || offset / volume->fileSystem->block->sectorSize > volume->fileSystem->block->sectorCount) { \
#define CHECK_BLOCK_INDEX() if (offset == 0 || offset / volume->block->sectorSize > volume->block->sectorCount) { \
KernelLog(LOG_ERROR, "Ext2", "invalid block index", "GetDataBlock - Block out of bounds.\n"); return 0; }
#define GET_DATA_BLOCK_ACCESS_FAILURE() do { KernelLog(LOG_ERROR, "Ext2", "block access failure", "GetDataBlock - Could not read block.\n"); return 0; } while (0)
@ -254,7 +253,7 @@ static uint32_t GetDataBlock(Volume *volume, Inode *node, uint64_t blockIndex, u
if (blockIndex < blockPointersPerBlock) {
offset = node->indirectBlockPointers[0] * volume->blockBytes;
CHECK_BLOCK_INDEX();
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
offset = blockPointers[blockIndex];
CHECK_BLOCK_INDEX();
return offset;
@ -265,10 +264,10 @@ static uint32_t GetDataBlock(Volume *volume, Inode *node, uint64_t blockIndex, u
if (blockIndex < blockPointersPerBlock * blockPointersPerBlock) {
offset = node->indirectBlockPointers[1] * volume->blockBytes;
CHECK_BLOCK_INDEX();
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
offset = blockPointers[blockIndex / blockPointersPerBlock];
CHECK_BLOCK_INDEX();
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
offset = blockPointers[blockIndex % blockPointersPerBlock];
CHECK_BLOCK_INDEX();
return offset;
@ -279,13 +278,13 @@ static uint32_t GetDataBlock(Volume *volume, Inode *node, uint64_t blockIndex, u
if (blockIndex < blockPointersPerBlock * blockPointersPerBlock * blockPointersPerBlock) {
offset = node->indirectBlockPointers[2] * volume->blockBytes;
CHECK_BLOCK_INDEX();
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
offset = blockPointers[blockIndex / blockPointersPerBlock / blockPointersPerBlock];
CHECK_BLOCK_INDEX();
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
offset = blockPointers[(blockIndex / blockPointersPerBlock) % blockPointersPerBlock];
CHECK_BLOCK_INDEX();
if (!volume->fileSystem->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
if (!volume->Access(offset, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) GET_DATA_BLOCK_ACCESS_FAILURE();
offset = blockPointers[blockIndex % blockPointersPerBlock];
CHECK_BLOCK_INDEX();
return offset;
@ -318,7 +317,7 @@ static EsError Enumerate(KNode *node) {
return ES_ERROR_DRIVE_CONTROLLER_REPORTED;
}
if (!volume->fileSystem->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
if (!volume->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
ENUMERATE_FAILURE("Could not read block.\n");
}
@ -388,7 +387,7 @@ static EsError Scan(const char *name, size_t nameBytes, KNode *_directory) {
return ES_ERROR_UNKNOWN;
}
if (!volume->fileSystem->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
if (!volume->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
SCAN_FAILURE("Could not read block.\n");
}
@ -449,14 +448,14 @@ static EsError Load(KNode *_directory, KNode *node, KNodeMetadata *metadata, con
uint32_t blockGroup = (inode - 1) / volume->superBlock.inodesPerBlockGroup;
uint32_t indexInInodeTable = (inode - 1) % volume->superBlock.inodesPerBlockGroup;
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->fileSystem->block->sectorSize;
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->fileSystem->block->sectorSize;
uint32_t sectorInInodeTable = (indexInInodeTable * volume->superBlock.inodeStructureBytes) / volume->block->sectorSize;
uint32_t offsetInSector = (indexInInodeTable * volume->superBlock.inodeStructureBytes) % volume->block->sectorSize;
BlockGroupDescriptor *blockGroupDescriptor = volume->blockGroupDescriptorTable + blockGroup;
if (!volume->fileSystem->Access(blockGroupDescriptor->inodeTable * volume->blockBytes
+ sectorInInodeTable * volume->fileSystem->block->sectorSize,
volume->fileSystem->block->sectorSize,
if (!volume->Access(blockGroupDescriptor->inodeTable * volume->blockBytes
+ sectorInInodeTable * volume->block->sectorSize,
volume->block->sectorSize,
K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
return ES_ERROR_DRIVE_CONTROLLER_REPORTED;
}
@ -505,7 +504,7 @@ struct ReadDispatchGroup : KWorkGroup {
void QueueExtent() {
if (!extentCount) return;
volume->fileSystem->Access(extentIndex * volume->blockBytes,
volume->Access(extentIndex * volume->blockBytes,
volume->blockBytes * extentCount, K_ACCESS_READ, extentBuffer, ES_FLAGS_DEFAULT, this);
}
@ -568,7 +567,7 @@ static size_t Read(KNode *node, void *_buffer, EsFileOffset offset, EsFileOffset
dispatchGroup.QueueBlock(volume, block, outputBuffer + outputPosition);
outputPosition += volume->blockBytes;
} else {
if (!volume->fileSystem->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
if (!volume->Access((uint64_t) block * volume->blockBytes, volume->blockBytes, K_ACCESS_READ, blockBuffer, ES_FLAGS_DEFAULT)) {
READ_FAILURE("Could not read blocks from drive.\n");
}
@ -594,55 +593,53 @@ static void Close(KNode *node) {
}
static void DeviceAttach(KDevice *parent) {
Volume *volume = (Volume *) KDeviceCreate("ext2", parent, sizeof(Volume));
Volume *volume = (Volume *) KDeviceCreate("ext2", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
if (!volume) {
KernelLog(LOG_ERROR, "Ext2", "allocate error", "Could not allocate Volume structure.\n");
if (!volume || !FSFileSystemInitialise(volume)) {
KernelLog(LOG_ERROR, "Ext2", "allocate error", "Could not initialise volume.\n");
return;
}
volume->fileSystem = (KFileSystem *) parent;
if (volume->fileSystem->block->sectorSize & 0x1FF) {
if (volume->block->sectorSize & 0x1FF) {
KernelLog(LOG_ERROR, "Ext2", "incorrect sector size", "Expected sector size to be a multiple of 512, but drive's sectors are %D.\n",
volume->fileSystem->block->sectorSize);
volume->block->sectorSize);
KDeviceDestroy(volume);
return;
}
if (!Mount(volume)) {
KernelLog(LOG_ERROR, "Ext2", "mount failure", "Could not mount Ext2 volume.\n");
EsHeapFree(volume->fileSystem->rootDirectory->driverNode, 0, K_FIXED);
EsHeapFree(volume->rootDirectory->driverNode, 0, K_FIXED);
EsHeapFree(volume->blockGroupDescriptorTable, 0, K_FIXED);
KDeviceDestroy(volume);
return;
}
volume->fileSystem->read = Read;
volume->fileSystem->scan = Scan;
volume->fileSystem->load = Load;
volume->fileSystem->enumerate = Enumerate;
volume->fileSystem->close = Close;
volume->read = Read;
volume->scan = Scan;
volume->load = Load;
volume->enumerate = Enumerate;
volume->close = Close;
volume->fileSystem->spaceTotal = volume->superBlock.blockCount * volume->blockBytes;
volume->fileSystem->spaceUsed = (volume->superBlock.blockCount - volume->superBlock.unallocatedBlockCount) * volume->blockBytes;
volume->spaceTotal = volume->superBlock.blockCount * volume->blockBytes;
volume->spaceUsed = (volume->superBlock.blockCount - volume->superBlock.unallocatedBlockCount) * volume->blockBytes;
volume->fileSystem->nameBytes = sizeof(volume->superBlock.volumeName);
if (volume->fileSystem->nameBytes > sizeof(volume->fileSystem->name)) volume->fileSystem->nameBytes = sizeof(volume->fileSystem->name);
EsMemoryCopy(volume->fileSystem->name, volume->superBlock.volumeName, volume->fileSystem->nameBytes);
volume->nameBytes = sizeof(volume->superBlock.volumeName);
if (volume->nameBytes > sizeof(volume->name)) volume->nameBytes = sizeof(volume->name);
EsMemoryCopy(volume->name, volume->superBlock.volumeName, volume->nameBytes);
for (uintptr_t i = 0; i < volume->fileSystem->nameBytes; i++) {
if (!volume->fileSystem->name[i]) {
volume->fileSystem->nameBytes = i;
for (uintptr_t i = 0; i < volume->nameBytes; i++) {
if (!volume->name[i]) {
volume->nameBytes = i;
}
}
volume->fileSystem->directoryEntryDataBytes = sizeof(uint32_t);
volume->fileSystem->nodeDataBytes = sizeof(FSNode);
volume->directoryEntryDataBytes = sizeof(uint32_t);
volume->nodeDataBytes = sizeof(FSNode);
KernelLog(LOG_INFO, "Ext2", "register file system", "Registering file system with name '%s'.\n",
volume->fileSystem->nameBytes, volume->fileSystem->name);
FSRegisterFileSystem(volume->fileSystem);
volume->nameBytes, volume->name);
FSRegisterFileSystem(volume);
}
KDriver driverExt2 = {

View File

@ -64,9 +64,7 @@ struct DirectoryEntry {
uint32_t fileSizeBytes;
} __attribute__((packed));
struct Volume : KDevice {
KFileSystem *fileSystem;
struct Volume : KFileSystem {
union {
char _unused0[SECTOR_SIZE];
SuperBlock16 sb16;
@ -84,7 +82,7 @@ struct Volume : KDevice {
#define TYPE_FAT32 (32)
int type;
DirectoryEntry *rootDirectory;
DirectoryEntry *rootDirectoryEntries;
};
struct DirectoryEntryReference {
@ -154,7 +152,7 @@ static EsError Load(KNode *_directory, KNode *_node, KNodeMetadata *, const void
DirectoryEntry entry;
if (!directory->rootDirectory) {
if (!volume->fileSystem->Access((reference.cluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
if (!volume->Access((reference.cluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
superBlock->sectorsPerCluster * SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) clusterBuffer, ES_FLAGS_DEFAULT)) {
return ES_ERROR_UNKNOWN;
}
@ -199,7 +197,7 @@ static size_t Read(KNode *node, void *_buffer, EsFileOffset offset, EsFileOffset
uint32_t bytesFromThisCluster = superBlock->sectorsPerCluster * SECTOR_SIZE - offset;
if (bytesFromThisCluster > count) bytesFromThisCluster = count;
if (!volume->fileSystem->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
if (!volume->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
superBlock->sectorsPerCluster * SECTOR_SIZE, K_ACCESS_READ,
(uint8_t *) clusterBuffer, ES_FLAGS_DEFAULT)) {
READ_FAILURE("Could not read cluster.\n");
@ -244,7 +242,7 @@ static EsError Scan(const char *_name, size_t nameLength, KNode *node) {
while (currentCluster < volume->terminateCluster) {
if (!directory->rootDirectory) {
if (!volume->fileSystem->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
if (!volume->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
superBlock->sectorsPerCluster * SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) clusterBuffer, ES_FLAGS_DEFAULT)) {
SCAN_FAILURE("Could not read cluster.\n");
}
@ -311,7 +309,7 @@ static EsError Enumerate(KNode *node) {
while (currentCluster < volume->terminateCluster) {
if (!directory->rootDirectory) {
if (!volume->fileSystem->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
if (!volume->Access((currentCluster * superBlock->sectorsPerCluster + volume->sectorOffset) * SECTOR_SIZE,
superBlock->sectorsPerCluster * SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) clusterBuffer, ES_FLAGS_DEFAULT)) {
ENUMERATE_FAILURE("Could not read cluster.\n");
}
@ -373,7 +371,7 @@ static bool Mount(Volume *volume) {
{
SuperBlockCommon *superBlock = &volume->superBlock;
if (!volume->fileSystem->Access(0, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) superBlock, ES_FLAGS_DEFAULT)) MOUNT_FAILURE("Could not read superBlock.\n");
if (!volume->Access(0, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) superBlock, ES_FLAGS_DEFAULT)) MOUNT_FAILURE("Could not read superBlock.\n");
uint32_t sectorCount = superBlock->totalSectors ?: superBlock->largeSectorCount;
uint32_t clusterCount = sectorCount / superBlock->sectorsPerCluster;
@ -402,16 +400,16 @@ static bool Mount(Volume *volume) {
volume->fat = (uint8_t *) EsHeapAllocate(sectorsPerFAT * SECTOR_SIZE, true, K_FIXED);
if (!volume->fat) MOUNT_FAILURE("Could not allocate FAT.\n");
if (!volume->fileSystem->Access(superBlock->reservedSectors * SECTOR_SIZE,
if (!volume->Access(superBlock->reservedSectors * SECTOR_SIZE,
sectorsPerFAT * SECTOR_SIZE, K_ACCESS_READ, volume->fat, ES_FLAGS_DEFAULT)) MOUNT_FAILURE("Could not read FAT.\n");
volume->fileSystem->spaceUsed = CountUsedClusters(volume) * superBlock->sectorsPerCluster * superBlock->bytesPerSector;
volume->fileSystem->spaceTotal = volume->fileSystem->block->sectorSize * volume->fileSystem->block->sectorCount;
volume->spaceUsed = CountUsedClusters(volume) * superBlock->sectorsPerCluster * superBlock->bytesPerSector;
volume->spaceTotal = volume->block->sectorSize * volume->block->sectorCount;
volume->fileSystem->rootDirectory->driverNode = EsHeapAllocate(sizeof(FSNode), true, K_FIXED);
if (!volume->fileSystem->rootDirectory->driverNode) MOUNT_FAILURE("Could not allocate root node.\n");
volume->rootDirectory->driverNode = EsHeapAllocate(sizeof(FSNode), true, K_FIXED);
if (!volume->rootDirectory->driverNode) MOUNT_FAILURE("Could not allocate root node.\n");
FSNode *root = (FSNode *) volume->fileSystem->rootDirectory->driverNode;
FSNode *root = (FSNode *) volume->rootDirectory->driverNode;
root->volume = volume;
if (volume->type == TYPE_FAT32) {
@ -422,13 +420,13 @@ static bool Mount(Volume *volume) {
while (currentCluster < volume->terminateCluster) {
currentCluster = NextCluster(volume, currentCluster);
volume->fileSystem->rootDirectoryInitialChildren += SECTOR_SIZE * superBlock->sectorsPerCluster / sizeof(DirectoryEntry);
volume->rootDirectoryInitialChildren += SECTOR_SIZE * superBlock->sectorsPerCluster / sizeof(DirectoryEntry);
}
} else {
root->rootDirectory = (DirectoryEntry *) EsHeapAllocate(rootDirectorySectors * SECTOR_SIZE, true, K_FIXED);
volume->rootDirectory = root->rootDirectory;
volume->rootDirectoryEntries = root->rootDirectory;
if (!volume->fileSystem->Access(rootDirectoryOffset * SECTOR_SIZE, rootDirectorySectors * SECTOR_SIZE,
if (!volume->Access(rootDirectoryOffset * SECTOR_SIZE, rootDirectorySectors * SECTOR_SIZE,
K_ACCESS_READ, (uint8_t *) root->rootDirectory, ES_FLAGS_DEFAULT)) {
MOUNT_FAILURE("Could not read root directory.\n");
}
@ -436,7 +434,7 @@ static bool Mount(Volume *volume) {
for (uintptr_t i = 0; i < superBlock->rootDirectoryEntries; i++) {
if (root->rootDirectory[i].name[0] == 0xE5 || root->rootDirectory[i].attributes == 0x0F || (root->rootDirectory[i].attributes & 0x08)) continue;
else if (root->rootDirectory[i].name[0] == 0x00) break;
else volume->fileSystem->rootDirectoryInitialChildren++;
else volume->rootDirectoryInitialChildren++;
}
}
@ -456,57 +454,49 @@ static void Close(KNode *node) {
}
static void DeviceAttach(KDevice *parent) {
Volume *volume = (Volume *) KDeviceCreate("FAT", parent, sizeof(Volume));
Volume *volume = (Volume *) KDeviceCreate("FAT", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
if (!volume) {
KernelLog(LOG_ERROR, "FAT", "allocate error", "EntryFAT - Could not allocate Volume structure.\n");
if (!volume || !FSFileSystemInitialise(volume)) {
KernelLog(LOG_ERROR, "FAT", "allocate error", "DeviceAttach - Could not initialise volume.\n");
return;
}
volume->fileSystem = (KFileSystem *) parent;
if (!volume->fileSystem) {
KernelLog(LOG_ERROR, "FAT", "device error", "EntryFAT - Could not create file system device.\n");
KDeviceDestroy(volume);
return;
}
if (volume->fileSystem->block->sectorSize != SECTOR_SIZE) {
KernelLog(LOG_ERROR, "FAT", "mount failure", "EntryFAT - Unsupported sector size.\n");
if (volume->block->sectorSize != SECTOR_SIZE) {
KernelLog(LOG_ERROR, "FAT", "mount failure", "DeviceAttach - Unsupported sector size.\n");
KDeviceDestroy(volume);
return;
}
if (!Mount(volume)) {
KernelLog(LOG_ERROR, "FAT", "mount failure", "EntryFAT - Could not mount FAT volume.\n");
KernelLog(LOG_ERROR, "FAT", "mount failure", "DeviceAttach - Could not mount FAT volume.\n");
KDeviceDestroy(volume);
return;
}
volume->fileSystem->read = Read;
volume->fileSystem->load = Load;
volume->fileSystem->scan = Scan;
volume->fileSystem->enumerate = Enumerate;
volume->fileSystem->close = Close;
volume->read = Read;
volume->load = Load;
volume->scan = Scan;
volume->enumerate = Enumerate;
volume->close = Close;
if (volume->type == TYPE_FAT32) {
volume->fileSystem->nameBytes = sizeof(volume->sb32.label);
EsMemoryCopy(volume->fileSystem->name, volume->sb32.label, volume->fileSystem->nameBytes);
volume->nameBytes = sizeof(volume->sb32.label);
EsMemoryCopy(volume->name, volume->sb32.label, volume->nameBytes);
} else {
if (volume->rootDirectory[0].attributes & 8) {
volume->fileSystem->nameBytes = sizeof(volume->rootDirectory[0].name);
EsMemoryCopy(volume->fileSystem->name, volume->rootDirectory[0].name, volume->fileSystem->nameBytes);
if (volume->rootDirectoryEntries[0].attributes & 8) {
volume->nameBytes = sizeof(volume->rootDirectoryEntries[0].name);
EsMemoryCopy(volume->name, volume->rootDirectoryEntries[0].name, volume->nameBytes);
} else {
volume->fileSystem->nameBytes = sizeof(volume->sb16.label);
EsMemoryCopy(volume->fileSystem->name, volume->sb16.label, volume->fileSystem->nameBytes);
volume->nameBytes = sizeof(volume->sb16.label);
EsMemoryCopy(volume->name, volume->sb16.label, volume->nameBytes);
}
}
volume->fileSystem->rootDirectory->driverNode = volume->root;
volume->fileSystem->directoryEntryDataBytes = sizeof(DirectoryEntryReference);
volume->fileSystem->nodeDataBytes = sizeof(FSNode);
volume->rootDirectory->driverNode = volume->root;
volume->directoryEntryDataBytes = sizeof(DirectoryEntryReference);
volume->nodeDataBytes = sizeof(FSNode);
FSRegisterFileSystem(volume->fileSystem);
FSRegisterFileSystem(volume);
}
KDriver driverFAT = {

View File

@ -286,7 +286,7 @@ static void HDAControllerExploreFunctionGroup(HDAController *controller, uint32_
uint32_t widgetType = ES_EXTRACT_BITS(widgetCapabilities, 23, 20);
HDAWidget *widget = (HDAWidget *) KDeviceCreate("HD Audio widget", controller, sizeof(HDAWidget));
HDAWidget *widget = (HDAWidget *) KDeviceCreate("HD Audio widget", controller, sizeof(HDAWidget), ES_DEVICE_AUDIO);
widget->codec = codec;
widget->node = j;
widget->functionGroup = functionGroupNode;
@ -382,7 +382,7 @@ static void HDAControllerDestroy(KDevice *_controller) {
}
static void HDAControllerAttach(KDevice *_parent) {
HDAController *controller = (HDAController *) KDeviceCreate("HD Audio controller", _parent, sizeof(HDAController));
HDAController *controller = (HDAController *) KDeviceCreate("HD Audio controller", _parent, sizeof(HDAController), ES_DEVICE_CONTROLLER);
if (!controller) {
return;

View File

@ -469,7 +469,7 @@ void Controller::Initialise() {
static void DeviceAttach(KDevice *_parent) {
KPCIDevice *parent = (KPCIDevice *) _parent;
Controller *device = (Controller *) KDeviceCreate("I8254x", parent, sizeof(Controller));
Controller *device = (Controller *) KDeviceCreate("I8254x", parent, sizeof(Controller), ES_DEVICE_NETWORK_CARD);
if (!device) return;
device->shutdown = [] (KDevice *device) {

View File

@ -551,7 +551,7 @@ void ATAController::Initialise() {
for (uintptr_t i = 0; i < ATA_DRIVES; i++) {
if (sectorCount[i]) {
// Register the drive.
ATADrive *device = (ATADrive *) KDeviceCreate("IDE drive", this, sizeof(ATADrive));
ATADrive *device = (ATADrive *) KDeviceCreate("IDE drive", this, sizeof(ATADrive), ES_DEVICE_BLOCK);
if (!device) {
KernelLog(LOG_ERROR, "IDE", "allocation failure", "Could not create device for drive %d.\n", i);
@ -585,7 +585,7 @@ static void DeviceAttach(KDevice *_parent) {
return;
}
ATAController *device = (ATAController *) KDeviceCreate("IDE controller", parent, sizeof(ATAController));
ATAController *device = (ATAController *) KDeviceCreate("IDE controller", parent, sizeof(ATAController), ES_DEVICE_CONTROLLER);
if (!device) return;
ataController = device;
device->pci = parent;

View File

@ -100,8 +100,7 @@ struct FSNode {
DirectoryRecord record;
};
struct Volume : KDevice {
KFileSystem *fileSystem;
struct Volume : KFileSystem {
PrimaryDescriptor primaryDescriptor;
};
@ -113,7 +112,7 @@ static bool Mount(Volume *volume) {
uintptr_t descriptorIndex = 0;
while (true) {
if (!volume->fileSystem->Access(32768 + SECTOR_SIZE * descriptorIndex, SECTOR_SIZE, K_ACCESS_READ, &volume->primaryDescriptor, ES_FLAGS_DEFAULT)) {
if (!volume->Access(32768 + SECTOR_SIZE * descriptorIndex, SECTOR_SIZE, K_ACCESS_READ, &volume->primaryDescriptor, ES_FLAGS_DEFAULT)) {
MOUNT_FAILURE("Could not access descriptor list.\n");
}
@ -135,7 +134,7 @@ static bool Mount(Volume *volume) {
}
if (volume->primaryDescriptor.version != 1 || volume->primaryDescriptor.fileStructureVersion != 1) {
MOUNT_FAILURE("Unsupported fileSystem version.\n");
MOUNT_FAILURE("Unsupported file system version.\n");
}
if (volume->primaryDescriptor.logicalBlockSize.x != SECTOR_SIZE) {
@ -149,8 +148,8 @@ static bool Mount(Volume *volume) {
MOUNT_FAILURE("Could not allocate root node.\n");
}
volume->fileSystem->rootDirectory->driverNode = root;
volume->fileSystem->rootDirectoryInitialChildren = volume->primaryDescriptor.rootDirectory.extentSize.x / sizeof(DirectoryRecord);
volume->rootDirectory->driverNode = root;
volume->rootDirectoryInitialChildren = volume->primaryDescriptor.rootDirectory.extentSize.x / sizeof(DirectoryRecord);
root->volume = volume;
root->record = volume->primaryDescriptor.rootDirectory;
@ -170,11 +169,11 @@ static bool Mount(Volume *volume) {
}
DirectoryRecord record = {};
ScanInternal(EsLiteral("ESSENCE.DAT;1"), volume->fileSystem->rootDirectory, &record);
ScanInternal(EsLiteral("ESSENCE.DAT;1"), volume->rootDirectory, &record);
record.extentSize.x = (record.extentSize.x + SECTOR_SIZE - 1) / SECTOR_SIZE;
if (!record.length || record.extentStart.x >= volume->fileSystem->block->sectorCount
|| record.extentSize.x >= volume->fileSystem->block->sectorCount - record.extentStart.x) {
if (!record.length || record.extentStart.x >= volume->block->sectorCount
|| record.extentSize.x >= volume->block->sectorCount - record.extentStart.x) {
goto notBoot;
}
@ -189,7 +188,7 @@ static bool Mount(Volume *volume) {
EsDefer(EsHeapFree(firstSector, SECTOR_SIZE, K_FIXED));
if (!volume->fileSystem->Access(record.extentStart.x * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, firstSector, ES_FLAGS_DEFAULT)) {
if (!volume->Access(record.extentStart.x * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, firstSector, ES_FLAGS_DEFAULT)) {
goto notBoot;
}
@ -206,7 +205,7 @@ static bool Mount(Volume *volume) {
KernelLog(LOG_INFO, "ISO9660", "found boot disc", "Found boot disc. Image at %d/%d.\n",
record.extentStart.x, record.extentSize.x);
FSPartitionDeviceCreate(volume->fileSystem->block, record.extentStart.x, record.extentSize.x, ES_FLAGS_DEFAULT, "CD-ROM boot partition");
FSPartitionDeviceCreate(volume->block, record.extentStart.x, record.extentSize.x, ES_FLAGS_DEFAULT, "CD-ROM boot partition");
}
notBoot:;
@ -236,7 +235,7 @@ static size_t Read(KNode *node, void *_buffer, EsFileOffset offset, EsFileOffset
while (count) {
if (offset || count < SECTOR_SIZE) {
if (!volume->fileSystem->Access(lba * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
if (!volume->Access(lba * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, sectorBuffer, ES_FLAGS_DEFAULT)) {
READ_FAILURE("Could not read file sector.\n");
}
@ -247,7 +246,7 @@ static size_t Read(KNode *node, void *_buffer, EsFileOffset offset, EsFileOffset
} else {
uint64_t sectorsToRead = count / SECTOR_SIZE;
if (!volume->fileSystem->Access(lba * SECTOR_SIZE, sectorsToRead * SECTOR_SIZE, K_ACCESS_READ, outputBuffer, ES_FLAGS_DEFAULT)) {
if (!volume->Access(lba * SECTOR_SIZE, sectorsToRead * SECTOR_SIZE, K_ACCESS_READ, outputBuffer, ES_FLAGS_DEFAULT)) {
READ_FAILURE("Could not read file sectors.\n");
}
@ -278,7 +277,7 @@ static EsError Enumerate(KNode *node) {
uint32_t remainingBytes = directory->record.extentSize.x;
while (remainingBytes) {
bool accessResult = volume->fileSystem->Access(currentSector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT);
bool accessResult = volume->Access(currentSector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT);
if (!accessResult) {
ENUMERATE_FAILURE("Could not read sector.\n");
@ -380,7 +379,7 @@ static EsError ScanInternal(const char *name, size_t nameBytes, KNode *_director
uint32_t remainingBytes = directory->record.extentSize.x;
while (remainingBytes) {
bool accessResult = volume->fileSystem->Access(currentSector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT);
bool accessResult = volume->Access(currentSector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT);
if (!accessResult) {
SCAN_FAILURE("Could not read sector.\n");
@ -465,7 +464,7 @@ static EsError Load(KNode *_directory, KNode *_node, KNodeMetadata *, const void
EsDefer(EsHeapFree(sectorBuffer, SECTOR_SIZE, K_FIXED));
if (!volume->fileSystem->Access(reference.sector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT)) {
if (!volume->Access(reference.sector * SECTOR_SIZE, SECTOR_SIZE, K_ACCESS_READ, (uint8_t *) sectorBuffer, ES_FLAGS_DEFAULT)) {
return ES_ERROR_DRIVE_CONTROLLER_REPORTED;
}
@ -489,55 +488,53 @@ static void Close(KNode *node) {
}
static void DeviceAttach(KDevice *parent) {
Volume *volume = (Volume *) KDeviceCreate("ISO9660", parent, sizeof(Volume));
Volume *volume = (Volume *) KDeviceCreate("ISO9660", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
if (!volume) {
KernelLog(LOG_ERROR, "ISO9660", "allocate error", "EntryISO9660 - Could not allocate Volume structure.\n");
if (!volume || !FSFileSystemInitialise(volume)) {
KernelLog(LOG_ERROR, "ISO9660", "allocate error", "DeviceAttach - Could not initialise volume.\n");
return;
}
volume->fileSystem = (KFileSystem *) parent;
if (volume->fileSystem->block->sectorSize != SECTOR_SIZE) {
KernelLog(LOG_ERROR, "ISO9660", "incorrect sector size", "EntryISO9660 - Expected 2KB sectors, but drive's sectors are %D.\n",
volume->fileSystem->block->sectorSize);
if (volume->block->sectorSize != SECTOR_SIZE) {
KernelLog(LOG_ERROR, "ISO9660", "incorrect sector size", "DeviceAttach - Expected 2KB sectors, but drive's sectors are %D.\n",
volume->block->sectorSize);
KDeviceDestroy(volume);
return;
}
if (!Mount(volume)) {
KernelLog(LOG_ERROR, "ISO9660", "mount failure", "EntryISO9660 - Could not mount ISO9660 volume.\n");
KernelLog(LOG_ERROR, "ISO9660", "mount failure", "DeviceAttach - Could not mount ISO9660 volume.\n");
KDeviceDestroy(volume);
return;
}
volume->fileSystem->read = Read;
volume->fileSystem->scan = Scan;
volume->fileSystem->load = Load;
volume->fileSystem->enumerate = Enumerate;
volume->fileSystem->close = Close;
volume->read = Read;
volume->scan = Scan;
volume->load = Load;
volume->enumerate = Enumerate;
volume->close = Close;
volume->fileSystem->spaceUsed = volume->primaryDescriptor.volumeSize.x * volume->primaryDescriptor.logicalBlockSize.x;
volume->fileSystem->spaceTotal = volume->fileSystem->spaceUsed;
volume->spaceUsed = volume->primaryDescriptor.volumeSize.x * volume->primaryDescriptor.logicalBlockSize.x;
volume->spaceTotal = volume->spaceUsed;
volume->fileSystem->nameBytes = sizeof(volume->primaryDescriptor.volumeIdentifier);
if (volume->fileSystem->nameBytes > sizeof(volume->fileSystem->name)) volume->fileSystem->nameBytes = sizeof(volume->fileSystem->name);
EsMemoryCopy(volume->fileSystem->name, volume->primaryDescriptor.volumeIdentifier, volume->fileSystem->nameBytes);
volume->nameBytes = sizeof(volume->primaryDescriptor.volumeIdentifier);
if (volume->nameBytes > sizeof(volume->name)) volume->nameBytes = sizeof(volume->name);
EsMemoryCopy(volume->name, volume->primaryDescriptor.volumeIdentifier, volume->nameBytes);
for (intptr_t i = volume->fileSystem->nameBytes - 1; i >= 0; i--) {
if (volume->fileSystem->name[i] == ' ') {
volume->fileSystem->nameBytes--;
for (intptr_t i = volume->nameBytes - 1; i >= 0; i--) {
if (volume->name[i] == ' ') {
volume->nameBytes--;
} else {
break;
}
}
volume->fileSystem->directoryEntryDataBytes = sizeof(DirectoryRecordReference);
volume->fileSystem->nodeDataBytes = sizeof(FSNode);
volume->directoryEntryDataBytes = sizeof(DirectoryRecordReference);
volume->nodeDataBytes = sizeof(FSNode);
KernelLog(LOG_INFO, "ISO9660", "register file system", "EntryISO9660 - Registering file system with name '%s'.\n",
volume->fileSystem->nameBytes, volume->fileSystem->name);
FSRegisterFileSystem(volume->fileSystem);
KernelLog(LOG_INFO, "ISO9660", "register file system", "DeviceAttach - Registering file system with name '%s'.\n",
volume->nameBytes, volume->name);
FSRegisterFileSystem(volume);
}
KDriver driverISO9660 = {

View File

@ -1212,7 +1212,7 @@ static void Close(KNode *node) {
}
static void DeviceAttach(KDevice *parent) {
Volume *volume = (Volume *) KDeviceCreate("NTFS", parent, sizeof(Volume));
Volume *volume = (Volume *) KDeviceCreate("NTFS", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
if (!volume) {
KernelLog(LOG_ERROR, "NTFS", "allocate error", "EntryNTFS - Could not allocate Volume structure.\n");

View File

@ -792,7 +792,7 @@ void NVMeController::Initialise() {
KernelLog(LOG_INFO, "NVMe", "namespace identified", "Identifier namespace %d with sectors of size %D, and a capacity of %D.%z\n",
nsid, sectorBytes, capacity, readOnly ? " The namespace is read-only." : "");
NVMeDrive *device = (NVMeDrive *) KDeviceCreate("NVMe namespace", this, sizeof(NVMeDrive));
NVMeDrive *device = (NVMeDrive *) KDeviceCreate("NVMe namespace", this, sizeof(NVMeDrive), ES_DEVICE_BLOCK);
if (!device) {
KernelLog(LOG_ERROR, "NVMe", "allocation failure", "Could not create device for namespace %d.\n", nsid);
@ -849,7 +849,7 @@ void NVMeController::Shutdown() {
static void DeviceAttach(KDevice *_parent) {
KPCIDevice *parent = (KPCIDevice *) _parent;
NVMeController *device = (NVMeController *) KDeviceCreate("NVMe controller", parent, sizeof(NVMeController));
NVMeController *device = (NVMeController *) KDeviceCreate("NVMe controller", parent, sizeof(NVMeController), ES_DEVICE_CONTROLLER);
if (!device) return;
device->pci = parent;

View File

@ -433,7 +433,7 @@ void PCIController::EnumerateFunction(int bus, int device, int function, int *bu
uint32_t deviceClass = ReadConfig(bus, device, function, 0x08);
uint32_t interruptInformation = ReadConfig(bus, device, function, 0x3C);
KPCIDevice *pciDevice = (KPCIDevice *) KDeviceCreate("PCI function", this, sizeof(KPCIDevice));
KPCIDevice *pciDevice = (KPCIDevice *) KDeviceCreate("PCI function", this, sizeof(KPCIDevice), ES_DEVICE_PCI_FUNCTION);
if (!pciDevice) return;
pciDevice->classCode = (deviceClass >> 24) & 0xFF;
@ -537,7 +537,7 @@ static void DeviceAttach(KDevice *parent) {
return;
}
pci = (PCIController *) KDeviceCreate("PCI controller", parent, sizeof(PCIController));
pci = (PCIController *) KDeviceCreate("PCI controller", parent, sizeof(PCIController), ES_DEVICE_CONTROLLER);
if (pci) {
pci->Enumerate();

View File

@ -550,9 +550,9 @@ void PS2::Initialise(KDevice *parentDevice) {
registeredIRQs = true;
}
KDevice *controller = KDeviceCreate("PS/2 controller", parentDevice, sizeof(KDevice));
KDeviceCreate("PS/2 keyboard", controller, sizeof(KDevice));
if (channels == 2) KDeviceCreate("PS/2 mouse", controller, sizeof(KDevice));
KDevice *controller = KDeviceCreate("PS/2 controller", parentDevice, sizeof(KDevice), ES_DEVICE_CONTROLLER);
KDeviceCreate("PS/2 keyboard", controller, sizeof(KDevice), ES_DEVICE_HID);
if (channels == 2) KDeviceCreate("PS/2 mouse", controller, sizeof(KDevice), ES_DEVICE_HID);
KernelLog(LOG_INFO, "PS/2", "controller initialised", "Setup PS/2 controller%z.\n", channels == 2 ? ", with a mouse" : "");
}

View File

@ -103,7 +103,7 @@ void InitialiseVBE(KDevice *parent) {
}
}
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VBE", parent, sizeof(KGraphicsTarget));
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VBE", parent, sizeof(KGraphicsTarget), ES_DEVICE_GRAPHICS_TARGET);
linearBuffer = (uint8_t *) MMMapPhysical(MMGetKernelSpace(), vbeMode->bufferPhysical,
vbeMode->bytesPerScanlineLinear * vbeMode->heightPixels, MM_REGION_WRITE_COMBINING);
@ -267,7 +267,7 @@ void InitialiseVGA(KDevice *parent) {
ProcessorIn8(VGA_INSTAT_READ);
ProcessorOut8(VGA_AC_INDEX, 0x20);
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VGA", parent, sizeof(KGraphicsTarget));
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VGA", parent, sizeof(KGraphicsTarget), ES_DEVICE_GRAPHICS_TARGET);
target->screenWidth = VGA_SCREEN_WIDTH;
target->screenHeight = VGA_SCREEN_HEIGHT;
target->updateScreen = VGAUpdateScreen;

View File

@ -185,7 +185,7 @@ void Device::Initialise() {
// Register the drive.
Drive *drive = (Drive *) KDeviceCreate("USB bulk drive", this, sizeof(Drive));
Drive *drive = (Drive *) KDeviceCreate("USB bulk drive", this, sizeof(Drive), ES_DEVICE_BLOCK);
if (!drive) {
KernelLog(LOG_ERROR, "USBBulk", "allocation failure", "Could not create drive for LUN %d.\n", i);
@ -206,7 +206,7 @@ void Device::Initialise() {
}
static void DeviceAttach(KDevice *parent) {
Device *device = (Device *) KDeviceCreate("USB bulk", parent, sizeof(Device));
Device *device = (Device *) KDeviceCreate("USB bulk", parent, sizeof(Device), ES_DEVICE_OTHER);
if (!device) {
KernelLog(LOG_ERROR, "USBBulk", "allocation failure", "Could not allocate device structure.\n");

View File

@ -719,7 +719,7 @@ static void DeviceDestroy(KDevice *_device) {
}
static void DeviceAttach(KDevice *parent) {
HIDDevice *device = (HIDDevice *) KDeviceCreate("USB HID", parent, sizeof(HIDDevice));
HIDDevice *device = (HIDDevice *) KDeviceCreate("USB HID", parent, sizeof(HIDDevice), ES_DEVICE_HID);
if (!device) {
KernelLog(LOG_ERROR, "USBHID", "allocation failure", "Could not allocate HIDDevice structure.\n");

View File

@ -849,7 +849,7 @@ void XHCIController::OnPortEnable(uintptr_t port) {
// Register the device with USB subsystem.
XHCIDevice *device = (XHCIDevice *) KDeviceCreate("XHCI device", this, sizeof(XHCIDevice));
XHCIDevice *device = (XHCIDevice *) KDeviceCreate("XHCI device", this, sizeof(XHCIDevice), ES_DEVICE_USB);
ports[port].device = device;
device->port = port;
device->controlTransfer = ControlTransferWrapper;
@ -1255,7 +1255,7 @@ void XHCIController::Initialise() {
static void DeviceAttach(KDevice *_parent) {
KPCIDevice *parent = (KPCIDevice *) _parent;
XHCIController *device = (XHCIController *) KDeviceCreate("XHCI controller", parent, sizeof(XHCIController));
XHCIController *device = (XHCIController *) KDeviceCreate("XHCI controller", parent, sizeof(XHCIController), ES_DEVICE_CONTROLLER);
if (!device) return;
device->pci = parent;

View File

@ -54,26 +54,6 @@ struct CCSpaceCallbacks {
EsError (*writeFrom)(CCSpace *fileCache, const void *buffer, EsFileOffset offset, EsFileOffset count);
};
// Describes the physical and virtual memory covering a file.
struct CCSpace {
// A sorted list of the cached sections in the file.
// Maps offset -> physical address.
KMutex cachedSectionsMutex;
Array<CCCachedSection, K_CORE> cachedSections;
// A sorted list of the active sections.
// Maps offset -> virtual address.
KMutex activeSectionsMutex;
Array<CCActiveSectionReference, K_CORE> activeSections;
// Used by CCSpaceFlush.
KEvent writeComplete;
// Callbacks.
const CCSpaceCallbacks *callbacks;
};
void CCInitialise();
void CCDereferenceActiveSection(CCActiveSection *section, uintptr_t startingPage = 0);

View File

@ -17,7 +17,7 @@ Array<KInstalledDriver, K_FIXED> installedDrivers;
void *ResolveKernelSymbol(const char *name, size_t nameBytes);
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes) {
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes, EsDeviceType type) {
if (bytes < sizeof(KDevice)) {
KernelPanic("KDeviceCreate - Device structure size is too small (less than KDevice).\n");
}
@ -28,6 +28,7 @@ KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes) {
device->parent = parent;
device->cDebugName = cDebugName;
device->handles = 2; // One handle for the creator, and another closed when the device is removed (by the parent).
device->type = type;
if (parent) {
KMutexAcquire(&deviceTreeMutex);
@ -254,7 +255,7 @@ bool KDeviceAttachByName(KDevice *parentDevice, const char *cName) {
void DeviceRootAttach(KDevice *parentDevice) {
// Load all the root drivers and create their devices.
KDeviceAttachAll(KDeviceCreate("root", parentDevice, sizeof(KDevice)), "Root");
KDeviceAttachAll(KDeviceCreate("root", parentDevice, sizeof(KDevice), ES_DEVICE_OTHER), "Root");
// Check we have found the drive from which we booted.
// TODO Decide the timeout.

View File

@ -1014,7 +1014,7 @@ void FSUnmountFileSystem(uintptr_t argument) {
}
KernelLog(LOG_INFO, "FS", "unmount complete", "Unmounted file system %x.\n", fileSystem);
KDeviceCloseHandle(fileSystem->children[0]);
KDeviceCloseHandle(fileSystem);
__sync_fetch_and_sub(&fs.fileSystemsUnmounting, 1);
KEventSet(&fs.fileSystemUnmounted, false, true);
}
@ -1594,13 +1594,13 @@ bool FSBlockDeviceAccess(KBlockDeviceAccessRequest request) {
}
}
EsError FSReadIntoBlockCache(CCSpace *fileCache, void *buffer, EsFileOffset offset, EsFileOffset count) {
KFileSystem *fileSystem = (KFileSystem *) fileCache - 1;
EsError FSReadIntoBlockCache(CCSpace *cache, void *buffer, EsFileOffset offset, EsFileOffset count) {
KFileSystem *fileSystem = EsContainerOf(KFileSystem, cacheSpace, cache);
return fileSystem->Access(offset, count, K_ACCESS_READ, buffer, ES_FLAGS_DEFAULT, nullptr) ? ES_SUCCESS : ES_ERROR_DRIVE_CONTROLLER_REPORTED;
}
EsError FSWriteFromBlockCache(CCSpace *fileCache, const void *buffer, EsFileOffset offset, EsFileOffset count) {
KFileSystem *fileSystem = (KFileSystem *) fileCache - 1;
EsError FSWriteFromBlockCache(CCSpace *cache, const void *buffer, EsFileOffset offset, EsFileOffset count) {
KFileSystem *fileSystem = EsContainerOf(KFileSystem, cacheSpace, cache);
return fileSystem->Access(offset, count, K_ACCESS_WRITE, (void *) buffer, ES_FLAGS_DEFAULT, nullptr) ? ES_SUCCESS : ES_ERROR_DRIVE_CONTROLLER_REPORTED;
}
@ -1631,7 +1631,7 @@ bool KFileSystem::Access(EsFileOffset offset, size_t count, int operation, void
// We use the CC_ACCESS_PRECISE flag for file systems that have a block size less than the page size.
// Otherwise, we might end up trashing file blocks (which aren't kept in the block device cache).
EsError result = CCSpaceAccess((CCSpace *) (this + 1), buffer, offset, count,
EsError result = CCSpaceAccess(&cacheSpace, buffer, offset, count,
operation == K_ACCESS_READ ? CC_ACCESS_READ : (CC_ACCESS_WRITE | CC_ACCESS_WRITE_BACK | CC_ACCESS_PRECISE));
if (dispatchGroup) {
@ -1669,7 +1669,7 @@ void FSPartitionDeviceAccess(KBlockDeviceAccessRequest request) {
}
void FSPartitionDeviceCreate(KBlockDevice *parent, EsFileOffset offset, EsFileOffset sectorCount, unsigned flags, const char *cName) {
PartitionDevice *child = (PartitionDevice *) KDeviceCreate(cName, parent, sizeof(PartitionDevice));
PartitionDevice *child = (PartitionDevice *) KDeviceCreate(cName, parent, sizeof(PartitionDevice), ES_DEVICE_BLOCK);
if (!child) return;
child->parent = parent;
@ -1692,7 +1692,7 @@ void FSPartitionDeviceCreate(KBlockDevice *parent, EsFileOffset offset, EsFileOf
//////////////////////////////////////////
bool FSSignatureCheck(KInstalledDriver *driver, KDevice *device) {
uint8_t *block = ((KFileSystem *) device)->block->information;
uint8_t *block = ((KBlockDevice *) device)->information;
EsINIState s = {};
s.buffer = driver->config;
@ -1762,6 +1762,28 @@ bool FSCheckMBR(KBlockDevice *device) {
return true;
}
bool FSFileSystemInitialise(KFileSystem *fileSystem) {
FSDirectoryEntry *rootEntry = (FSDirectoryEntry *) EsHeapAllocate(sizeof(FSDirectoryEntry), true, K_FIXED);
if (!rootEntry) goto error;
rootEntry->type = ES_NODE_DIRECTORY;
if (ES_SUCCESS != FSDirectoryEntryAllocateNode(rootEntry, nullptr, true, false)) goto error;
fileSystem->rootDirectory = rootEntry->node;
fileSystem->rootDirectory->fileSystem = fileSystem;
fileSystem->block = (KBlockDevice *) fileSystem->parent;
if (!CCSpaceInitialise(&fileSystem->cacheSpace)) goto error;
fileSystem->cacheSpace.callbacks = &fsBlockCacheCallbacks;
return true;
error:;
if (rootEntry && rootEntry->node) FSNodeFree(rootEntry->node);
if (rootEntry) EsHeapFree(rootEntry, sizeof(FSDirectoryEntry), K_FIXED);
KDeviceDestroy(fileSystem);
return false;
}
void FSDetectFileSystem(KBlockDevice *device) {
KernelLog(LOG_INFO, "FS", "detect file system", "Detecting file system on block device '%z'.\n", device->cModel);
@ -1793,35 +1815,7 @@ void FSDetectFileSystem(KBlockDevice *device) {
if (!device->noMBR && FSCheckMBR(device)) {
// Found an MBR.
} else {
FSDirectoryEntry *rootEntry = nullptr;
KFileSystem *fileSystem = nullptr;
CCSpace *cache = nullptr;
rootEntry = (FSDirectoryEntry *) EsHeapAllocate(sizeof(FSDirectoryEntry), true, K_FIXED);
if (!rootEntry) goto error;
rootEntry->type = ES_NODE_DIRECTORY;
if (ES_SUCCESS != FSDirectoryEntryAllocateNode(rootEntry, nullptr, true, false)) goto error;
fileSystem = (KFileSystem *) KDeviceCreate("file system", device, sizeof(KFileSystem) + sizeof(CCSpace));
if (!fileSystem) goto error;
fileSystem->rootDirectory = rootEntry->node;
fileSystem->rootDirectory->fileSystem = fileSystem;
fileSystem->block = device;
cache = (CCSpace *) (fileSystem + 1);
if (!CCSpaceInitialise(cache)) goto error;
cache->callbacks = &fsBlockCacheCallbacks;
KDeviceAttach(fileSystem, "Files", FSSignatureCheck);
KDeviceCloseHandle(fileSystem);
goto success;
error:;
if (fileSystem) KDeviceDestroy(fileSystem);
if (rootEntry && rootEntry->node) FSNodeFree(rootEntry->node);
if (rootEntry) EsHeapFree(rootEntry, sizeof(FSDirectoryEntry), K_FIXED);
success:;
KDeviceAttach(device, "Files", FSSignatureCheck);
}
}
@ -1862,10 +1856,6 @@ void FSFileSystemDeviceRemoved(KDevice *device) {
}
void FSRegisterFileSystem(KFileSystem *fileSystem) {
if (fileSystem->children.Length() != 1) {
KernelPanic("FSRegisterFileSystem - File system %x does not have a child device.\n", fileSystem);
}
static volatile uint64_t id = 1;
fileSystem->id = __sync_fetch_and_add(&id, 1);

View File

@ -548,7 +548,7 @@ struct KDevice {
#define K_DEVICE_REMOVED (1 << 0)
uint8_t flags;
uint16_t type;
uint32_t handles;
// These callbacks are called with the deviceTreeMutex locked.
@ -582,7 +582,7 @@ void KDeviceAttachAll(KDevice *parentDevice, const char *cParentDriver);
// Similar to KDeviceAttach, except it calls `attach` only for the driver matching the provided name. Returns true if the driver was found.
bool KDeviceAttachByName(KDevice *parentDevice, const char *cName);
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes /* must be at least the size of a KDevice */);
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes /* must be at least the size of a KDevice */, EsDeviceType type);
void KDeviceOpenHandle(KDevice *device);
void KDeviceDestroy(KDevice *device); // Call if initialisation of the device failed. Otherwise use KDeviceCloseHandle.
void KDeviceCloseHandle(KDevice *device); // The device creator is responsible for one handle after the creating it. The device is destroyed once all handles are closed.
@ -798,6 +798,24 @@ void KRegisterUSBDevice(KUSBDevice *device); // Takes ownership of the device's
// File systems.
// ---------------------------------------------------------------------------------------------------------------
struct CCSpace {
// A sorted list of the cached sections in the file.
// Maps offset -> physical address.
KMutex cachedSectionsMutex;
Array<struct CCCachedSection, K_CORE> cachedSections;
// A sorted list of the active sections.
// Maps offset -> virtual address.
KMutex activeSectionsMutex;
Array<struct CCActiveSectionReference, K_CORE> activeSections;
// Used by CCSpaceFlush.
KEvent writeComplete;
// Callbacks.
const struct CCSpaceCallbacks *callbacks;
};
struct KNodeMetadata {
// Metadata stored in the node's directory entry.
EsNodeType type;
@ -836,8 +854,6 @@ struct KFileSystem : KDevice {
// Fill these fields in before registering the file system:
void *driverData;
char name[64];
size_t nameBytes;
@ -870,6 +886,7 @@ struct KFileSystem : KDevice {
bool isBootFileSystem, unmounting;
volatile uint64_t totalHandleCount;
uint64_t id;
CCSpace cacheSpace;
MMObjectCache cachedDirectoryEntries, // Directory entries without a loaded node.
cachedNodes; // Nodes with no handles or directory entries.
@ -888,6 +905,8 @@ void FSNodeScanAndLoadComplete(KNode *node, bool success);
// but lets you pass an arbitrary KNode instead of a [directory, file name] pair.
void FSNodeUpdateDriverData(KNode *node, const void *newDriverData);
bool FSFileSystemInitialise(KFileSystem *fileSystem); // Do not attempt to load the file system if this returns false; the file system will be destroyed.
// All these functions take ownership of the device's main handle.
void FSRegisterBlockDevice(KBlockDevice *blockDevice);
void FSRegisterFileSystem(KFileSystem *fileSystem);

View File

@ -261,7 +261,7 @@ Option options[] = {
{ "Driver.EssenceFS", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.Ext2", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.FAT", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.HDAudio", OPTION_TYPE_BOOL, { .b = false } },
{ "Driver.HDAudio", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.I8254x", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.IDE", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.ISO9660", OPTION_TYPE_BOOL, { .b = true } },

View File

@ -165,6 +165,7 @@ typedef enum UIMessage {
UI_MSG_WINDOW_CLOSE, // return 1 to prevent default (process exit for UIWindow; close for UIMDIChild)
UI_MSG_TAB_SELECTED, // sent to the tab that was selected (not the tab pane itself)
UI_MSG_WINDOW_DROP_FILES, // di = count, dp = char ** of paths
UI_MSG_WINDOW_ACTIVATE,
UI_MSG_USER,
} UIMessage;
@ -4538,6 +4539,7 @@ bool _UIProcessEvent(XEvent *event) {
UIWindow *window = _UIFindWindow(event->xfocus.window);
if (!window) return false;
window->ctrl = window->shift = window->alt = false;
UIElementMessage(&window->e, UI_MSG_WINDOW_ACTIVATE, 0, 0);
} else if (event->type == ClientMessage && event->xclient.message_type == ui.dndEnterID) {
UIWindow *window = _UIFindWindow(event->xclient.window);
if (!window) return false;
@ -4607,11 +4609,19 @@ bool _UIProcessEvent(XEvent *event) {
while (!(i && data[i - 1] == '\r' && data[i] == '\n' && i < (int) count)) i++;
copy[i - 1] = 0;
for (int j = 0; s[j]; j++) {
if (s[j] == '%' && s[j + 1] && s[j + 2]) {
char n[3];
n[0] = s[j + 1], n[1] = s[j + 2], n[2] = 0;
s[j] = strtol(n, NULL, 16);
if (!s[j]) break;
memmove(s + j + 1, s + j + 3, strlen(s) - j - 2);
}
}
if (s[0] == 'f' && s[1] == 'i' && s[2] == 'l' && s[3] == 'e' && s[4] == ':' && s[5] == '/' && s[6] == '/') {
files[fileCount++] = s + 7;
}
// TODO Replace % codes in the URL.
}
UIElementMessage(&window->e, UI_MSG_WINDOW_DROP_FILES, fileCount, files);
@ -4847,9 +4857,27 @@ LRESULT CALLBACK _UIWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR
if (message == WM_SETFOCUS) {
_UIInspectorSetFocusedWindow(window);
UIElementMessage(&window->e, UI_MSG_WINDOW_ACTIVATE, 0, 0);
}
} else if (message == WM_MOUSEACTIVATE && (window->e.flags & UI_WINDOW_MENU)) {
return MA_NOACTIVATE;
} else if (message == WM_DROPFILES) {
HDROP drop = (HDROP) wParam;
int count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0);
char **files = (char **) UI_MALLOC(sizeof(char *) * count);
for (int i = 0; i < count; i++) {
int length = DragQueryFile(drop, i, NULL, 0);
files[i] = (char *) UI_MALLOC(length + 1);
files[i][length] = 0;
DragQueryFile(drop, i, files[i], length + 1);
}
UIElementMessage(&window->e, UI_MSG_WINDOW_DROP_FILES, count, files);
for (int i = 0; i < count; i++) UI_FREE(files[i]);
UI_FREE(files);
DragFinish(drop);
_UIUpdate();
} else if (message == WM_APP + 1) {
UIElementMessage(&window->e, (UIMessage) wParam, 0, (void *) lParam);
_UIUpdate();
@ -4945,7 +4973,7 @@ UIWindow *UIWindowCreate(UIWindow *owner, uint32_t flags, const char *cTitle, in
window->hwnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_NOACTIVATE, "shadow", 0, WS_POPUP,
0, 0, 0, 0, owner->hwnd, NULL, NULL, NULL);
} else {
window->hwnd = CreateWindow("normal", cTitle, WS_OVERLAPPEDWINDOW,
window->hwnd = CreateWindowEx(WS_EX_ACCEPTFILES, "normal", cTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, width ? width : CW_USEDEFAULT, height ? height : CW_USEDEFAULT,
owner ? owner->hwnd : NULL, NULL, NULL, NULL);
}