NFS4 Lock Type
1. LOCK Operation Overview
NFSv4 introduces byte-range locking (record locking) as a stateful operation.
Each LOCK request specifies:
Which file (via PUTFH)
The region (offset, length)
The lock type (read vs. write)
The owner (clientid + lock owner)
Whether this is a new lock owner
Whether this is a reclaim (during recovery)
2. Lock Type Field
In the NFSv4 protocol (RFC 8881, Section 18), the field is defined as:
enum nfs_lock_type4 {
READ_LT = 1, /* Read (shared) lock */
WRITE_LT = 2, /* Write (exclusive) lock */
READW_LT = 3, /* Blocking read lock request */
WRITEW_LT = 4 /* Blocking write lock request */
};
3. Lock Type Meanings
| Lock Type | Constant | Meaning | Blocking Behavior |
| ------------- | -------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| **READ_LT** | `1` | Request a **shared** lock (read lock). Other READ locks can coexist, but WRITE locks conflict. | **Non-blocking** — if conflict exists, returns `NFS4ERR_DENIED`. |
| **WRITE_LT** | `2` | Request an **exclusive** lock (write lock). No other locks (read or write) can overlap. | **Non-blocking** — if conflict exists, returns `NFS4ERR_DENIED`. |
| **READW_LT** | `3` | Same as READ_LT, but client is willing to **wait** (block) until lock becomes available. | **Blocking** — server delays reply until lock is free or timeout. |
| **WRITEW_LT** | `4` | Same as WRITE_LT, but **waits** if conflict. | **Blocking** — server queues request until lock can be granted. |
4. READ vs. WRITE Lock Behavior
| Property | READ_LT | WRITE_LT |
| -------------------------- | ------------------- | ---------------------- |
| Multiple holders allowed? | ✅ Yes (shared) | ❌ No (exclusive) |
| Conflicts with WRITE lock? | ✅ Yes | ✅ Yes |
| Conflicts with READ lock? | ❌ No | ✅ Yes |
| Example use | Reader coordination | File update protection |
So:
READ_LT → multiple readers, no writers
WRITE_LT → single writer, no readers or writers
5. Blocking vs. Non-blocking Locks
Normally, NFSv4 locks are non-blocking:
If another client holds a conflicting lock, the server immediately replies:
NFS4ERR_DENIED
The client can retry later.
If the client uses READW_LT or WRITEW_LT, it asks the server to wait until the lock is available.
� However, not all NFS servers implement blocking locks, so many simply treat READW_LT/WRITEW_LT the same as READ_LT/WRITE_LT and return NFS4ERR_DENIED.
6. Example Wireshark View
Client → Server (WRITE lock)
NFS COMPOUND: LOCK
Type: WRITE (2)
Offset: 0
Length: 100
New Lock Owner: TRUE
Lock seqid: 1
Server → Client
NFS COMPOUND REPLY: LOCK → NFS4_OK
stateid: { seqid=1, other=0xabcdef1234567890 }
7. Lock Conflict Example
If another client tries to lock the same range:
NFS COMPOUND: LOCK (WRITE)
Offset: 0
Length: 100
Server reply:
NFS COMPOUND REPLY: LOCK → NFS4ERR_DENIED
conflicting_lock:
type: WRITE
offset: 0
length: 100
owner: clientid=0xaabbccdd
8. Summary Table
| Type | Value | Description | Shared? | Blocking? |
| ------------- | ----- | ---------------------------------- | ------- | --------- |
| **READ_LT** | `1` | Read (shared) lock | ✅ Yes | ❌ No |
| **WRITE_LT** | `2` | Write (exclusive) lock | ❌ No | ❌ No |
| **READW_LT** | `3` | Read (shared), wait if blocked | ✅ Yes | ✅ Yes |
| **WRITEW_LT** | `4` | Write (exclusive), wait if blocked | ❌ No | ✅ Yes |
In NFSv4:
READ_LT and WRITE_LT are non-blocking advisory locks.
READW_LT and WRITEW_LT are blocking versions (server may queue them).
WRITE_LT = exclusive, READ_LT = shared.
All are advisory, not mandatory.