diff options
author | Himbeer <himbeer@disroot.org> | 2024-07-21 12:35:36 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-07-21 12:36:03 +0200 |
commit | c50c9b1d9380ff04bfdecf4aa9c5e08322658f79 (patch) | |
tree | aacd53cb05ca1469cb255140d039613aaa079785 | |
parent | 797fb6901a1fe386475216d79ef75f46d4361bd6 (diff) |
vfs: Get rid of File OpenFn callback
Context initialization is now left to the provider, allowing the kernel itself to interact with resources of this kind.
-rw-r--r-- | src/lib/resources.zig | 41 | ||||
-rw-r--r-- | src/lib/syscall.zig | 3 | ||||
-rw-r--r-- | src/lib/vfs.zig | 23 |
3 files changed, 38 insertions, 29 deletions
diff --git a/src/lib/resources.zig b/src/lib/resources.zig index 25835d5..93e9f04 100644 --- a/src/lib/resources.zig +++ b/src/lib/resources.zig @@ -278,7 +278,6 @@ fn addFile(path: []const u8, file: File) !void { .tag = .file, .data = .{ .file = .{ - .openFn = open, .readFn = read, .writeFn = null, .closeFn = close, @@ -303,30 +302,36 @@ fn addDir(path: []const u8) !void { }); } -fn open(initializer: ?*anyopaque, _: u16) callconv(.C) Result(*anyopaque) { - const file_template: *File = @alignCast(@ptrCast(initializer orelse { - return Result(*anyopaque).fromAnyTypeOrError(Error.NoTarFileInitializer); - })); - +fn open(context: *vfs.FileContext) !void { const allocator = vfs.treeRoot().allocator; - const context = allocator.create(File) catch |err| { - return Result(*anyopaque).fromAnyTypeOrError(err); - }; - context.* = file_template.*; - return Result(*anyopaque).fromAnyTypeOrError(context); + const inner = context.inner orelse return Error.NoTarFileInitializer; + const old_context: *File = @alignCast(@ptrCast(inner)); + + const new_context = try allocator.create(File); + new_context.* = old_context.*; + + context.inner = new_context; } -fn read(context: *anyopaque, ptr: [*]u8, len: usize) callconv(.C) Result(usize) { - const ctx: *File = @alignCast(@ptrCast(context)); +fn read(context: *vfs.FileContext, ptr: [*]u8, len: usize) callconv(.C) Result(usize) { + if (context.inner == null) { + open(context) catch |err| { + return Result(usize).fromAnyTypeOrError(err); + }; + } + + const inner: *File = @alignCast(@ptrCast(context.inner.?)); const buffer = ptr[0..len]; - return Result(usize).fromAnyTypeOrError(ctx.read(buffer)); + return Result(usize).fromAnyTypeOrError(inner.read(buffer)); } -fn close(context: *anyopaque) callconv(.C) void { - const ctx: *File = @alignCast(@ptrCast(context)); +fn close(context: *vfs.FileContext) callconv(.C) void { + if (context.inner) |inner_opaque| { + const allocator = vfs.treeRoot().allocator; - const allocator = vfs.treeRoot().allocator; - allocator.destroy(ctx); + const inner: *File = @alignCast(@ptrCast(inner_opaque)); + allocator.destroy(inner); + } } diff --git a/src/lib/syscall.zig b/src/lib/syscall.zig index c124373..37be59d 100644 --- a/src/lib/syscall.zig +++ b/src/lib/syscall.zig @@ -106,7 +106,6 @@ fn provideStream(proc: *const process.Info, trap_frame: *trap.Frame) void { // provideFile( // path_c: [*:0]const u8, // fixme: Kernel panic if null pointer // options: *const vfs.Options, // fixme: Kernel panic if null pointer -// openFn: vfs.File.OpenFn, // readFn: ?vfs.File.ReadFn, // writeFn: ?vfs.File.WriteFn, // closeFn: ?vfs.File.CloseFn, @@ -117,7 +116,6 @@ fn provideFile(proc: *const process.Info, trap_frame: *trap.Frame) void { const path_c: [*:0]const u8 = @ptrFromInt(trap_frame.general_purpose_registers[10]); const options: *const vfs.Options = @ptrFromInt(trap_frame.general_purpose_registers[11]); - const openFn: vfs.File.OpenFn = @ptrFromInt(trap_frame.general_purpose_registers[12]); const readFn: ?vfs.File.ReadFn = @ptrFromInt(trap_frame.general_purpose_registers[13]); const writeFn: ?vfs.File.WriteFn = @ptrFromInt(trap_frame.general_purpose_registers[14]); const closeFn: ?vfs.File.CloseFn = @ptrFromInt(trap_frame.general_purpose_registers[15]); @@ -125,7 +123,6 @@ fn provideFile(proc: *const process.Info, trap_frame: *trap.Frame) void { sysexchange.frameReturn(null, trap_frame, vfs.provideResourceZ(path_c, .{ .tag = .file, .data = .{ .file = .{ - .openFn = openFn, .readFn = readFn, .writeFn = writeFn, .closeFn = closeFn, diff --git a/src/lib/vfs.zig b/src/lib/vfs.zig index 7083c7c..951c666 100644 --- a/src/lib/vfs.zig +++ b/src/lib/vfs.zig @@ -61,16 +61,14 @@ pub const Stream = extern struct { // A file is a resource that creates a unique data stream with a driver. pub const File = extern struct { - openFn: OpenFn, readFn: ?ReadFn, writeFn: ?WriteFn, closeFn: ?CloseFn, initializer: ?*anyopaque, - pub const OpenFn = *allowzero const fn (initializer: ?*anyopaque, pid: u16) callconv(.C) sysexchange.Result(*anyopaque); - pub const ReadFn = *const fn (context: *anyopaque, ptr: [*]u8, len: usize) callconv(.C) sysexchange.Result(usize); - pub const WriteFn = *const fn (context: *anyopaque, ptr: [*]const u8, len: usize) callconv(.C) sysexchange.Result(usize); - pub const CloseFn = *const fn (context: *anyopaque) callconv(.C) void; + pub const ReadFn = *const fn (context: *FileContext, ptr: [*]u8, len: usize) callconv(.C) sysexchange.Result(usize); + pub const WriteFn = *const fn (context: *FileContext, ptr: [*]const u8, len: usize) callconv(.C) sysexchange.Result(usize); + pub const CloseFn = *const fn (context: *FileContext) callconv(.C) void; }; // A hook is a resource that invokes raw driver callbacks when interacted with. @@ -92,7 +90,7 @@ pub const DirHook = extern struct { }; pub const FileContext = extern struct { - inner: *allowzero anyopaque, + inner: ?*anyopaque, }; pub const ResourceKind = enum(u32) { @@ -185,10 +183,19 @@ pub const ResourceDescriptor = struct { pub fn init(allocator: Allocator, inode: *Inode) !ResourceDescriptor { inode.refs = std.math.add(usize, inode.refs, 1) catch return Error.TooManyReferences; - const context = if (inode.resource.tag == .file) try allocator.create(FileContext) else null; + if (inode.resource.tag == .file) { + const context = try allocator.create(FileContext); + context.inner = inode.resource.data.file.initializer; + + return .{ + .inode = inode, + .context = context, + }; + } + return .{ .inode = inode, - .context = context, + .context = null, }; } |