Further work on inode decoding

This commit is contained in:
Caleb Gardner
2025-05-13 00:23:53 -05:00
parent b3a5ff8f94
commit b4848de95d
6 changed files with 53 additions and 36 deletions
+9 -7
View File
@@ -1,3 +1,5 @@
const std = @import("std");
pub const InodeRef = packed struct { pub const InodeRef = packed struct {
_: u16, _: u16,
block_start: u32, block_start: u32,
@@ -52,14 +54,14 @@ const file = @import("inode_types/file.zig");
const sym = @import("inode_types/sym.zig"); const sym = @import("inode_types/sym.zig");
const misc = @import("inode_types/misc.zig"); const misc = @import("inode_types/misc.zig");
const Inode = struct { pub const Inode = struct {
header: InodeHeader, header: InodeHeader,
data: InodeData, data: InodeData,
}; };
const io = @import("std").io; const io = @import("std").io;
pub fn readInode(rdr: io.AnyReader, block_size: u64) !Inode { pub fn readInode(rdr: io.AnyReader, block_size: u64, alloc: std.heap.Allocator) !Inode {
const hdr = try rdr.readStruct(InodeHeader); const hdr = try rdr.readStruct(InodeHeader);
const data: InodeData = undefined; const data: InodeData = undefined;
switch (hdr.inode_type) { switch (hdr.inode_type) {
@@ -67,19 +69,19 @@ pub fn readInode(rdr: io.AnyReader, block_size: u64) !Inode {
.dir = dir.readDirInode(rdr), .dir = dir.readDirInode(rdr),
}, },
.ext_dir => data = .{ .ext_dir => data = .{
.ext_dir = try dir.readExtDirInode(rdr), .ext_dir = try dir.readExtDirInode(rdr, alloc),
}, },
.file => data = .{ .file => data = .{
.file = try file.readFileInode(rdr, block_size), .file = try file.readFileInode(rdr, block_size, alloc),
}, },
.ext_file => data = .{ .ext_file => data = .{
.ext_file = try file.readExtFileInode(rdr, block_size), .ext_file = try file.readExtFileInode(rdr, block_size, alloc),
}, },
.symlink => data = .{ .symlink => data = .{
.block_device = try misc.readSymlinkInode(rdr), .block_device = try misc.readSymlinkInode(rdr, alloc),
}, },
.ext_symlink => data = .{ .ext_symlink => data = .{
.ext_symlink = try sym.readExtSymlinkInode(rdr), .ext_symlink = try sym.readExtSymlinkInode(rdr, alloc),
}, },
} }
return Inode{ return Inode{
+8 -8
View File
@@ -20,17 +20,15 @@ pub const DirIndex = struct {
name: []const u8, name: []const u8,
}; };
fn readDirIndex(rdr: io.AnyReader) !DirIndex { fn readDirIndex(rdr: io.AnyReader, alloc: std.heap.Allocator) !DirIndex {
const out = DirIndex{ const out = DirIndex{
.dir_header_offset = try rdr.readInt(u32, std.builtin.Endian.little), .dir_header_offset = try rdr.readInt(u32, std.builtin.Endian.little),
.dir_table_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_size = try rdr.readInt(u32, std.builtin.Endian.little),
.name = undefined, .name = undefined,
}; };
const buf = try std.heap.page_allocator.alloc(u8, out.name_size); out.name = try alloc.alloc(u8, out.name_size);
defer std.heap.page_allocator.free(buf); try rdr.read(out.name);
try rdr.read(buf);
out.name = buf[0..];
return out; return out;
} }
@@ -45,7 +43,7 @@ pub const ExtDirInode = struct {
indexes: []const DirIndex, indexes: []const DirIndex,
}; };
pub fn readExtDirInode(rdr: io.AnyReader) !ExtDirInode { pub fn readExtDirInode(rdr: io.AnyReader, alloc: std.heap.Allocator) !ExtDirInode {
const out = ExtDirInode{ const out = ExtDirInode{
.hard_links = rdr.readInt(u32, std.builtin.Endian.little), .hard_links = rdr.readInt(u32, std.builtin.Endian.little),
.dir_table_size = rdr.readInt(u32, std.builtin.Endian.little), .dir_table_size = rdr.readInt(u32, std.builtin.Endian.little),
@@ -56,10 +54,12 @@ pub fn readExtDirInode(rdr: io.AnyReader) !ExtDirInode {
.xattr_index = rdr.readInt(u32, std.builtin.Endian.little), .xattr_index = rdr.readInt(u32, std.builtin.Endian.little),
.indexes = undefined, .indexes = undefined,
}; };
out.indexes = []const DirIndex{undefined} ** out.dir_index_count; const tmp = std.ArrayList(DirIndex).init(alloc);
try tmp.resize(out.dir_index_count);
const i: u16 = 0; const i: u16 = 0;
while (i < out.dir_index_count) : (i += 1) { while (i < out.dir_index_count) : (i += 1) {
out.indexes[i] = try readDirIndex(rdr); tmp.items[i] = try readDirIndex(rdr, alloc);
} }
out.indexes = tmp.items;
return out; return out;
} }
+7 -4
View File
@@ -8,7 +8,7 @@ pub const FileInode = struct {
block_sizes: []const u32, block_sizes: []const u32,
}; };
pub fn readFileInode(rdr: std.io.AnyReader, block_size: u32) !FileInode { pub fn readFileInode(rdr: std.io.AnyReader, block_size: u32, alloc: std.heap.Allocator) !FileInode {
const out = FileInode{ const out = FileInode{
.start = try rdr.readInt(u32, std.builtin.Endian.little), .start = try rdr.readInt(u32, std.builtin.Endian.little),
.frag_index = try rdr.readInt(u32, std.builtin.Endian.little), .frag_index = try rdr.readInt(u32, std.builtin.Endian.little),
@@ -17,9 +17,11 @@ pub fn readFileInode(rdr: std.io.AnyReader, block_size: u32) !FileInode {
.block_sizes = undefined, .block_sizes = undefined,
}; };
var block_num = out.size / block_size; var block_num = out.size / block_size;
if (out.frag_index != 0xFFFFFFFF and out.size % block_size != 0) { if (out.frag_index != 0xFFFFFFFF) {
block_num += 1; block_num += 1;
} }
out.block_sizes = try alloc.alloc(u32, block_num);
try rdr.read(std.mem.asBytes(&out.block_sizes));
return out; return out;
} }
@@ -34,7 +36,7 @@ pub const ExtFileInode = struct {
block_sizes: []const u32, block_sizes: []const u32,
}; };
pub fn readExtFileInode(rdr: std.io.AnyReader, block_size: u32) !ExtFileInode { pub fn readExtFileInode(rdr: std.io.AnyReader, block_size: u32, alloc: std.heap.Allocator) !ExtFileInode {
const out = ExtFileInode{ const out = ExtFileInode{
.start = try rdr.readInt(u64, std.builtin.Endian.little), .start = try rdr.readInt(u64, std.builtin.Endian.little),
.size = try rdr.readInt(u64, std.builtin.Endian.little), .size = try rdr.readInt(u64, std.builtin.Endian.little),
@@ -49,6 +51,7 @@ pub fn readExtFileInode(rdr: std.io.AnyReader, block_size: u32) !ExtFileInode {
if (out.frag_index != 0xFFFFFFFF and out.size % block_size != 0) { if (out.frag_index != 0xFFFFFFFF and out.size % block_size != 0) {
block_num += 1; block_num += 1;
} }
//TODO: stuff out.block_sizes = try alloc.alloc(u32, block_num);
try rdr.read(std.mem.asBytes(&out.block_sizes));
return out; return out;
} }
+6 -4
View File
@@ -7,13 +7,14 @@ pub const SymlinkInode = struct {
path: []const u8, path: []const u8,
}; };
pub fn readSymlinkInode(rdr: io.AnyReader) !SymlinkInode { pub fn readSymlinkInode(rdr: io.AnyReader, alloc: std.heap.Allocator) !SymlinkInode {
const out = SymlinkInode{ const out = SymlinkInode{
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little), .hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
.target_size = try rdr.readInt(u32, std.builtin.Endian.little), .target_size = try rdr.readInt(u32, std.builtin.Endian.little),
.path = undefined, .path = undefined,
}; };
out.path = (try rdr.readBoundedBytes(out.target_size + 1)).constSlice(); out.path = try alloc.alloc(u8, out.target_size + 1);
try rdr.read(out.path);
return out; return out;
} }
@@ -24,14 +25,15 @@ pub const ExtSymlinkInode = struct {
xattr_index: u32, xattr_index: u32,
}; };
pub fn readExtSymlinkInode(rdr: io.AnyReader) !SymlinkInode { pub fn readExtSymlinkInode(rdr: io.AnyReader, alloc: std.heap.Allocator) !SymlinkInode {
const out = ExtSymlinkInode{ const out = ExtSymlinkInode{
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little), .hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
.target_size = try rdr.readInt(u32, std.builtin.Endian.little), .target_size = try rdr.readInt(u32, std.builtin.Endian.little),
.path = undefined, .path = undefined,
.xattr_index = undefined, .xattr_index = undefined,
}; };
out.path = (try rdr.readBoundedBytes(out.target_size + 1)).constSlice(); out.path = try alloc.alloc(u8, out.target_size + 1);
try rdr.read(out.path);
out.xattr_index = try rdr.readInt(u32, std.builtin.Endian.little); out.xattr_index = try rdr.readInt(u32, std.builtin.Endian.little);
return out; return out;
} }
+20 -5
View File
@@ -1,17 +1,32 @@
const std = @import("std"); const std = @import("std");
const io = std.io; const fs = std.fs;
const Superblock = @import("superblock.zig").Superblock; const Superblock = @import("superblock.zig").Superblock;
const Inode = @import("inode.zig").Inode;
pub const Reader = struct { pub const Reader = struct {
super: Superblock, super: Superblock,
rdr: io.AnyReader, rdr: fs.File,
root: Inode,
alloc: std.heap.GeneralPurposeAllocator(.{}),
pub fn close(self: Reader) void {
self.rdr.close();
self.alloc.deinit();
}
}; };
pub fn newReader(rdr: io.AnyReader) !Reader { pub fn newReader(filename: []const u8) !Reader {
const super = try rdr.readStruct(Superblock); const file = try std.fs.cwd().openFile(filename, .{});
errdefer file.close();
const alloc = std.heap.GeneralPurposeAllocator(.{});
errdefer alloc.deinit();
const super = try file.reader().readStruct(Superblock);
try super.valid(); try super.valid();
return Reader{ return Reader{
.super = super, .super = super,
.rdr = rdr, .rdr = file,
.alloc = alloc,
}; };
} }
+2 -7
View File
@@ -5,11 +5,6 @@ const squashfs = @import("squashfs.zig");
const testFileName = "testing/LinuxPATest.sfs"; const testFileName = "testing/LinuxPATest.sfs";
test "open test file" { test "open test file" {
const testFile = try std.fs.cwd().openFile( const reader = try squashfs.newReader(testFileName);
testFileName, defer reader.close();
.{},
);
defer testFile.close();
const reader = try squashfs.newReader(testFile.reader().any());
_ = reader;
} }