-
Notifications
You must be signed in to change notification settings - Fork 117
feat: Allow both vectored and non-vectored reads to coexist #183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| to.Dst = inMsg.GetFree(int(in.Size)) | ||
| } | ||
| // Use part of the incoming message storage as the read buffer. | ||
| to.Dst = inMsg.GetFree(int(in.Size)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this part of your change performance-neutral? Going by the comment, we’re now “allocating” (reserving?) more buffers.
cc @vitalif who contributed vectored read support back in 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be performance-neutral because inMsg.GetFree() doesn't actually allocate. It merely makes the free space that was already allocated in the incoming message available for use by the output message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. So let me confirm the facts to make sure we’re on the same page:
- Each buffer (
InMessage) isMaxWriteSize(1 MB) + one page (4096 bytes) in size. - When vectored read support is enabled, we currently stop using the 1 MB buffer.
- This means we’re “wasting” 1 MB of RAM, but only for read requests — write requests will fill that 1 MB.
Is that accurate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is correct.
mount_config.go
Outdated
| // Vectored read allows file systems to avoid memory copying overhead if | ||
| // the data is already in memory when they return it to FUSE. | ||
| // When turned on, ReadFileOp.Dst is always nil and the FS must return data | ||
| // being read from the file as a list of slices in ReadFileOp.Data. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we expand on this description a bit? The vectored read flags is a bit of a misnomer, it's actual meaning was "the file system allocates its own buffers when serving reads". Originally, op.Dst was set to the free space in the incoming message (since reads requests are small, and we always allocate MaxPages+1 for incoming message, there are MaxPages free pages in a read request). That unused space is made available to the file system as op.Dst.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the comment.
Description:
This change modifies the FUSE connection to support both vectored and non-vectored reads within the same mounted filesystem.
Previously, vectored reads were controlled by the UseVectoredRead flag in
MountConfig. When enabled, the file system was expected to return data in ReadFileOp.Data, and ReadFileOp.Dst would be nil. This global setting made it difficult to support mixed read patterns efficiently.With this change:
This allows a file system to choose the appropriate read method on a per-read basis, enabling optimizations like zero-copy for buffered reads while still allowing direct reads for other cases.
This change is motivated by the need to implement zero-copy reads for the Buffered Reader in GCSFuse, without regressing the performance of the existing GCSReader.
More context in bug: https://b.corp.google.com/issues/458015680