Subject: idea - atomic append for NFS writes

From: "Wittle, Mark" <[email-masked]>
Date: Thu, 15 Mar 2001 20:11:47 -0800

Why Atomic Append
-----------------
NFS server atomic append is intended to provide better
write append semantics than are currently available in NFS,
where the client must make his best guess as to the current
size of the file, and then issue a write request at that
offset, hoping that no intervening write from another source
changes the length of the file during the interim.

Atomic Append Proposal
----------------------
This proposal applies to the NFS WRITE operation.  The
proposal adds an additional "atomic_append" flag (or enum)
field to the struct WRITE4args.  If that flag is set, then
the "offset" argument field is ignored by the NFS server,
and the data is appended to the current end of the file. 
The NFS server is required to make these 2 events atomic:
   1. the determination of current end of the file value
   2. appending the write data at that file offset
The proposal also adds an additional "write_offset" field
to the struct WRITE4resok which returns the offset value
of the write operation. 

This feature should be required of the NFS server.  Without
a guarantee that all NFS servers will support atomic append,
NFS clients can not depend  on it, and therefore will
probably not implement use of it.

Rationale
---------
Currently, the NFS client can provide atomic append semantics
through the use of LOCK operations.  However, this approach
introduces significant overhead to a common i/o operation.

Alternatively, a LOCK, GETATTR, WRITE, and UNLOCK could be
grouped in a compound, and an additional server side state
variable could be created to pass the write offset value
from the GETATTR to the WRITE.  But unless this sequence
of operations automatically implied that a write append
operation was intented, a flag would be required to specify
this behavior.  If a flag is required, why not just have it
mean append directly. 

Without the write_offset value being returned, the NFS
client can not determine the file offset where the data
was written, and so can not place the data into a local
buffer cache at the correct file offset.  The client must
either invalidate that data from any local buffer cache and
the affected file attributes, or must include a subsequent
GETATTR operation in the compound.

Issues
------
Requiring the server to return the write_offset for all
write operations introduces performance overhead that is
unnecessary for many write operations.  On the other hand,
it is also somewhat undesirable to return different return
value types depending on whether the write operation
specified the append flag.  One alternative would be to
also return an append_flag specifying whether the returned
write_offset value is valid.

Finally, it may be undesirable for the client to perform
partial file attribute cache updates as a result of an
append operation.

---

From: Brent Callaghan <[email-masked]>
Date: Thu, 15 Mar 2001 22:46:05 -0800

"Wittle, Mark" wrote:
> field to the struct WRITE4args. 

Why bother with a flag.  Couldn't we just define the
maximum file offset value (all ones) as meaning the
current end of file ?

I'm not sure how this would be used by current clients.
They already have a "find end of file, write to that offset"
procedure above the NFS layer.

Assuming you've got some unconventional clients that don't
have this restriction, the worry is that two clients will
concurrently determine the current end of file and write
to it - one overwriting the other.  You could get pretty
close to atomic if you included a VERIFY op for the file
size prefixing the WRITE op.

	Brent