summaryrefslogtreecommitdiff
path: root/gpt/gpt.ha
diff options
context:
space:
mode:
Diffstat (limited to 'gpt/gpt.ha')
-rw-r--r--gpt/gpt.ha51
1 files changed, 46 insertions, 5 deletions
diff --git a/gpt/gpt.ha b/gpt/gpt.ha
index 53ca37f..f104584 100644
--- a/gpt/gpt.ha
+++ b/gpt/gpt.ha
@@ -11,7 +11,7 @@ export type nogpt = !void;
export type gpt = struct {
mbr_sec: sector::sector,
- mbr: *mbr::mbr,
+ mbr: *mbr::bootsector,
primary: block,
backup: block
};
@@ -104,7 +104,7 @@ export fn from(fd: io::file) (*gpt | nogpt | io::error) = {
// Allocate the GPT structure
let self = alloc(gpt {
mbr_sec = mbr_sec,
- mbr = mbr_sec.buf: *[*]u8: *mbr::mbr,
+ mbr = mbr_sec.buf: *[*]u8: *mbr::bootsector,
primary = block {
header_sec = prim_header_sec,
entries_sec = prim_entries_sec,
@@ -129,7 +129,7 @@ export fn create(fd: io::file, freeno: size) *gpt = {
const bheader_begin = bentries_begin + 128*128/512;
const mbr_sec = sector::map(fd, 0, 1);
- const mbr = mbr_sec.buf: *[*]u8: *mbr::mbr;
+ const mbr = mbr_sec.buf: *[*]u8: *mbr::bootsector;
const prim_header_sec = sector::map(fd, 1, 1);
const prim_header = prim_header_sec.buf: *[*]u8: *header;
@@ -182,7 +182,7 @@ export fn create(fd: io::file, freeno: size) *gpt = {
};
// Finds an lba for a new partition that fits the desired length
-export fn findfree(self: *gpt, length: u64) u64 = {
+fn findfree(self: *gpt, length: u64) u64 = {
const header = self.primary.header;
const entries = self.primary.entries;
@@ -209,7 +209,7 @@ export fn findfree(self: *gpt, length: u64) u64 = {
// Finds a GPT entry that is currently not used
// The entry pointer returned is borrowed from the arguments
-export fn findfreeentry(self: *gpt) nullable *entry = {
+fn findfreeentry(self: *gpt) nullable *entry = {
const header = self.primary.header;
const entries = self.primary.entries;
@@ -221,6 +221,47 @@ export fn findfreeentry(self: *gpt) nullable *entry = {
return null;
};
+// Allocates a partition with a given length (in lba)
+export fn allocate(self: *gpt, length: u64) nullable *entry = {
+ const addr = findfree(self, length);
+ if (addr == 0)
+ return null;
+
+ const entry = match (findfreeentry(self)) {
+ case let e: *entry =>
+ yield e;
+ case => return null;
+ };
+
+ entry.lba_begin = addr;
+ entry.lba_end = addr + length - 1;
+
+ return entry;
+};
+
+// Returns a stream to the partition associated with the entry
+// in order to write in it
+export fn partstream_writer(self: *gpt, entry: *entry) (io::limitstream | io::error) = {
+ const fd = self.primary.header_sec.fd;
+ const part = entry.lba_begin * sector::sector_length;
+ const length = (entry.lba_end - entry.lba_begin + 1) * sector::sector_length;
+
+
+ io::seek(fd, part: io::off, io::whence::SET)?;
+ return io::limitwriter(fd, length);
+};
+
+// Returns a stream to the partition associated with the entry
+// in order to read from it
+export fn partstream_reader(self: *gpt, entry: *entry) (io::limitstream | io::error) = {
+ const fd = self.primary.header_sec.fd;
+ const part = entry.lba_begin * sector::sector_length;
+ const length = (entry.lba_end - entry.lba_begin + 1) * sector::sector_length;
+
+ io::seek(fd, part: io::off, io::whence::SET)?;
+ return io::limitreader(fd, length);
+};
+
// Frees the resources associated with the GPT structure.
export fn finish(self: *gpt) void = {
sector::finish(&self.mbr_sec);