From 4cb6dd14969c13aec216ae6e185b8a2c4a82cde5 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Fri, 27 Feb 2015 10:43:01 +1100 Subject: [PATCH] Big braind dump about ReadDir. --- file_system.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/file_system.go b/file_system.go index afb355d..5c4f582 100644 --- a/file_system.go +++ b/file_system.go @@ -39,6 +39,11 @@ type FileSystem interface { ctx context.Context, req *OpenDirRequest) (*OpenDirResponse, error) + // XXX: Comments + ReadDir( + ctx context.Context, + req *ReadDirRequest) (*ReadDirResponse, error) + // Release a previously-minted handle. The kernel calls this when there are // no more references to an open file: all file descriptors are closed and // all memory mappings are unmapped. @@ -210,11 +215,76 @@ type OpenDirResponse struct { // using the same struct file in the kernel. In practice this usually means // follow-up calls using the file descriptor returned by open(2). // + // The handle may be supplied to the following methods: + // + // * ReadDir + // * ReleaseHandle + // // The file system must ensure this ID remains valid until a later call to // ReleaseHandle. Handle HandleID } +type ReadDirRequest struct { + // The directory inode that we are reading, and the handle previously + // returned by OpenDir when opening that inode. + Inode InodeID + Handle HandleID + + // The offset within the directory at which to read. + // + // Warning: this field is not necessarily a count of bytes. Its legal values + // are defined by the results returned in ReadDirResponse. See the notes + // below and the notes on that struct. + // + // In the Linux kernel this ultimately comes from file::f_pos, which starts + // at zero and is set by llseek and by the final consumed result returned by + // each call to ReadDir: + // + // * (http://goo.gl/2nWJPL) iterate_dir, which is called by getdents(2) and + // readdir(2), sets dir_context::pos to file::f_pos before calling + // f_op->iterate, and then does the opposite assignment afterward. + // + // * (http://goo.gl/rTQVSL) fuse_readdir, which implements iterate for fuse + // directories, passes dir_context::pos as the offset to fuse_read_fill, + // which passes it on to user-space. fuse_readdir later calls + // parse_dirfile with the same context. + // + // * (http://goo.gl/vU5ukv) For each returned result (except perhaps the + // last, which may be truncated by the page boundary), parse_dirfile + // updates dir_context::pos with fuse_dirent::off. + // + OpaqueOffset uint64 + + // The maximum number of bytes to return in ReadDirResponse.Data. + Size uint64 +} + +type ReadDirResponse struct { + // A buffer consisting of a sequence of FUSE directory entries in the format + // generated by fuse_add_direntry (http://goo.gl/qCcHCV), which is consumed + // by parse_dirfile (http://goo.gl/2WUmD2). Use TODO to generate this data. + // + // The buffer must not exceed the length specified in ReadDirRequest.Size. It + // is okay for the final entry to be truncated; parse_dirfile copes with this + // by ignoring the partial record. + + // XXX: Fields + // + // In Linux this corresponds to dirent::d_off, and in OS X it corresponds to + // dirent::d_seekoff. In the glibc implementation of the Posix interface + // discussed below, it corresponds to __dirstream::filepos + // (http://goo.gl/x15ISb). + // + // Warning: this field is not necessarily a count of bytes. It makes the most + // sense when looking at the Posix interface for reading directories: + // + // * (http://goo.gl/fQhbyn, http://goo.gl/ns1kDF) opendir initially causes + // filepos to be set to zero. + // + // This field makes most +} + type ReleaseHandleRequest struct { // The handle ID to be released. The kernel guarantees that this ID will not // be used in further calls to the file system (unless it is reissued by the