Skip to content

Commit

Permalink
Make dir and create file pre-implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
bagggage committed Dec 10, 2024
1 parent e605645 commit 9b70ca9
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 12 deletions.
65 changes: 58 additions & 7 deletions src/kernel/vfs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,30 @@ pub const Inode = struct {
}
};

pub const Path = struct {
dentry: *const Dentry,

pub fn format(self: Path, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
if (self.dentry.parent != root_dentry) {
try format(.{.dentry = self.dentry.parent}, "", .{}, writer);
}

try writer.print("/{s}", .{self.dentry.name.str()});
}
};

pub const Dentry = struct {
pub const List = utils.SList(Dentry);
pub const Node = List.Node;

pub const Operations = struct {
pub const Lookup = *const fn(*const Dentry, []const u8) ?*Dentry;
pub const LookupFn = *const fn(*const Dentry, []const u8) ?*Dentry;
pub const MakeDirectoryFn = *const fn(*const Dentry, *Dentry) Error!void;
pub const CreateFileFn = *const fn(*const Dentry, *Dentry) Error!void;

lookup: Lookup,
lookup: LookupFn,
makeDirectory: MakeDirectoryFn,
createFile: CreateFileFn,
};

pub const Name = struct {
Expand Down Expand Up @@ -322,11 +338,35 @@ pub const Dentry = struct {
return child;
}

pub fn makeDirectory(self: *Dentry, name: []const u8) Error!*Dentry {
const dir_dentry = try self.createLike(name);
errdefer { dir_dentry.name.deinit(); dir_dentry.delete(); }

try self.ops.makeDirectory(self, dir_dentry);
self.addChild(dir_dentry);

return dir_dentry;
}

pub fn createFile(self: *Dentry, name: []const u8) Error!*Dentry {
const file_dentry = try self.createLike(name);
errdefer { file_dentry.name.deinit(); file_dentry.delete(); }

try self.ops.createFile(self, file_dentry);
self.addChild(file_dentry);

return file_dentry;
}

pub fn addChild(self: *Dentry, child: *Dentry) void {
child.parent = self;
self.child.prepend(child.getNode());
}

pub inline fn path(self: *const Dentry) Path {
return Path{ .dentry = self };
}

inline fn cacheName(dentry: *const Dentry) void {
const hash = dentry.parent.calcHash(dentry.name.str());
insertLookupCache(hash, dentry);
Expand All @@ -337,6 +377,19 @@ pub const Dentry = struct {
return removeLookupCache(hash) == dentry;
}

fn createLike(self: *const Dentry, name: []const u8) !*Dentry {
const dentry = Dentry.new() orelse return error.NoMemory;
errdefer dentry.delete();

try dentry.name.init(name);
errdefer dentry.name.deinit();

dentry.super = self.super;
dentry.ops = self.ops;

return dentry;
}

fn calcHash(parent: *const Dentry, name: []const u8) u64 {
const ptr = @intFromPtr(parent.inode);

Expand Down Expand Up @@ -423,7 +476,7 @@ pub fn deinit() void {
}

pub inline fn mount(dentry: *Dentry, fs_name: []const u8, drive: ?*Drive, part_idx: u32) Error!void {
const result =mountEx(
const result = mountEx(
dentry,
fs_name.ptr, fs_name.len,
drive, part_idx
Expand Down Expand Up @@ -499,8 +552,6 @@ pub fn lookup(dir: ?*Dentry, path: []const u8) !*Dentry {
}
}

log.debug("call lookup", .{});

ent = ent.?.lookup(element);
}

Expand Down Expand Up @@ -577,10 +628,10 @@ fn mountImpl(dentry: *Dentry, fs_name: []const u8, drive: ?*Drive, part_idx: u32

if (drive) |d| {
log.info("{s} on {s}:part:{} is mounted to \"{s}\"", .{
fs.name, d.base_name, part_idx, dentry.name.str()
fs.name, d.base_name, part_idx, dentry.path()
});
} else {
log.info("{s} is mounted to \"{s}\"", .{fs.name, dentry.name.str()});
log.info("{s} is mounted to \"{s}\"", .{fs.name, dentry.path()});
}

mount_lock.lock();
Expand Down
4 changes: 4 additions & 0 deletions src/kernel/vfs/ext2.zig
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ var fs = vfs.FileSystem.init(
},
.{
.lookup = dentryLookup,
.makeDirectory = undefined,
.createFile = undefined
}
);

Expand Down Expand Up @@ -345,6 +347,8 @@ pub fn mount(drive: *vfs.Drive, part: *const vfs.Partition) vfs.Error!*vfs.Super

const dentry = vfs.Dentry.new() orelse return error.NoMemory;
dentry.init("/", super, try inode.cache(root_inode), &fs.data.dentry_ops) catch unreachable;

super.root = dentry;
}

log.info("mounting on drive: {s}", .{drive.base_name});
Expand Down
14 changes: 12 additions & 2 deletions src/kernel/vfs/initrd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ var fs = vfs.FileSystem.init(
.unmount = undefined
},
.{
.lookup = dentryLookup
.lookup = dentryLookup,
.makeDirectory = undefined,
.createFile = undefined
}
);

Expand All @@ -36,7 +38,15 @@ var link_name: [max_name]u8 = .{ 0 } ** max_name;
pub fn init() !void {
if (!vfs.registerFs(&fs)) return error.RegisterFailed;

try vfs.mount(vfs.getRoot(), "initramfs", null, undefined);
const mount_dir = vfs.getRoot().makeDirectory("initrd") catch |err| {
log.err("failed to create mount point: {}", .{err});
return error.MountFailed;
};

vfs.mount(mount_dir, "initramfs", null, undefined) catch |err| {
log.err("while mount: {}", .{err});
return error.MountFailed;
};
}

pub fn deinit() void {
Expand Down
33 changes: 30 additions & 3 deletions src/kernel/vfs/tmpfs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ const max_name_len = 64;
const oma_capacity = 128;

const Entry = struct {
const Kind = enum {
directory,
file
};

const List = utils.SList(Entry);
const Node = List.Node;

Expand Down Expand Up @@ -60,7 +65,7 @@ const Entry = struct {
name_buf: [max_name_len]u8 = undefined,
name_len: u8 = 0,

data: union(enum) {
data: union(Kind) {
directory: Directory,
file: File,
},
Expand Down Expand Up @@ -104,7 +109,9 @@ var fs = vfs.FileSystem.init(
.unmount = undefined
},
.{
.lookup = dentryLookup
.lookup = dentryLookup,
.makeDirectory = dentryMakeDirectory,
.createFile = dentryCreateFile,
}
);

Expand Down Expand Up @@ -140,6 +147,26 @@ fn dentryLookup(parent: *const vfs.Dentry, name: []const u8) ?*vfs.Dentry {
return createDentry(parent.super, child) catch return null;
}

fn dentryMakeDirectory(parent: *const vfs.Dentry, child: *vfs.Dentry) vfs.Error!void {
return dentryCreateEntry(parent, child, .directory);
}

fn dentryCreateFile(parent: *const vfs.Dentry, child: *vfs.Dentry) vfs.Error!void {
return dentryCreateEntry(parent, child, .file);
}

fn dentryCreateEntry(parent: *const vfs.Dentry, child: *vfs.Dentry, comptime kind: Entry.Kind) vfs.Error!void {
const dir = parent.inode.fs_data.as(Entry).?;

const entry = try createEntry(child.name.str(), kind);
errdefer entry.delete();

const inode = try createInode(entry);

dir.data.directory.childs.prepend(entry.getNode());
child.inode = inode;
}

fn createDentry(super: *vfs.Superblock, entry: *const Entry) !*vfs.Dentry {
const dentry = vfs.Dentry.new() orelse return error.NoMemory;
errdefer dentry.delete();
Expand Down Expand Up @@ -168,7 +195,7 @@ fn createInode(entry: *const Entry) !*vfs.Inode {
return inode;
}

fn createEntry(name: []const u8, comptime kind: enum {directory,file}) !*Entry {
fn createEntry(name: []const u8, comptime kind: Entry.Kind) !*Entry {
const entry: *Entry = Entry.new() orelse return error.NoMemory;
errdefer entry.delete();

Expand Down

0 comments on commit 9b70ca9

Please sign in to comment.