| RFC-0156: Stream Append Mode | |
|---|---|
| Status | Accepted |
| Areas |
|
| Description | Add an append mode to streams. |
| Issues | |
| Gerrit change | |
| Authors | |
| Reviewers | |
| Date submitted (year-month-day) | 2022-04-06 |
| Date reviewed (year-month-day) | 2022-04-20 |
Summary
This RFC proposes modifying the stream API by adding an
append mode to streams and removing the append option from
zx_stream_writev.
Motivation
The stream append option, ZX_STREAM_APPEND, is currently only used in the C++
VFS for implementing fuchsia.io/File.Write for memfs. All of the memfs streams
live on the server side of the FIDL connection where the append mode of the
connection is known. Accessing the append mode to optionally pass
ZX_STREAM_APPEND to each zx_stream_writev call works for this specific
situation.
With the implementation of writeback for userspace pagers, streams can be sent to the client side of the FIDL connection to significantly increase IO performance. Moving streams to the client side, with the current stream API, will require fdio to keep track of the append mode of the connection.
Design
Overview
The goal of this design is to avoid keeping track of the append mode in fdio and bring the stream API more inline with POSIX.
The stream API is very similar to reading, writing, and seeking a file
in POSIX, with the exception of how appends are handled. In POSIX a file can be
opened in append mode by passing O_APPEND to open. All POSIX write calls
to a file in append mode behave similarly to zx_stream_writev with the
ZX_STREAM_APPEND option.
Adding an append mode to streams will avoid fdio storing the append mode and be
more inline with POSIX. With this addition, the ZX_STREAM_APPEND option for
zx_stream_writev is no longer necessary.
API Changes
This RFC consists of 3 API changes:
A new option for
zx_stream_createnamed,ZX_STREAM_MODE_APPEND, will be added. A stream created withZX_STREAM_MODE_APPENDwill be placed in append mode. Allzx_stream_writevcalls to a stream in append mode will behave as ifZX_STREAM_APPENDwas passed to thezx_stream_writevcall.A new property named
ZX_PROP_STREAM_MODE_APPENDwill be added. This property is necessary for fdio to implementfcntlwithF_SETFLandO_APPEND.ZX_PROP_STREAM_MODE_APPENDwill have a value type ofuint8_t.- Calling
zx_object_set_propertywithZX_PROP_STREAM_MODE_APPENDand a value of0will take a stream out of append mode. - Calling
zx_object_set_propertywithZX_PROP_STREAM_MODE_APPENDand any value other than0will put a stream into append mode. - For
zx_object_get_propertycalls withZX_PROP_STREAM_MODE_APPENDthe property will have a value of1if the stream is in append and a value of0if the stream is not in append mode.
The
ZX_STREAM_APPENDoption forzx_stream_writevwill be removed.
Implementation
This RFC will be implemented in 3 Gerrit changes:
Add
ZX_STREAM_MODE_APPENDandZX_PROP_STREAM_MODE_APPENDto the stream API.Migrate the C++ VFS from
ZX_STREAM_APPENDtoZX_STREAM_MODE_APPENDandZX_PROP_STREAM_MODE_APPENDRemove the
ZX_STREAM_APPENDoption from the stream API.
Performance
This proposal should have no performance impact.
Ergonomics
Storing the append mode inside of the stream brings the stream API inline with
fuchsia.io/Directory.Open and open which developers will already be familiar
with.
Security considerations
None.
Privacy considerations
None.
Testing
Core tests will be written to exercise the new API including tests with multiple threads.
The existing fs_test suite used by memfs already includes append related tests which should catch any potential regressions during the migration.
Documentation
The Zircon stream documentation will be updated with the changes to the API.
Drawbacks, alternatives, and unknowns
Alternative: Store the append mode in fdio
Store the append mode of the connection directly in fdio and use the stream API as is.
Storing the append mode in the stream is preferred because it matches how appends work in POSIX.
Alternative: Keep ZX_STREAM_APPEND for zx_stream_writev
Filesystems that support streams will typically implement
fuchsia.io/File.Read, Write, and Seek by dispatching the requests to a
stream internally. Each connection already keeps track of its append mode for
responding to GetFlags requests which makes using ZX_STREAM_APPEND with
zx_stream_writev convenient.
Removing ZX_STREAM_APPEND forces the filesystem to keep the append mode of the
connection and the append mode of the stream in sync, which is not difficult.
Reducing the API surface area and matching POSIX is preferred over keeping
ZX_STREAM_APPEND.
Prior art and references
zx_stream_create
with ZX_STREAM_MODE_APPEND is similar to
open
with O_APPEND from POSIX.
zx_object_set_property
with ZX_PROP_STREAM_MODE_APPEND is similar to
fcntl
with F_SETFL and O_APPEND from POSIX.