diff --git a/file_system.go b/file_system.go index 506aec2..0588966 100644 --- a/file_system.go +++ b/file_system.go @@ -151,11 +151,40 @@ type FileSystem interface { req *OpenFileRequest) (*OpenFileResponse, error) // Read data from a file previously opened with CreateFile or OpenFile. + // + // Note that this method is not called for every call to read(2) by the end + // user; some reads may be served by the page cache. See notes on Write for + // more. ReadFile( ctx context.Context, req *ReadFileRequest) (*ReadFileResponse, error) // Write data to a file previously opened with CreateFile or OpenFile. + // + // When the user writes data using write(2), the write goes into the page + // cache and the page is marked dirty. Later the kernel may write back the + // page via the FUSE VFS layer, causing this method to be called: + // + // * The kernel calls address_space_operations::writepage when a dirty page + // needs to be written to backing store (see vfs.txt). Fuse sets this to + // fuse_writepage (see file.c). + // + // * fuse_writepage calls fuse_writepage_locked. + // + // * fuse_writepage_locked makes a write request to the userspace server. + // + // Note that writes *will* be received before a call to Flush when closing + // the file descriptor to which they were written: + // + // * fuse_flush calls write_inode_now, which appears to start a writeback + // in the background (it talks about a "flusher thread"). + // + // * fuse_flush then calls fuse_sync_writes, which "[waits] for all pending + // writepages on the inode to finish". + // + // * Only then does fuse_flush finally send the flush request. + // + // TODO(jacobsa): Add links for all of the references above. WriteFile( ctx context.Context, req *WriteFileRequest) (*WriteFileResponse, error)