summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gpt/gpt.ha6
-rw-r--r--part/part.ha80
2 files changed, 79 insertions, 7 deletions
diff --git a/gpt/gpt.ha b/gpt/gpt.ha
index 9474830..00720f8 100644
--- a/gpt/gpt.ha
+++ b/gpt/gpt.ha
@@ -194,9 +194,9 @@ fn findfree(self: *gpt, length: u64) u64 = {
let i = 0z;
for (i < header.entries_len) {
defer i += 1;
- if (entries[i].part_type[0] == 0 && entries[i].part_type[1] == 0)
+ if (entries[i].lba_begin == 0 && entries[i].lba_end == 0)
continue;
- if (overlap((cur, length), (entries[i].lba_begin, entries[i].lba_end - entries[i].lba_begin))) {
+ if (overlap((cur, length), (entries[i].lba_begin, entries[i].lba_end - entries[i].lba_begin + 1))) {
cur = entries[i].lba_end + 1;
break;
};
@@ -216,7 +216,7 @@ fn findfreeentry(self: *gpt) nullable *entry = {
const entries = self.primary.entries;
for (let i = 0z; i < header.entries_len; i += 1) {
- if (entries[i].part_type[0] == 0 && entries[i].part_type[1] == 0)
+ if (entries[i].lba_begin == 0 && entries[i].lba_end == 0)
return &entries[i];
};
diff --git a/part/part.ha b/part/part.ha
index 46c6546..7584daf 100644
--- a/part/part.ha
+++ b/part/part.ha
@@ -1,4 +1,6 @@
use fmt;
+use io;
+use os;
use strconv;
use gpt;
@@ -7,7 +9,7 @@ use volume;
export fn part(vol: str, args: []str) void = {
if (len(args) <= 1) {
- list(vol, args[1..]);
+ partlist(vol, args[1..]);
return;
};
@@ -15,18 +17,37 @@ export fn part(vol: str, args: []str) void = {
case let i: uint =>
const vol = volume::opengpt(vol);
defer gpt::finish(vol);
- partinfo(vol, i);
+ partno(vol, i, args[2..]);
return;
case =>
yield;
};
switch (args[1]) {
- case "list" => list(vol, args[1..]);
+ case "new" => partnew(vol, args[1..]);
+ case "list" => partlist(vol, args[1..]);
+ };
+};
+
+export fn partnew(vol: str, args: []str) void = {
+ const vol = volume::opengpt(vol);
+ defer {
+ gpt::chksums(vol);
+ gpt::commit(vol)!;
+ gpt::finish(vol);
+ };
+
+ const sz = 71z;
+
+ const entry = match (gpt::allocate(vol, sz)) {
+ case let e: *gpt::entry =>
+ yield e;
+ case =>
+ fmt::fatalf("gpt.part: could not allocate entry of size {}", sz);
};
};
-export fn list(vol: str, args: []str) void = {
+export fn partlist(vol: str, args: []str) void = {
const vol = volume::opengpt(vol);
defer gpt::finish(vol);
const header = vol.primary.header;
@@ -53,3 +74,54 @@ fn partinfo(vol: *gpt::gpt, i: size) void = {
// XXX name
};
+
+fn partno(vol: *gpt::gpt, i: size, args: []str) void = {
+ const header = vol.primary.header;
+
+ if (i >= header.entries_len)
+ fmt::fatalf("gpt.part: invalid partition number");
+
+ if (len(args) == 0) {
+ partinfo(vol, i);
+ return;
+ };
+
+ switch (args[0]) {
+ case "fill" =>
+ partfill(vol, i);
+ case "dump" =>
+ partdump(vol, i);
+ };
+};
+
+fn partfill(vol: *gpt::gpt, i: size) void = {
+ const entry = &vol.primary.entries[i];
+
+ if (entry.lba_begin == 0 && entry.lba_end == 0)
+ fmt::fatalf("gpt.part: partition {} is not allocated", i);
+
+ const writer = match (gpt::partstream_writer(vol, entry)) {
+ case let l: io::limitstream =>
+ yield l;
+ case =>
+ fmt::fatalf("gpt.part: could not create a writing stream");
+ };
+
+ io::copy(&writer, os::stdin)!;
+};
+
+fn partdump(vol: *gpt::gpt, i: size) void = {
+ const entry = &vol.primary.entries[i];
+
+ if (entry.lba_begin == 0 && entry.lba_end == 0)
+ fmt::fatalf("gpt.part: partition {} is not allocated", i);
+
+ const reader = match (gpt::partstream_reader(vol, entry)) {
+ case let l: io::limitstream =>
+ yield l;
+ case =>
+ fmt::fatalf("gpt.part: could not create a reading stream");
+ };
+
+ io::copy(os::stdout, &reader)!;
+};