diff options
Diffstat (limited to 'gpt/gpt.ha')
| -rw-r--r-- | gpt/gpt.ha | 51 |
1 files changed, 46 insertions, 5 deletions
@@ -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); |
