What is FREE_STATEID?
1. FREE_STATEID is an NFSv4 compound operation that allows a client to explicitly free a stateid (a handle representing an open, lock, or delegation).
Introduced in NFSv4.1 (RFC 5661).
It’s optional — the server can implement it but isn’t required to.
It’s part of the state cleanup mechanism that helps both client and server manage state resources efficiently.
2. Background: What is a stateid?
In NFSv4, whenever a client:
Opens a file (OPEN),
Locks a range (LOCK),
Or gets a delegation,
The server issues a stateid to represent that specific state.
Example
When you do:
OPEN -> returns stateid A
LOCK -> returns stateid B
Each stateid tracks that client’s claim on the file.
Normally, these are cleaned up automatically:
When you CLOSE an open,
When you LOCKU (unlock),
When the lease expires,
Or when the client does a DELEGRETURN.
But sometimes a client might have orphaned stateids — for instance:
After a recovery,
After cancelling pending I/O,
Or if the client just wants to proactively release server state.
That’s where FREE_STATEID comes in.
3. Purpose of FREE_STATEID
The goal of FREE_STATEID is to let the client explicitly tell the server:
“I’m done with this particular stateid — you can free any associated state.”
This helps:
Prevent accumulation of unused state on the server.
Simplify client recovery logic.
Speed up failover transitions.
4. Server Response
Returns NFS4_OK if successful.
Returns one of:
NFS4ERR_BAD_STATEID — invalid or expired stateid.
NFS4ERR_STALE_STATEID — stateid references state the server no longer knows.
NFS4ERR_BAD_STATEID — incorrect or mismatched generation.
NFS4ERR_INVAL — stateid type not eligible for freeing.
5. When to Use
| Use Case | Description |
| ---------------------- | ------------------------------------------------------------------------------------- |
| **Client cleanup** | Client releases lock/open/delegation that’s no longer needed before lease expiration. |
| **Recovery** | After reboot or crash, client finds an old stateid it doesn’t want to reclaim. |
| **Performance tuning** | Reduces server memory/state pressure in long-running sessions. |
6. Relation to Other Operations
| Operation | Cleans up | Implicitly or Explicitly? |
| ------------------ | ------------------ | ------------------------------ |
| `CLOSE` | File open stateid | Explicit |
| `LOCKU` | Lock stateid | Explicit |
| `DELEGRETURN` | Delegation stateid | Explicit |
| **`FREE_STATEID`** | Any stateid | **Explicit (general purpose)** |
7. Example Flow
Example NFSv4.1 sequence where client opens and then frees state:
1. SEQUENCE
PUTFH /data/file1
OPEN (open file RW)
--> returns stateid X
2. (client does I/O...)
3. SEQUENCE
PUTFH /data/file1
FREE_STATEID stateid=X
--> server frees stateid, returns NFS4_OK
8. After Freeing
The client must not use that stateid again.
It can re-lock later via a new LOCK request (which will create a new stateid).
If the client tries to use the old stateid again:
-> NFS4ERR_BAD_STATEID
9. Summary Table
| Step | Operation | Description | Server Result |
| ---- | ---------------------------- | ------------------------- | ------------------------ |
| 1 | `LOCK` | Acquire byte-range lock | `NFS4_OK` + lock stateid |
| 2 | `FREE_STATEID` | Client frees that stateid | `NFS4_OK` |
| 3 | (Optional) Use stateid again | Invalid | `NFS4ERR_BAD_STATEID` |