diff --git a/src/browser.zig b/src/browser.zig
index 13e09eb1b13ce90310d87da7adcab626a69aaabc..8ec47656f4ccce7f9453a3282f36aa1b97b5c88a 100644
--- a/src/browser.zig
+++ b/src/browser.zig
@@ -83,22 +83,22 @@ fn sortLt(_: void, ap: ?*model.Entry, bp: ?*model.Entry) bool {
     switch (main.config.sort_col) {
         .name => {}, // name sorting is the fallback
         .blocks => {
-            if (sortIntLt(a.blocks, b.blocks)) |r| return r;
+            if (sortIntLt(a.pack.blocks, b.pack.blocks)) |r| return r;
             if (sortIntLt(a.size, b.size)) |r| return r;
         },
         .size => {
             if (sortIntLt(a.size, b.size)) |r| return r;
-            if (sortIntLt(a.blocks, b.blocks)) |r| return r;
+            if (sortIntLt(a.pack.blocks, b.pack.blocks)) |r| return r;
         },
         .items => {
             const ai = if (a.dir()) |d| d.items else 0;
             const bi = if (b.dir()) |d| d.items else 0;
             if (sortIntLt(ai, bi)) |r| return r;
-            if (sortIntLt(a.blocks, b.blocks)) |r| return r;
+            if (sortIntLt(a.pack.blocks, b.pack.blocks)) |r| return r;
             if (sortIntLt(a.size, b.size)) |r| return r;
         },
         .mtime => {
-            if (!a.isext or !b.isext) return a.isext;
+            if (!a.pack.isext or !b.pack.isext) return a.pack.isext;
             if (sortIntLt(a.ext().?.mtime, b.ext().?.mtime)) |r| return r;
         },
     }
@@ -135,10 +135,10 @@ pub fn loadDir(next_sel: ?*const model.Entry) void {
         dir_items.append(null) catch unreachable;
     var it = dir_parent.sub;
     while (it) |e| {
-        if (e.blocks > dir_max_blocks) dir_max_blocks = e.blocks;
+        if (e.pack.blocks > dir_max_blocks) dir_max_blocks = e.pack.blocks;
         if (e.size > dir_max_size) dir_max_size = e.size;
         const shown = main.config.show_hidden or blk: {
-            const excl = if (e.file()) |f| f.excluded else false;
+            const excl = if (e.file()) |f| f.pack.excluded else false;
             const name = e.name();
             break :blk !excl and name[0] != '.' and name[name.len-1] != '~';
         };
@@ -164,14 +164,14 @@ const Row = struct {
         const item = self.item orelse return;
         const ch: u7 = ch: {
             if (item.file()) |f| {
-                if (f.err) break :ch '!';
-                if (f.excluded) break :ch '<';
-                if (f.other_fs) break :ch '>';
-                if (f.kernfs) break :ch '^';
-                if (f.notreg) break :ch '@';
+                if (f.pack.err) break :ch '!';
+                if (f.pack.excluded) break :ch '<';
+                if (f.pack.other_fs) break :ch '>';
+                if (f.pack.kernfs) break :ch '^';
+                if (f.pack.notreg) break :ch '@';
             } else if (item.dir()) |d| {
-                if (d.err) break :ch '!';
-                if (d.suberr) break :ch '.';
+                if (d.pack.err) break :ch '!';
+                if (d.pack.suberr) break :ch '.';
                 if (d.sub == null) break :ch 'e';
             } else if (item.link()) |_| break :ch 'H';
             return;
@@ -187,7 +187,7 @@ const Row = struct {
             width += 2 + width;
         defer self.col += width;
         const item = self.item orelse return;
-        const siz = if (main.config.show_blocks) util.blocksToSize(item.blocks) else item.size;
+        const siz = if (main.config.show_blocks) util.blocksToSize(item.pack.blocks) else item.size;
         var shr = if (item.dir()) |d| (if (main.config.show_blocks) util.blocksToSize(d.shared_blocks) else d.shared_size) else 0;
         if (main.config.show_shared == .unique) shr = siz -| shr;
 
@@ -216,8 +216,8 @@ const Row = struct {
         if (main.config.show_percent) {
             self.bg.fg(.num);
             ui.addprint("{d:>5.1}", .{ 100 *
-                if (main.config.show_blocks) @intToFloat(f32, item.blocks) / @intToFloat(f32, std.math.max(1, dir_parent.entry.blocks))
-                else                         @intToFloat(f32, item.size)   / @intToFloat(f32, std.math.max(1, dir_parent.entry.size))
+                if (main.config.show_blocks) @intToFloat(f32, item.pack.blocks) / @intToFloat(f32, std.math.max(1, dir_parent.entry.pack.blocks))
+                else                         @intToFloat(f32, item.size)        / @intToFloat(f32, std.math.max(1, dir_parent.entry.size))
             });
             self.bg.fg(.default);
             ui.addch('%');
@@ -225,7 +225,7 @@ const Row = struct {
         if (main.config.show_graph and main.config.show_percent) ui.addch(' ');
         if (main.config.show_graph) {
             var max = if (main.config.show_blocks) dir_max_blocks else dir_max_size;
-            var num = if (main.config.show_blocks) item.blocks else item.size;
+            var num = if (main.config.show_blocks) item.pack.blocks else item.size;
             if (max < bar_size) {
                 max *= bar_size;
                 num *= bar_size;
@@ -290,7 +290,7 @@ const Row = struct {
     fn name(self: *Self) void {
         ui.move(self.row, self.col);
         if (self.item) |i| {
-            self.bg.fg(if (i.etype == .dir) .dir else .default);
+            self.bg.fg(if (i.pack.etype == .dir) .dir else .default);
             ui.addch(if (i.isDirectory()) '/' else ' ');
             ui.addstr(ui.shorten(ui.toUtf8(i.name()), ui.cols -| self.col -| 1));
         } else {
@@ -460,7 +460,7 @@ const info = struct {
         } else {
             ui.addstr("Type: ");
             ui.style(.default);
-            ui.addstr(if (e.isDirectory()) "Directory" else if (if (e.file()) |f| f.notreg else false) "Other" else "File");
+            ui.addstr(if (e.isDirectory()) "Directory" else if (if (e.file()) |f| f.pack.notreg else false) "Other" else "File");
         }
         row.* += 1;
 
@@ -474,7 +474,7 @@ const info = struct {
         }
 
         // Disk usage & Apparent size
-        drawSize(box, row, "   Disk usage: ", util.blocksToSize(e.blocks), if (e.dir()) |d| util.blocksToSize(d.shared_blocks) else 0);
+        drawSize(box, row, "   Disk usage: ", util.blocksToSize(e.pack.blocks), if (e.dir()) |d| util.blocksToSize(d.shared_blocks) else 0);
         drawSize(box, row, "Apparent size: ", e.size, if (e.dir()) |d| d.shared_size else 0);
 
         // Number of items
@@ -522,7 +522,7 @@ const info = struct {
         var row: u32 = 2;
 
         // Tabs
-        if (e.etype == .link) {
+        if (e.pack.etype == .link) {
             box.tab(cols-19, tab == .info, 1, "Info");
             box.tab(cols-10, tab == .links, 2, "Links");
         }
@@ -543,7 +543,7 @@ const info = struct {
     }
 
     fn keyInput(ch: i32) bool {
-        if (entry.?.etype == .link) {
+        if (entry.?.pack.etype == .link) {
             switch (ch) {
                 '1', 'h', ui.c.KEY_LEFT => { set(entry, .info); return true; },
                 '2', 'l', ui.c.KEY_RIGHT => { set(entry, .links); return true; },
@@ -778,7 +778,7 @@ pub fn draw() void {
     ui.move(ui.rows-1, 1);
     ui.style(if (main.config.show_blocks) .bold_hd else .hd);
     ui.addstr("Total disk usage: ");
-    ui.addsize(.hd, util.blocksToSize(dir_parent.entry.blocks));
+    ui.addsize(.hd, util.blocksToSize(dir_parent.entry.pack.blocks));
     ui.style(if (main.config.show_blocks) .hd else .bold_hd);
     ui.addstr("  Apparent size: ");
     ui.addsize(.hd, dir_parent.entry.size);
diff --git a/src/delete.zig b/src/delete.zig
index 1f6575c38f2fd7539f02752a7ea7be685df1cba0..d98a2bd888800b504f1180e247ff5f73d5419fd5 100644
--- a/src/delete.zig
+++ b/src/delete.zig
@@ -100,7 +100,7 @@ fn drawConfirm() void {
     ui.addstr("Are you sure you want to delete \"");
     ui.addstr(ui.shorten(ui.toUtf8(entry.name()), 21));
     ui.addch('"');
-    if (entry.etype != .dir)
+    if (entry.pack.etype != .dir)
         ui.addch('?')
     else {
         box.move(2, 18);
diff --git a/src/model.zig b/src/model.zig
index 75cfe3d5223a1de85380a58c4e07dd00b5cbf467..cfd67b54a2be6540caae6dc9760e9d398eb655e8 100644
--- a/src/model.zig
+++ b/src/model.zig
@@ -17,7 +17,7 @@ const allocator = allocator_state.allocator();
 
 pub const EType = enum(u2) { dir, link, file };
 
-// Type for the Entry.blocks field. Smaller than a u64 to make room for flags.
+// Type for the Entry.Packed.blocks field. Smaller than a u64 to make room for flags.
 pub const Blocks = u60;
 
 // Memory layout:
@@ -31,38 +31,40 @@ pub const Blocks = u60;
 // These are all packed structs and hence do not have any alignment, which is
 // great for saving memory but perhaps not very great for code size or
 // performance.
-// (TODO: What are the aliassing rules for Zig? There is a 'noalias' keyword,
-// but does that mean all unmarked pointers are allowed to alias?)
-pub const Entry = packed struct {
-    etype: EType,
-    isext: bool,
-    // Whether or not this entry's size has been counted in its parents.
-    // Counting of Link entries is deferred until the scan/delete operation has
-    // completed, so for those entries this flag indicates an intention to be
-    // counted.
-    counted: bool,
-    blocks: Blocks, // 512-byte blocks
-    size: u64,
-    next: ?*Entry,
+pub const Entry = extern struct {
+    pack: Packed align(1),
+    size: u64 align(1),
+    next: ?*Entry align(1),
+
+    pub const Packed = packed struct(u64) {
+        etype: EType,
+        isext: bool,
+        // Whether or not this entry's size has been counted in its parents.
+        // Counting of Link entries is deferred until the scan/delete operation has
+        // completed, so for those entries this flag indicates an intention to be
+        // counted.
+        counted: bool,
+        blocks: Blocks, // 512-byte blocks
+    };
 
     const Self = @This();
 
     pub fn dir(self: *Self) ?*Dir {
-        return if (self.etype == .dir) @ptrCast(*Dir, self) else null;
+        return if (self.pack.etype == .dir) @ptrCast(*Dir, self) else null;
     }
 
     pub fn link(self: *Self) ?*Link {
-        return if (self.etype == .link) @ptrCast(*Link, self) else null;
+        return if (self.pack.etype == .link) @ptrCast(*Link, self) else null;
     }
 
     pub fn file(self: *Self) ?*File {
-        return if (self.etype == .file) @ptrCast(*File, self) else null;
+        return if (self.pack.etype == .file) @ptrCast(*File, self) else null;
     }
 
     // Whether this entry should be displayed as a "directory".
     // Some dirs are actually represented in this data model as a File for efficiency.
     pub fn isDirectory(self: *Self) bool {
-        return if (self.file()) |f| f.other_fs or f.kernfs else self.etype == .dir;
+        return if (self.file()) |f| f.pack.other_fs or f.pack.kernfs else self.pack.etype == .dir;
     }
 
     fn nameOffset(etype: EType) usize {
@@ -74,12 +76,12 @@ pub const Entry = packed struct {
     }
 
     pub fn name(self: *const Self) [:0]const u8 {
-        const ptr = @ptrCast([*:0]const u8, self) + nameOffset(self.etype);
+        const ptr = @ptrCast([*:0]const u8, self) + nameOffset(self.pack.etype); // TODO: ptrCast the 'name' field instead.
         return std.mem.sliceTo(ptr, 0);
     }
 
     pub fn ext(self: *Self) ?*Ext {
-        if (!self.isext) return null;
+        if (!self.pack.isext) return null;
         return @ptrCast(*Ext, @ptrCast([*]Ext, self) - 1);
     }
 
@@ -88,7 +90,7 @@ pub const Entry = packed struct {
         const size = nameOffset(etype) + ename.len + 1 + extsize;
         var ptr = blk: {
             while (true) {
-                if (allocator.allocWithOptions(u8, size, std.math.max(@alignOf(Ext), @alignOf(Entry)), null)) |p|
+                if (allocator.allocWithOptions(u8, size, 1, null)) |p|
                     break :blk p
                 else |_| {}
                 ui.oom();
@@ -96,8 +98,8 @@ pub const Entry = packed struct {
         };
         std.mem.set(u8, ptr, 0); // kind of ugly, but does the trick
         var e = @ptrCast(*Entry, ptr.ptr + extsize);
-        e.etype = etype;
-        e.isext = isext;
+        e.pack.etype = etype;
+        e.pack.isext = isext;
         var name_ptr = @ptrCast([*]u8, e) + nameOffset(etype);
         std.mem.copy(u8, name_ptr[0..ename.len], ename);
         return e;
@@ -105,19 +107,19 @@ pub const Entry = packed struct {
 
     // Set the 'err' flag on Dirs and Files, propagating 'suberr' to parents.
     pub fn setErr(self: *Self, parent: *Dir) void {
-        if (self.dir()) |d| d.err = true
-        else if (self.file()) |f| f.err = true
+        if (self.dir()) |d| d.pack.err = true
+        else if (self.file()) |f| f.pack.err = true
         else unreachable;
         var it: ?*Dir = if (&parent.entry == self) parent.parent else parent;
         while (it) |p| : (it = p.parent) {
-            if (p.suberr) break;
-            p.suberr = true;
+            if (p.pack.suberr) break;
+            p.pack.suberr = true;
         }
     }
 
     pub fn addStats(self: *Entry, parent: *Dir, nlink: u31) void {
-        if (self.counted) return;
-        self.counted = true;
+        if (self.pack.counted) return;
+        self.pack.counted = true;
 
         // Add link to the inode map, but don't count its size (yet).
         if (self.link()) |l| {
@@ -125,7 +127,7 @@ pub const Entry = packed struct {
             var d = inodes.map.getOrPut(l) catch unreachable;
             if (!d.found_existing) {
                 d.value_ptr.* = .{ .counted = false, .nlink = nlink };
-                inodes.total_blocks +|= self.blocks;
+                inodes.total_blocks +|= self.pack.blocks;
                 l.next = l;
             } else {
                 inodes.setStats(.{ .key_ptr = d.key_ptr, .value_ptr = d.value_ptr }, false);
@@ -144,9 +146,9 @@ pub const Entry = packed struct {
                 if (p.entry.ext()) |pe|
                     if (e.mtime > pe.mtime) { pe.mtime = e.mtime; };
             p.items +|= 1;
-            if (self.etype != .link) {
+            if (self.pack.etype != .link) {
                 p.entry.size +|= self.size;
-                p.entry.blocks +|= self.blocks;
+                p.entry.pack.blocks +|= self.pack.blocks;
             }
         }
     }
@@ -165,8 +167,8 @@ pub const Entry = packed struct {
     // anymore, meaning that delStats() followed by addStats() with the same
     // data may cause information to be lost.
     pub fn delStats(self: *Entry, parent: *Dir) void {
-        if (!self.counted) return;
-        defer self.counted = false; // defer, to make sure inodes.setStats() still sees it as counted.
+        if (!self.pack.counted) return;
+        defer self.pack.counted = false; // defer, to make sure inodes.setStats() still sees it as counted.
 
         if (self.link()) |l| {
             var d = inodes.map.getEntry(l).?;
@@ -175,7 +177,7 @@ pub const Entry = packed struct {
             if (l.next == l) {
                 _ = inodes.map.remove(l);
                 _ = inodes.uncounted.remove(l);
-                inodes.total_blocks -|= self.blocks;
+                inodes.total_blocks -|= self.pack.blocks;
             } else {
                 if (d.key_ptr.* == l)
                     d.key_ptr.* = l.next;
@@ -195,9 +197,9 @@ pub const Entry = packed struct {
         var it: ?*Dir = parent;
         while(it) |p| : (it = p.parent) {
             p.items -|= 1;
-            if (self.etype != .link) {
+            if (self.pack.etype != .link) {
                 p.entry.size -|= self.size;
-                p.entry.blocks -|= self.blocks;
+                p.entry.pack.blocks -|= self.pack.blocks;
             }
         }
     }
@@ -212,32 +214,35 @@ pub const Entry = packed struct {
     }
 };
 
-const DevId = u30; // Can be reduced to make room for more flags in Dir.
+const DevId = u30; // Can be reduced to make room for more flags in Dir.Packed.
 
-pub const Dir = packed struct {
+pub const Dir = extern struct {
     entry: Entry,
 
-    sub: ?*Entry,
-    parent: ?*Dir,
+    sub: ?*Entry align(1),
+    parent: ?*Dir align(1),
 
     // entry.{blocks,size}: Total size of all unique files + dirs. Non-shared hardlinks are counted only once.
     //   (i.e. the space you'll need if you created a filesystem with only this dir)
     // shared_*: Unique hardlinks that still have references outside of this directory.
     //   (i.e. the space you won't reclaim by deleting this dir)
     // (space reclaimed by deleting a dir =~ entry. - shared_)
-    shared_blocks: u64,
-    shared_size: u64,
-    items: u32,
-
-    // Indexes into the global 'devices.list' array
-    dev: DevId,
+    shared_blocks: u64 align(1),
+    shared_size: u64 align(1),
+    items: u32 align(1),
 
-    err: bool,
-    suberr: bool,
+    pack: Packed align(1),
 
     // Only used to find the @offsetOff, the name is written at this point as a 0-terminated string.
     // (Old C habits die hard)
-    name: u8,
+    name: [0]u8,
+
+    pub const Packed = packed struct {
+        // Indexes into the global 'devices.list' array
+        dev: DevId,
+        err: bool,
+        suberr: bool,
+    };
 
     pub fn fmtPath(self: *const @This(), withRoot: bool, out: *std.ArrayList(u8)) void {
         if (!withRoot and self.parent == null) return;
@@ -259,13 +264,13 @@ pub const Dir = packed struct {
 };
 
 // File that's been hardlinked (i.e. nlink > 1)
-pub const Link = packed struct {
+pub const Link = extern struct {
     entry: Entry,
-    parent: *Dir,
-    next: *Link, // Singly circular linked list of all *Link nodes with the same dev,ino.
+    parent: *Dir align(1),
+    next: *Link align(1), // Singly circular linked list of all *Link nodes with the same dev,ino.
     // dev is inherited from the parent Dir
-    ino: u64,
-    name: u8,
+    ino: u64 align(1),
+    name: [0]u8,
 
     // Return value should be freed with main.allocator.
     pub fn path(self: @This(), withRoot: bool) [:0]const u8 {
@@ -278,40 +283,32 @@ pub const Link = packed struct {
 };
 
 // Anything that's not an (indexed) directory or hardlink. Excluded directories are also "Files".
-pub const File = packed struct {
+pub const File = extern struct {
     entry: Entry,
-
-    err: bool,
-    excluded: bool,
-    other_fs: bool,
-    kernfs: bool,
-    notreg: bool,
-    _pad: u3,
-
-    name: u8,
+    pack: Packed,
+    name: [0]u8,
+
+    pub const Packed = packed struct(u8) {
+        err: bool = false,
+        excluded: bool = false,
+        other_fs: bool = false,
+        kernfs: bool = false,
+        notreg: bool = false,
+        _pad: u3 = 0, // Make this struct "ABI sized" to allow inclusion in an extern struct
+    };
 
     pub fn resetFlags(f: *@This()) void {
-        f.err = false;
-        f.excluded = false;
-        f.other_fs = false;
-        f.kernfs = false;
-        f.notreg = false;
+        f.pack = .{};
     }
 };
 
-pub const Ext = packed struct {
-    mtime: u64 = 0,
-    uid: u32 = 0,
-    gid: u32 = 0,
-    mode: u16 = 0,
+pub const Ext = extern struct {
+    mtime: u64 align(1) = 0,
+    uid: u32 align(1) = 0,
+    gid: u32 align(1) = 0,
+    mode: u16 align(1) = 0,
 };
 
-comptime {
-    std.debug.assert(@bitOffsetOf(Dir, "name") % 8 == 0);
-    std.debug.assert(@bitOffsetOf(Link, "name") % 8 == 0);
-    std.debug.assert(@bitOffsetOf(File, "name") % 8 == 0);
-}
-
 
 // List of st_dev entries. Those are typically 64bits, but that's quite a waste
 // of space when a typical scan won't cover many unique devices.
@@ -367,13 +364,13 @@ pub const inodes = struct {
     const HashContext = struct {
         pub fn hash(_: @This(), l: *Link) u64 {
             var h = std.hash.Wyhash.init(0);
-            h.update(std.mem.asBytes(&@as(u32, l.parent.dev)));
+            h.update(std.mem.asBytes(&@as(u32, l.parent.pack.dev)));
             h.update(std.mem.asBytes(&l.ino));
             return h.final();
         }
 
         pub fn eql(_: @This(), a: *Link, b: *Link) bool {
-            return a.ino == b.ino and a.parent.dev == b.parent.dev;
+            return a.ino == b.ino and a.parent.pack.dev == b.parent.pack.dev;
         }
     };
 
@@ -399,7 +396,7 @@ pub const inodes = struct {
         defer dirs.deinit();
         var it = entry.key_ptr.*;
         while (true) {
-            if (it.entry.counted) {
+            if (it.entry.pack.counted) {
                 nlink += 1;
                 var parent: ?*Dir = it.parent;
                 while (parent) |p| : (parent = p.parent) {
@@ -419,19 +416,19 @@ pub const inodes = struct {
         var dir_iter = dirs.iterator();
         if (add) {
             while (dir_iter.next()) |de| {
-                de.key_ptr.*.entry.blocks +|= entry.key_ptr.*.entry.blocks;
-                de.key_ptr.*.entry.size   +|= entry.key_ptr.*.entry.size;
+                de.key_ptr.*.entry.pack.blocks +|= entry.key_ptr.*.entry.pack.blocks;
+                de.key_ptr.*.entry.size        +|= entry.key_ptr.*.entry.size;
                 if (de.value_ptr.* < nlink) {
-                    de.key_ptr.*.shared_blocks +|= entry.key_ptr.*.entry.blocks;
+                    de.key_ptr.*.shared_blocks +|= entry.key_ptr.*.entry.pack.blocks;
                     de.key_ptr.*.shared_size   +|= entry.key_ptr.*.entry.size;
                 }
             }
         } else {
             while (dir_iter.next()) |de| {
-                de.key_ptr.*.entry.blocks -|= entry.key_ptr.*.entry.blocks;
-                de.key_ptr.*.entry.size   -|= entry.key_ptr.*.entry.size;
+                de.key_ptr.*.entry.pack.blocks -|= entry.key_ptr.*.entry.pack.blocks;
+                de.key_ptr.*.entry.size        -|= entry.key_ptr.*.entry.size;
                 if (de.value_ptr.* < nlink) {
-                    de.key_ptr.*.shared_blocks -|= entry.key_ptr.*.entry.blocks;
+                    de.key_ptr.*.shared_blocks -|= entry.key_ptr.*.entry.pack.blocks;
                     de.key_ptr.*.shared_size   -|= entry.key_ptr.*.entry.size;
                 }
             }
@@ -458,7 +455,7 @@ pub var root: *Dir = undefined;
 
 test "entry" {
     var e = Entry.create(.file, false, "hello");
-    try std.testing.expectEqual(e.etype, .file);
-    try std.testing.expect(!e.isext);
+    try std.testing.expectEqual(e.pack.etype, .file);
+    try std.testing.expect(!e.pack.isext);
     try std.testing.expectEqualStrings(e.name(), "hello");
 }
diff --git a/src/scan.zig b/src/scan.zig
index 74c2ae527c0924460916f48b76880d5d6334b6a0..142857c7475c155317e647ceb0564124b2ba952b 100644
--- a/src/scan.zig
+++ b/src/scan.zig
@@ -156,11 +156,11 @@ const ScanDir = struct {
                 // in-place conversion to a File entry. That's more efficient,
                 // but also more code. I don't expect this to happen often.
                 var e = entry.key_ptr.*.?;
-                if (e.etype == .file) {
-                    if (e.size > 0 or e.blocks > 0) {
+                if (e.pack.etype == .file) {
+                    if (e.size > 0 or e.pack.blocks > 0) {
                         e.delStats(self.dir);
                         e.size = 0;
-                        e.blocks = 0;
+                        e.pack.blocks = 0;
                         e.addStats(self.dir, 0);
                     }
                     e.file().?.resetFlags();
@@ -177,9 +177,9 @@ const ScanDir = struct {
         var f = e.file().?;
         switch (t) {
             .err => e.setErr(self.dir),
-            .other_fs => f.other_fs = true,
-            .kernfs => f.kernfs = true,
-            .excluded => f.excluded = true,
+            .other_fs => f.pack.other_fs = true,
+            .kernfs => f.pack.kernfs = true,
+            .excluded => f.pack.excluded = true,
         }
     }
 
@@ -192,9 +192,9 @@ const ScanDir = struct {
                 // XXX: In-place conversion may also be possible here.
                 var e = entry.key_ptr.*.?;
                 // changes of dev/ino affect hard link counting in a way we can't simply merge.
-                const samedev = if (e.dir()) |d| d.dev == model.devices.getId(stat.dev) else true;
+                const samedev = if (e.dir()) |d| d.pack.dev == model.devices.getId(stat.dev) else true;
                 const sameino = if (e.link()) |l| l.ino == stat.ino else true;
-                if (e.etype == etype and samedev and sameino) {
+                if (e.pack.etype == etype and samedev and sameino) {
                     _ = self.entries.removeAdapted(@as(?*model.Entry,null), HashContext{ .cmp = name });
                     break :blk e;
                 } else e.delStatsRec(self.dir);
@@ -209,18 +209,18 @@ const ScanDir = struct {
         // entire subtree, which, in turn, would break all shared hardlink
         // sizes. The current approach may result in incorrect sizes after
         // refresh, but I expect the difference to be fairly minor.
-        if (!(e.etype == .dir and e.counted) and (e.blocks != stat.blocks or e.size != stat.size)) {
+        if (!(e.pack.etype == .dir and e.pack.counted) and (e.pack.blocks != stat.blocks or e.size != stat.size)) {
             e.delStats(self.dir);
-            e.blocks = stat.blocks;
+            e.pack.blocks = stat.blocks;
             e.size = stat.size;
         }
         if (e.dir()) |d| {
             d.parent = self.dir;
-            d.dev = model.devices.getId(stat.dev);
+            d.pack.dev = model.devices.getId(stat.dev);
         }
         if (e.file()) |f| {
             f.resetFlags();
-            f.notreg = !stat.dir and !stat.reg;
+            f.pack.notreg = !stat.dir and !stat.reg;
         }
         if (e.link()) |l| l.ino = stat.ino;
         if (e.ext()) |ext| {
@@ -415,11 +415,11 @@ const Context = struct {
             var e = if (p.items.len == 0) blk: {
                 // Root entry
                 var e = model.Entry.create(.dir, main.config.extended, self.name);
-                e.blocks = self.stat.blocks;
+                e.pack.blocks = self.stat.blocks;
                 e.size = self.stat.size;
                 if (e.ext()) |ext| ext.* = self.stat.ext;
                 model.root = e.dir().?;
-                model.root.dev = model.devices.getId(self.stat.dev);
+                model.root.pack.dev = model.devices.getId(self.stat.dev);
                 break :blk e;
             } else
                 p.items[p.items.len-1].addStat(self.name, &self.stat);
@@ -552,7 +552,7 @@ pub fn setupRefresh(parent: *model.Dir) void {
     parent.fmtPath(true, &full_path);
     active_context.pushPath(full_path.items);
     active_context.stat.dir = true;
-    active_context.stat.dev = model.devices.list.items[parent.dev];
+    active_context.stat.dev = model.devices.list.items[parent.pack.dev];
 }
 
 // To be called after setupRefresh() (or from scanRoot())
@@ -1021,7 +1021,7 @@ fn drawBox() void {
         box.move(2, 30);
         ui.addstr("size: ");
         // TODO: Should display the size of the dir-to-be-refreshed on refreshing, not the root.
-        ui.addsize(.default, util.blocksToSize(model.root.entry.blocks +| model.inodes.total_blocks));
+        ui.addsize(.default, util.blocksToSize(model.root.entry.pack.blocks +| model.inodes.total_blocks));
     }
 
     box.move(3, 2);
@@ -1088,7 +1088,7 @@ pub fn draw() void {
                     .{ ui.shorten(active_context.pathZ(), 63), active_context.items_seen }
                 ) catch return;
             } else {
-                const r = ui.FmtSize.fmt(util.blocksToSize(model.root.entry.blocks));
+                const r = ui.FmtSize.fmt(util.blocksToSize(model.root.entry.pack.blocks));
                 line = std.fmt.bufPrint(&buf, "\x1b7\x1b[J{s: <51} {d:>9} files / {s}{s}\x1b8",
                     .{ ui.shorten(active_context.pathZ(), 51), active_context.items_seen, r.num(), r.unit }
                 ) catch return;