Summary
- RFC 1094 says a stateless NFS server cannot reproduce an operating system’s open-but-unlinked file behavior, because the server does not keep the per-client open state that behavior needs.
- The 1989 memo leaves a client-side workaround: rename the file when the user removes it, then remove the renamed entry when the open ends. The document specifies the gap and an idea, not a universal implementation or its crash-cleanup policy.
The name disappeared before the process was finished
A process opens a file, reads several pages and keeps working. A second action removes the file’s name from its directory. On some local operating systems, that does not invalidate the process’s existing open reference. The name is gone from the namespace; the process can still reach the file until it closes the reference.
That distinction becomes awkward when the file lives on another machine. The application sees one mounted tree, but the server receives individual network procedures. Which machine knows that the file is still open? Which one may safely reclaim the data after its last directory entry is removed?
RFC 1094, the March 1989 specification for NFS version 2, answers with an architectural limit rather than a compatibility promise. It explains that some operating systems let a process remove an open file and continue reading or writing it. A stateless server cannot implement that behavior, the memo says. It offers a client-side trick: rename the file on removal and delete it only on close.
The line is easy to miss because NFS was designed to make remote files look accessible through a local filesystem interface. The interface could be familiar even when the remote protocol did not carry every local operation or state transition.
NFSv2 sent filesystem procedures, not a remote open session
The RPC program defined procedures such as LOOKUP, READ, WRITE, CREATE, REMOVE and RENAME. REMOVE takes a directory reference and a filename. The RPC interface has no NFSv2 OPEN or CLOSE procedure that tells the server, “this client now holds this file open,” followed later by, “the last open reference is gone.”
The client did pass server-issued file handles in file operations. That is a reference to an object, not a report of local process state. An OPEN call in the application could be handled by the local operating system and its NFS client without creating a matching remote open record. The server could receive a REMOVE for a name without knowing that a process on one client still expected the object to live.
This is the precise limit. RFC 1094 did not say that a client could never emulate open-after-unlink. It said a stateless server could not provide those semantics by itself. The memo placed the emulation at the side that knew about the process’s open reference.
Rename made a deletion wait
The proposed client trick changes the sequence. Instead of immediately removing the directory entry, the client can rename it to a temporary name. The open process continues to use its existing file reference; the local client remembers that the temporary entry must be removed when the open is closed. From the user’s namespace, the original name has disappeared. From the server’s namespace, an entry remains long enough to preserve the file.
That is not the same as deleting the data and hoping a handle keeps it alive. It leaves the server a name it can still represent, while placing the pending-cleanup decision with the client. The behavior that applications attribute to a single unlink therefore spans at least two actors and two times: namespace removal now, remote cleanup later.
RFC 1094 does not prescribe the temporary naming scheme, collision handling, crash recovery or how several clients should observe the intermediate entry. The rename passage is a suggested compatibility technique, not a complete transaction protocol. Any claim about a particular client’s implementation needs evidence from that implementation, not just the RFC.
The design also makes deletion less binary than a user interface suggests. The visible name may be absent while storage remains allocated. Conversely, a later cleanup may fail or be delayed without restoring the original name. Those are operational possibilities implied by deferred removal; RFC 1094 does not report their frequency or document a deployed incident.
“Stateless” described the protocol conversation
The RFC’s stateless-server goal was specific: a server should not need per-client protocol state to function correctly. After a server or network interruption, a client could retry rather than negotiate the reconstruction of an open session. The file system itself still had state: file contents, directory entries, attributes and storage all persisted according to their own rules.
Open-file lifetime was one of the places where local operating-system state did not fit inside that minimal server model. NFS could make many filesystem operations available remotely, but it did not make every local kernel convention part of the wire contract. File and record locking were also outside this RFC’s protocol and were implemented as separate services.
Later NFS designs made a different allocation. NFSv3 still exposes filesystem procedures without remote OPEN and CLOSE; NFSv4, described in RFC 7530, includes explicit open and close operations and stateids for protocol state. That later design does not make every client application or server interchangeable, and it does not prove that all NFS installations migrated. It shows that open state can be made part of a protocol when its coordination cost is accepted.
A compatibility promise has an owner
RFC 1094’s contribution here is the placement of responsibility. The server controls the exported directory and executes REMOVE. The client’s operating system knows whether a local process still has the file open. Without a remote open record, the server lacks the fact needed to decide when an unlinked object can be reclaimed. The client workaround connects those views by delaying the actual removal.
That connection is not free. A client may need a private naming convention, bookkeeping and cleanup behavior. An application that depends on open-after-unlink must know whether its client really preserves that behavior, rather than treating a mounted remote path as proof. A server administrator may need to understand why an entry remains after the visible name is gone. The RFC defines neither side’s operational policy in detail.
The point is not that the NFSv2 design was defective for failing to imitate every local filesystem. It deliberately kept the server protocol small and identified a semantic case where the client might need to adapt. The cost of that minimum was distributed: implementation freedom on the server, extra responsibility on the client, and a need to test the exact combination used by an application.
Sources and evidence boundary
- RFC 1094 — NFS: Network File System Protocol Specification, especially the stateless-server discussion and Section 3.1’s open-file and mount-boundary examples.
- RFC 1813 — NFS Version 3 Protocol Specification, for the later procedure interface.
- RFC 7530 — Network File System (NFS) Version 4 Protocol, for explicit open, close and stateid operations.
- RFC 2624 — NFS Version 4 Design Considerations, for the later design discussion of protocol state and client caching.
The RFCs establish specified interfaces and design reasoning. They do not show which operating systems used the rename workaround, how a named client cleaned it up after a crash, or how often users encountered the boundary.
Member Briefing
Deeper Profile Context
Sign in with the right membership level to unlock the full briefing and source notes.
Only for Strategic Circle
Strategic Circle
Open to all readers. Unlock profile briefings after joining and signing in.
Join Strategic CircleOnly for Leadership Alliance
Leadership Alliance
For qualified IP-asset owners and management; sign in to unlock alliance briefings.
Join Leadership Alliance
