]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
partition: add partition_t structure and registry (Etapa 1)
authorTulio A M Mendes <[email protected]>
Tue, 26 May 2026 03:52:42 +0000 (00:52 -0300)
committerTulio A M Mendes <[email protected]>
Wed, 3 Jun 2026 04:02:35 +0000 (01:02 -0300)
- 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

include/partition.h [new file with mode: 0644]
src/kernel/partition.c [new file with mode: 0644]

diff --git a/include/partition.h b/include/partition.h
new file mode 100644 (file)
index 0000000..8990fba
--- /dev/null
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#ifndef PARTITION_H
+#define PARTITION_H
+
+#include "blockdev.h"
+#include <stddef.h>
+#include <stdint.h>
+
+/* 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 (file)
index 0000000..46b0eac
--- /dev/null
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * 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 <string.h>
+
+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);
+}