| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
| |
at the limit the command's group is killed and reaped off the answer's path, the stdin writer owning its input, so a filter writing its own ctl with > or >> answers EIO at 10 s instead of hanging; a running Edit keeps its own copies of the names it reports, and the panes it changes refuse Del, delete, rmdir, Undo, Redo, Get and Zerox (busy, EBUSY); e and r say unreadable files in Get's words; the reference says both sides of a filter's own ctl write need <>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
the serving thread; selfmount kills a session under a burst of reads of it through the registry mount and checks every read returns
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
FOPEN_PARALLEL_DIRECT_WRITES: an Edit filter writing, through a mount, the ctl its Edit came by (without truncating it) answers at once, not after 10 s; selfmount checks it
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
again to overwrite), the rest of an X/'/w written and the refused named; Edit filters get a pane command's environment ($PARDES_MOUNT, $PARDES_9P, $PARDES_PID, $winid); an Edit with no commands runs beside one whose commands run unless it touches a file that one changes, refused busy (EBUSY) as is a second Edit with commands
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
(answered like a held read, so a status read or a filter reading the session's own mount runs beside it), a Tflush or hang-up of the write kills the commands' process groups and changes nothing; e loads by Get's way (asked once, clean after, undo puts the name back); ~ in e r w f B; B checks every name first; an Edit that runs commands is a write of its own, refused up front with other lines; Edit's +Errors output keeps the keyboard where it was; X goes in pane order; a refused write open says its errno; the reference's Coming from acme rows say what Get file's undo, failure and directory refusal, Putall's answer, Zerox across Dump and Incl's directories now do
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
under 9ns --mntgen ($NINE_MOUNT/pardes/<name>), unset when it is not known
9ns says --mntgen with NINE_MNTGEN=1 (cloud9). Under `9ns --unix` the
mount is the server it dialled, never this session (its socket does not
exist until it starts), so it stays unset there; scripts fall back to
`9p -a "unix!$PARDES_9P"`. Nothing is statted: the name comes from the
session's socket and the environment. selfmount checks both modes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 <[email protected]>
|
| |
|
|
| |
written after its directory with ghostty-vt, SGR becomes spans drawn over the plain text, every other escape is dropped, and PagerColor off pages it plain
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
because a write was short: a long line cut by a mount is one line
A write shorter than its message, and not a multiple of 4096, was taken
as whole, its tail a line. 9ns cuts a FUSE write of up to 512 KiB into
65512-byte Twrites, the last one short, so a 600 KiB `Edit ,c/.../`
arrived cut and its tail ran as an unknown control message; the 1 MiB
refusal failed the same way. Each open now holds a partial line until
its newline, or its release, which ends the last line; an Edit block is
whole when it closes, as before. A name write with a NUL still fails
its write at once. selfmount writes a 600 KiB Edit line and a 1.1 MiB
line through a real 9ns mount; building.typ says how lines are cut.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
EMFILE, "Too many open files": pardes re-pins cloud9, whose 9ns maps the words
The refusal's words said too many open files, but 9ns matched none of
its needles and handed the shell Input/output error. The re-pinned
cloud9's 9ns maps them to EMFILE. selfmount opens the root exec for
writing eighty times through the mount and hears EMFILE at the 65th.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
read loop on event works
A read shorter than the record waiting was refused EINVAL, and bash's
read, a byte at a time on a file it cannot seek in, failed on the
first record. A short read now takes the record's front and the next
read the rest, as log and pty/data already did and acme allows. A
unit test reads two records a byte at a time; selfmount runs a bash
read on event through the mount.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
and nonseekable: fs.md's follow recipe with cat works through a mount
The log stated the length an open would freeze, a length a mount's
kernel could take as its end, and a splicing cat read it from the
kernel's offset. log now stats 0, as the other streams and generated
views do, and the re-pinned cloud9's 9ns opens any file stating 0
FOPEN_DIRECT_IO | FOPEN_NONSEEKABLE. A look at such a file (the mounted
index) reads a regular file that will not seek as a stream rather than
refusing it as a pipe. selfmount runs the recipe, exec 3<>log; echo
follow >&3; cat <&3, through the mount and hears a record made after it
started.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
one that fills its Twrite does: a burst through a mount no longer runs its cut lines as two commands
selfmount's 1000-line burst reported 943 lines, on main too. The log
ring was not losing records: a follower opened before the burst heard
exactly 943 and no `lost`, and the burst itself exited 1 with
`err 1 exec: wrong #args in control message "Msg"`. `seq ... > exec`
through the mount arrives as stdio's 4096-byte writes, each shorter than
a Twrite. The rule that such a write is whole ran each one's cut last
line at once, so both halves of the line ran as commands (hence `exit
127` records). At 12288 bytes the cut left a bare `Msg`, which was
refused and failed the write and the rest of the burst.
A write of a multiple of 4096 bytes is where a writer's buffer (stdio, a
page cache) filled, so it may go on: its unended tail now waits for the
next write or the close, like one that fills its Twrite. `printf Save >
exec` stays whole at once. fs.md says so, the 9P fuzzer's model of served
lines follows it, and a unit test cuts a `Msg` at 4096 bytes.
A follower does not lose records silently: a ring that outruns one
already reads it `lost N` first (documented, tested). selfmount now
follows the log from before the burst, so it checks every line heard
once, in order, or a loss said, not a fresh open of a 64 KiB ring. It
passed 3 in 3 and joins the gates with the new 9ns.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
waiting: 128", and a mount beside 40 held event reads still answers
Two limits met. pardes parked 32 reads per connection and refused the
next with EAGAIN's C string, "Resource temporarily unavailable". 9ns kept
32 tags and 31 workers, each pinned by a held read. So 31 followers
through one mount took every worker, and `cat layout` then queued for
ever: the whole mount deadlocked.
cloud9 (705be665, pushed to sr.ht and pinned here) now refuses in words
past the cap. Its 9ns window is 256, so a mount always has workers past
what pardes holds. pardes raises its cap to 128. fs.md documents the limit
beside held reads. selfmount.py holds 40 event reads through the mount and
reads layout beside them. It times out with the 9ns installed before this
change and passes with the new one.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A mount cuts a write at its message size, and each piece ran on its own: a
line cut at the boundary ran as shell commands and a 50 KB Edit block
broke. An open of look, exec, tagexec, any ctl or a column's exec now keeps
an unfinished last line, or an Edit block still open, until its next write
or its release, and never runs a fragment. The same open record holds what
its last write touched, which a read on it answers (as /net/tcp/clone
does); an open that never wrote reads the session's last as of its open.
A release that runs a held line waits for quiet and counts as a change;
a clicked line with a control character is still refused at its write.
Tested in unit tests, fs.py (python client, 8 KiB) and selfmount.py (the
kernel mount, a 1000-line seq burst and a 50 KB Edit block).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
A script could not see where the panes sit or edit the tags a person
clicks in. /layout lists each column, its index, x and width in cells,
current or not, empty or full, and its panes' serials, then the active
column; /tag is the workspace tag and /col/<n>/tag a column's, read and
written as a pane tag is (one line: a newline written in is a space, and a
truncating write drops the one ending it); /index's lines end with the
pane's column; the log says newcol <n> and delcol <n>. acme serves no
column files, and the docs say so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
|
|
The editor's loop was the only thing that could answer a 9P request, which
made the editor's own syscalls through a mount of its own tree -- a Look at
/mnt/9p/pardes/<me>/anything under a `9ns --mntgen` view, a Save into it --
requests only the blocked loop could serve. The name-based refusal that
followed (ownMountSuffix) and the in-process routing of a mount of oneself
(Client.sameSession) were patches over that, and both are gone, with the
mailbox that shipped every request to the editor's thread.
One rule replaces them, `pardes.turn`: the core is single-threaded, the
editor's thread has the turn by default and gives it up in two kinds of gap
-- while it waits for input and while a step of it is out in a host syscall
-- and a cloud9 connection task takes it in those gaps to answer. `out`
counts the steps that are out, from any thread: while one is, the core reads
consistently but that step still holds pointers into it, so a request that
would change a pane (a write, a truncation, an rmdir) is parked in the
engine and retried when the turn is next given up with nothing out, and the
editor's own wake waits for the count to reach zero. It is never a write of
its own that a step waits on out there -- writes come from a shell
performing a save between steps -- so a parked request is never the
syscall's own, and making a pane or rendering a screen need not park:
every yield sits before its step's mutation, so the layout and the surface
are whole under it. A changing request that queued effects is answered
once the editor has performed them (`echo Save > exec` returns with the
file written, as acme's `put` does), and it settles the way a step does,
because without that a /log reader waited for the user's next keystroke.
Every host syscall on a user path has to give the turn up, not fs.zig's
alone: the first end-to-end run hung in `inotify_add_watch` performing the
new pane's watch effect. PDFs and images are read whole at open, so no
draw goes out into the host. The core's allocator takes its fixed buffer
through the lock-free interface, since a connection task allocates while
the editor's thread is out in a syscall that allocates too. A Restore puts
the replacement in first and releases every task waiting on the old core.
cloud9 (pinned at eb1a104) parks an open, a truncating wstat, a clunk and a
remove on `again`, not only reads and writes, and answers a parked job
whose fid was clunked without asking the backend.
Verified: test/selfmount.py runs the editor under `9ns --mntgen` and
Looks at, reads and Saves its own tree through the mount; a unit test pins
that a change parks while the editor is out mid-step and lands when it
rests, while a read is answered in the window. 9P over the Unix socket
against a tty session, same machine, Debug builds: a read of /index 278us
-> 61us, a truncating body write 1184us -> 609us, exec Save 718us -> 583us;
the gesture benchmark is unchanged (geometric mean 0.997 over 53 cells).
Also from the reviews: a notice chip over an image or PDF pane was painted
out by the picture drawn after the cells, so pictures give up the rows; in
the GUI a tree-sitter context band painted over the chip, so body layers
are emitted first; a message is one row of printable text, its 256-byte
cut never leaves half a glyph, and one wider than its pane keeps its tail
(the file name, the reason) rather than its head.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|