From: Tulio A M Mendes Date: Tue, 26 May 2026 03:52:42 +0000 (-0300) Subject: partition: add partition_t structure and registry (Etapa 1) X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=64187b00b69ecaaea22343fcd85610d8a4f89db8;p=AdrOS.git partition: add partition_t structure and registry (Etapa 1) - Created include/partition.h with partition_t structure - Created src/kernel/partition.c with partition registry functions - Implemented partition_register, partition_find, partition_find_by_device - Implemented partition_claim, partition_release for refcounting - Added partition_init_lock for spinlock initialization - Tests: 124/124 PASS --- diff --git a/include/partition.h b/include/partition.h new file mode 100644 index 00000000..8990fba6 --- /dev/null +++ b/include/partition.h @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2018, Tulio A M Mendes + * All rights reserved. + * See LICENSE for details. + * + * Source: https://github.com/tadryanom/AdrOS + */ + +#ifndef PARTITION_H +#define PARTITION_H + +#include "blockdev.h" +#include +#include + +/* Maximum number of partitions in the system */ +#define PARTITION_MAX 32 + +/* Partition types (MBR) */ +#define PART_TYPE_EMPTY 0x00 +#define PART_TYPE_FAT12 0x01 +#define PART_TYPE_FAT16 0x04 +#define PART_TYPE_EXTENDED 0x05 +#define PART_TYPE_FAT16B 0x06 +#define PART_TYPE_NTFS 0x07 +#define PART_TYPE_FAT32 0x0B +#define PART_TYPE_FAT32_LBA 0x0C +#define PART_TYPE_EXTENDED_LBA 0x0F +#define PART_TYPE_LINUX 0x83 +#define PART_TYPE_LINUX_SWAP 0x82 + +typedef struct partition { + block_device_t* parent; /* Parent block device (hda, vda, etc.) */ + uint32_t start_lba; /* Starting LBA of partition */ + uint32_t sector_count; /* Number of sectors in partition */ + uint8_t partition_type; /* Partition type (MBR/GPT) */ + uint8_t partition_number; /* Partition number (1-4 for primary MBR) */ + char name[32]; /* e.g. "hda1", "vda2" */ + int refcount; /* Number of filesystems using this partition */ +} partition_t; + +/* Register a partition. Returns 0 on success, -ENOSPC if table full. */ +int partition_register(const partition_t* part); + +/* Look up a partition by name (e.g. "hda1"). Returns pointer or NULL. */ +partition_t* partition_find(const char* name); + +/* Look up a partition by parent device and partition number. */ +partition_t* partition_find_by_device(block_device_t* parent, uint8_t partition_number); + +/* Increment partition refcount (called when filesystem mounts). */ +void partition_claim(partition_t* part); + +/* Decrement partition refcount (called when filesystem unmounts). */ +void partition_release(partition_t* part); + +/* Initialize partition subsystem lock */ +void partition_init_lock(void); + +#endif /* PARTITION_H */ diff --git a/src/kernel/partition.c b/src/kernel/partition.c new file mode 100644 index 00000000..46b0eac3 --- /dev/null +++ b/src/kernel/partition.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2018, Tulio A M Mendes + * All rights reserved. + * See LICENSE for details. + * + * Source: https://github.com/tadryanom/AdrOS + */ + +#include "partition.h" +#include "blockdev.h" +#include "spinlock.h" +#include "console.h" +#include "errno.h" + +#include + +static partition_t g_partitions[PARTITION_MAX]; +static int g_partition_count = 0; +static spinlock_t g_partition_lock; + +void partition_init_lock(void) { + spinlock_init(&g_partition_lock); +} + +int partition_register(const partition_t* part) { + if (!part) return -EINVAL; + if (!part->parent) return -EINVAL; + + uintptr_t flags = spin_lock_irqsave(&g_partition_lock); + + if (g_partition_count >= PARTITION_MAX) { + spin_unlock_irqrestore(&g_partition_lock, flags); + return -ENOSPC; + } + + /* Check for duplicate name */ + for (int i = 0; i < g_partition_count; i++) { + if (strcmp(g_partitions[i].name, part->name) == 0) { + /* Update existing entry */ + g_partitions[i] = *part; + spin_unlock_irqrestore(&g_partition_lock, flags); + return 0; + } + } + + g_partitions[g_partition_count++] = *part; + spin_unlock_irqrestore(&g_partition_lock, flags); + return 0; +} + +partition_t* partition_find(const char* name) { + if (!name) return NULL; + + uintptr_t flags = spin_lock_irqsave(&g_partition_lock); + partition_t* result = NULL; + for (int i = 0; i < g_partition_count; i++) { + if (strcmp(g_partitions[i].name, name) == 0) { + result = &g_partitions[i]; + break; + } + } + spin_unlock_irqrestore(&g_partition_lock, flags); + return result; +} + +partition_t* partition_find_by_device(block_device_t* parent, uint8_t partition_number) { + if (!parent) return NULL; + + uintptr_t flags = spin_lock_irqsave(&g_partition_lock); + partition_t* result = NULL; + for (int i = 0; i < g_partition_count; i++) { + if (g_partitions[i].parent == parent && + g_partitions[i].partition_number == partition_number) { + result = &g_partitions[i]; + break; + } + } + spin_unlock_irqrestore(&g_partition_lock, flags); + return result; +} + +void partition_claim(partition_t* part) { + if (!part) return; + uintptr_t flags = spin_lock_irqsave(&g_partition_lock); + part->refcount++; + spin_unlock_irqrestore(&g_partition_lock, flags); +} + +void partition_release(partition_t* part) { + if (!part) return; + uintptr_t flags = spin_lock_irqsave(&g_partition_lock); + if (part->refcount > 0) + part->refcount--; + spin_unlock_irqrestore(&g_partition_lock, flags); +}