Starting work on inode decoding
This commit is contained in:
@@ -4,7 +4,7 @@ pub const InodeRef = packed struct {
|
|||||||
offset: u16,
|
offset: u16,
|
||||||
};
|
};
|
||||||
|
|
||||||
const InodeType = enum(u16) {
|
pub const InodeType = enum(u16) {
|
||||||
dir = 1,
|
dir = 1,
|
||||||
file,
|
file,
|
||||||
symlink,
|
symlink,
|
||||||
@@ -30,21 +30,60 @@ pub const InodeHeader = packed struct {
|
|||||||
inode_num: u32,
|
inode_num: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
const itypes = @import("inode_types.zig");
|
pub const InodeData = union(enum) {
|
||||||
|
dir: dir.DirInode,
|
||||||
const InodeData = union(enum) {
|
file: file.FileInode,
|
||||||
dir: itypes.DirInode,
|
symlink: sym.SymlinkInode,
|
||||||
file: itypes.FileInode,
|
block_device: misc.DeviceInode,
|
||||||
symlink: itypes.SymlinkInode,
|
char_device: misc.DeviceInode,
|
||||||
block_device: itypes.DeviceInode,
|
fifo: misc.IPCInode,
|
||||||
char_device: itypes.DeviceInode,
|
socket: misc.IPCInode,
|
||||||
fifo: itypes.FifoInode,
|
ext_dir: dir.ExtDirInode,
|
||||||
socket: itypes.FifoInode,
|
ext_file: file.ExtFileInode,
|
||||||
ext_dir: itypes.ExtDirInode,
|
ext_symlink: sym.ExtSymlinkInode,
|
||||||
ext_file: itypes.ExtFileInode,
|
ext_block_device: misc.ExtDeviceInode,
|
||||||
ext_symlink: itypes.ExtSymlinkInode,
|
ext_char_device: misc.ExtDeviceInode,
|
||||||
ext_block_device: itypes.ExtDeviceInode,
|
ext_fifo: misc.IPCInode,
|
||||||
ext_char_device: itypes.ExtDeviceInode,
|
ext_socket: misc.IPCInode,
|
||||||
ext_fifo: itypes.ExtFifoInode,
|
|
||||||
ext_socket: itypes.ExtFifoInode,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const dir = @import("inode_types/dir.zig");
|
||||||
|
const file = @import("inode_types/file.zig");
|
||||||
|
const sym = @import("inode_types/sym.zig");
|
||||||
|
const misc = @import("inode_types/misc.zig");
|
||||||
|
|
||||||
|
const Inode = struct {
|
||||||
|
header: InodeHeader,
|
||||||
|
data: InodeData,
|
||||||
|
};
|
||||||
|
|
||||||
|
const io = @import("std").io;
|
||||||
|
|
||||||
|
pub fn readInode(rdr: io.AnyReader, block_size: u64) !Inode {
|
||||||
|
const hdr = try rdr.readStruct(InodeHeader);
|
||||||
|
const data: InodeData = undefined;
|
||||||
|
switch (hdr.inode_type) {
|
||||||
|
.dir => data = .{
|
||||||
|
.dir = dir.readDirInode(rdr),
|
||||||
|
},
|
||||||
|
.ext_dir => data = .{
|
||||||
|
.ext_dir = try dir.readExtDirInode(rdr),
|
||||||
|
},
|
||||||
|
.file => data = .{
|
||||||
|
.file = try file.readFileInode(rdr, block_size),
|
||||||
|
},
|
||||||
|
.ext_file => data = .{
|
||||||
|
.ext_file = try file.readExtFileInode(rdr, block_size),
|
||||||
|
},
|
||||||
|
.symlink => data = .{
|
||||||
|
.block_device = try misc.readSymlinkInode(rdr),
|
||||||
|
},
|
||||||
|
.ext_symlink => data = .{
|
||||||
|
.ext_symlink = try sym.readExtSymlinkInode(rdr),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return Inode{
|
||||||
|
.header = hdr,
|
||||||
|
.data = data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
pub const DirInode = packed struct {
|
|
||||||
dir_block_start: u32,
|
|
||||||
hard_links: u32,
|
|
||||||
dir_table_size: u16,
|
|
||||||
dir_block_offset: u16,
|
|
||||||
parent_inode_num: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const DirIndexStart = packed struct {
|
|
||||||
dir_header_offset: u32,
|
|
||||||
dir_table_offset: u32,
|
|
||||||
name_size: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const DirIndex = struct {
|
|
||||||
start: DirIndexStart,
|
|
||||||
name: []const u8,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const ExtDirInodeStart = packed struct {
|
|
||||||
hard_links: u32,
|
|
||||||
dir_table_size: u32,
|
|
||||||
dir_block_start: u32,
|
|
||||||
parent_inode_num: u32,
|
|
||||||
dir_index_count: u16,
|
|
||||||
dir_block_offset: u16,
|
|
||||||
xattr_index: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const ExtDirInode = struct {
|
|
||||||
start: ExtDirInodeStart,
|
|
||||||
indexes: []const u8,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const FileInodeStart = packed struct {
|
|
||||||
start: u32,
|
|
||||||
frag_index: u32,
|
|
||||||
frag_block_offset: u32,
|
|
||||||
size: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const FileInode = struct {
|
|
||||||
start: FileInodeStart,
|
|
||||||
block_sizes: []const u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const ExtFileInodeStart = packed struct {
|
|
||||||
start: u64,
|
|
||||||
size: u64,
|
|
||||||
sparse: u64,
|
|
||||||
hard_links: u32,
|
|
||||||
frag_index: u32,
|
|
||||||
frag_block_offset: u32,
|
|
||||||
xattr_index: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const ExtFileInode = struct {
|
|
||||||
start: ExtFileInodeStart,
|
|
||||||
block_sizes: []const u32,
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const io = std.io;
|
||||||
|
|
||||||
|
pub const DirInode = packed struct {
|
||||||
|
dir_block_start: u32,
|
||||||
|
hard_links: u32,
|
||||||
|
dir_table_size: u16,
|
||||||
|
dir_block_offset: u16,
|
||||||
|
parent_inode_num: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn readDirInode(rdr: io.AnyReader) !DirInode {
|
||||||
|
return try rdr.readStruct(DirInode);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const DirIndex = struct {
|
||||||
|
dir_header_offset: u32,
|
||||||
|
dir_table_offset: u32,
|
||||||
|
name_size: u32,
|
||||||
|
name: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn readDirIndex(rdr: io.AnyReader) !DirIndex {
|
||||||
|
const out = DirIndex{
|
||||||
|
.dir_header_offset = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.dir_table_offset = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.name_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.name = undefined,
|
||||||
|
};
|
||||||
|
const buf = try std.heap.page_allocator.alloc(u8, out.name_size);
|
||||||
|
defer std.heap.page_allocator.free(buf);
|
||||||
|
try rdr.read(buf);
|
||||||
|
out.name = buf[0..];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const ExtDirInode = struct {
|
||||||
|
hard_links: u32,
|
||||||
|
dir_table_size: u32,
|
||||||
|
dir_block_start: u32,
|
||||||
|
parent_inode_num: u32,
|
||||||
|
dir_index_count: u16,
|
||||||
|
dir_block_offset: u16,
|
||||||
|
xattr_index: u32,
|
||||||
|
indexes: []const DirIndex,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn readExtDirInode(rdr: io.AnyReader) !ExtDirInode {
|
||||||
|
const out = ExtDirInode{
|
||||||
|
.hard_links = rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.dir_table_size = rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.dir_block_start = rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.parent_inode_num = rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.dir_index_count = rdr.readInt(u16, std.builtin.Endian.little),
|
||||||
|
.dir_block_offset = rdr.readInt(u16, std.builtin.Endian.little),
|
||||||
|
.xattr_index = rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.indexes = undefined,
|
||||||
|
};
|
||||||
|
out.indexes = []const DirIndex{undefined} ** out.dir_index_count;
|
||||||
|
const i: u16 = 0;
|
||||||
|
while (i < out.dir_index_count) : (i += 1) {
|
||||||
|
out.indexes[i] = try readDirIndex(rdr);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const FileInode = struct {
|
||||||
|
start: u32,
|
||||||
|
frag_index: u32,
|
||||||
|
frag_block_offset: u32,
|
||||||
|
size: u32,
|
||||||
|
block_sizes: []const u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn readFileInode(rdr: std.io.AnyReader, block_size: u32) !FileInode {
|
||||||
|
const out = FileInode{
|
||||||
|
.start = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.frag_index = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.frag_block_offset = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.size = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.block_sizes = undefined,
|
||||||
|
};
|
||||||
|
var block_num = out.size / block_size;
|
||||||
|
if (out.frag_index != 0xFFFFFFFF and out.size % block_size != 0) {
|
||||||
|
block_num += 1;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const ExtFileInode = struct {
|
||||||
|
start: u64,
|
||||||
|
size: u64,
|
||||||
|
sparse: u64,
|
||||||
|
hard_links: u32,
|
||||||
|
frag_index: u32,
|
||||||
|
frag_block_offset: u32,
|
||||||
|
xattr_index: u32,
|
||||||
|
block_sizes: []const u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn readExtFileInode(rdr: std.io.AnyReader, block_size: u32) !ExtFileInode {
|
||||||
|
const out = ExtFileInode{
|
||||||
|
.start = try rdr.readInt(u64, std.builtin.Endian.little),
|
||||||
|
.size = try rdr.readInt(u64, std.builtin.Endian.little),
|
||||||
|
.sparse = try rdr.readInt(u64, std.builtin.Endian.little),
|
||||||
|
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.frag_index = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.frag_block_offset = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.xattr_index = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.block_sizes = undefined,
|
||||||
|
};
|
||||||
|
var block_num = out.size / block_size;
|
||||||
|
if (out.frag_index != 0xFFFFFFFF and out.size % block_size != 0) {
|
||||||
|
block_num += 1;
|
||||||
|
}
|
||||||
|
//TODO: stuff
|
||||||
|
return out;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
pub const DeviceInode = packed struct {
|
||||||
|
hard_links: u32,
|
||||||
|
device: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ExtDeviceInode = packed struct {
|
||||||
|
hard_links: u32,
|
||||||
|
device: u32,
|
||||||
|
xattr_index: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const IPCInode = packed struct {
|
||||||
|
hard_links: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ExtIPCInode = packed struct {
|
||||||
|
hard_links: u32,
|
||||||
|
xattr_index: u32,
|
||||||
|
};
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const io = std.io;
|
||||||
|
|
||||||
|
pub const SymlinkInode = struct {
|
||||||
|
hard_links: u32,
|
||||||
|
target_size: u32,
|
||||||
|
path: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn readSymlinkInode(rdr: io.AnyReader) !SymlinkInode {
|
||||||
|
const out = SymlinkInode{
|
||||||
|
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.target_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.path = undefined,
|
||||||
|
};
|
||||||
|
out.path = (try rdr.readBoundedBytes(out.target_size + 1)).constSlice();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const ExtSymlinkInode = struct {
|
||||||
|
hard_links: u32,
|
||||||
|
target_size: u32,
|
||||||
|
path: []const u8,
|
||||||
|
xattr_index: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn readExtSymlinkInode(rdr: io.AnyReader) !SymlinkInode {
|
||||||
|
const out = ExtSymlinkInode{
|
||||||
|
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.target_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
|
.path = undefined,
|
||||||
|
.xattr_index = undefined,
|
||||||
|
};
|
||||||
|
out.path = (try rdr.readBoundedBytes(out.target_size + 1)).constSlice();
|
||||||
|
out.xattr_index = try rdr.readInt(u32, std.builtin.Endian.little);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
+4
-3
@@ -1,4 +1,5 @@
|
|||||||
const std = @import("std");
|
const math = @import("std").math;
|
||||||
|
const InodeRef = @import("inode.zig").InodeRef;
|
||||||
|
|
||||||
pub const SuperblockError = error{
|
pub const SuperblockError = error{
|
||||||
InvalidMagic,
|
InvalidMagic,
|
||||||
@@ -31,7 +32,7 @@ pub const Superblock = packed struct {
|
|||||||
id_count: u16,
|
id_count: u16,
|
||||||
ver_maj: u16,
|
ver_maj: u16,
|
||||||
ver_min: u16,
|
ver_min: u16,
|
||||||
root_inode: @import("inode.zig").InodeRef,
|
root_inode: InodeRef,
|
||||||
size: u64,
|
size: u64,
|
||||||
id_table: u64,
|
id_table: u64,
|
||||||
xattr_table: u64,
|
xattr_table: u64,
|
||||||
@@ -43,7 +44,7 @@ pub const Superblock = packed struct {
|
|||||||
pub fn valid(self: Superblock) SuperblockError!void {
|
pub fn valid(self: Superblock) SuperblockError!void {
|
||||||
if (self.magic != 0x73717368) {
|
if (self.magic != 0x73717368) {
|
||||||
return SuperblockError.InvalidMagic;
|
return SuperblockError.InvalidMagic;
|
||||||
} else if (self.block_log != std.math.log2(self.block_size)) {
|
} else if (self.block_log != math.log2(self.block_size)) {
|
||||||
return SuperblockError.InvalidLog;
|
return SuperblockError.InvalidLog;
|
||||||
} else if (self.ver_maj != 4 or self.ver_min != 0) {
|
} else if (self.ver_maj != 4 or self.ver_min != 0) {
|
||||||
return SuperblockError.InvalidVersion;
|
return SuperblockError.InvalidVersion;
|
||||||
|
|||||||
Reference in New Issue
Block a user