From c5e5db988e59689b44feb42c59090c07687bcd42 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Thu, 1 Oct 2026 10:45:57 -0300 Subject: `> exec` through a mount no longer hangs the editor, and a close holding a last line is answered at once: the line runs at the editor's next step A shell's truncating open of exec (or look, ctl, log, pager) sends a setattr that changes nothing; it waited for the editor to be quiet, and through a 9ns mount that quiet could never come: 9ns answers nothing else on the mount while the setattr is out, and the editor's step may be out reading a pane's file through it. This was the "truncating open of exec hangs, only in selfmount" mystery. Only a truncate of a pane's file or a tag waits now. A close holding a last line with no newline hands it to the editor's step (tree.runClosedLines, beside fillClosedPagers), as a /pager close does, and is answered at once; a refusal is the log's err. Co-Authored-By: Claude Opus 5.5 --- src/fs.zig | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/fs.zig') diff --git a/src/fs.zig b/src/fs.zig index 4a243b10..7a56d387 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -1636,6 +1636,11 @@ pub const Namespace = struct { /// a close through a mount may not wait for the editor to be quiet, /// as 9ns answers nothing else on that mount while a clunk is out. pages: std.ArrayList(struct { serial: u32, bytes: std.ArrayList(u8) }) = .empty, + /// The last line each closed open wrote with no newline after it, with + /// the node it was written to, for the editor's step to run + /// (tree.runClosedLines): a close is answered at once, for the same + /// reason as `pages`. + closed_lines: std.ArrayList(struct { node: u64, bytes: std.ArrayList(u8) }) = .empty, batch: struct { serial: u32 = 0, node: u64 = 0, @@ -1685,6 +1690,8 @@ pub const Namespace = struct { for (&st.opens) |*o| o.deinit(gpa); for (st.pages.items) |*page| page.bytes.deinit(gpa); st.pages.deinit(gpa); + for (st.closed_lines.items) |*line| line.bytes.deinit(gpa); + st.closed_lines.deinit(gpa); st.log.deinit(gpa); st.out.deinit(gpa); } -- cgit v1.3