Carved up FileSystem.

geesefs-0-30-9
Aaron Jacobs 2015-03-24 14:02:10 +11:00
parent 8e746f35b5
commit 386855c559
1 changed files with 223 additions and 253 deletions

View File

@ -23,60 +23,44 @@ import (
"time" "time"
"github.com/jacobsa/bazilfuse" "github.com/jacobsa/bazilfuse"
"golang.org/x/net/context"
) )
// An interface that must be implemented by file systems to be mounted with
// FUSE. See also the comments on request and response structs.
//
// Not all methods need to have interesting implementations. Embed a field of
// type fuseutil.NotImplementedFileSystem to inherit defaults that return
// ENOSYS to the kernel.
//
// Must be safe for concurrent access via all methods.
type FileSystem interface {
// This method is called once when mounting the file system. It must succeed // This method is called once when mounting the file system. It must succeed
// in order for the mount to succeed. // in order for the mount to succeed.
Init( type InitOp struct {
ctx context.Context, }
req *InitRequest) (*InitResponse, error)
/////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Inodes // Inodes
/////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Look up a child by name within a parent directory. The kernel calls this // Look up a child by name within a parent directory. The kernel calls this
// when resolving user paths to dentry structs, which are then cached. // when resolving user paths to dentry structs, which are then cached.
LookUpInode( type LookUpInodeOp struct {
ctx context.Context, }
req *LookUpInodeRequest) (*LookUpInodeResponse, error)
// Refresh the attributes for an inode whose ID was previously returned by // Refresh the attributes for an inode whose ID was previously returned by
// LookUpInode. The kernel calls this when the FUSE VFS layer's cache of // LookUpInode. The kernel calls this when the FUSE VFS layer's cache of
// inode attributes is stale. This is controlled by the AttributesExpiration // inode attributes is stale. This is controlled by the AttributesExpiration
// field of responses to LookUp, etc. // field of responses to LookUp, etc.
GetInodeAttributes( type GetInodeAttributesOp struct {
ctx context.Context, }
req *GetInodeAttributesRequest) (*GetInodeAttributesResponse, error)
// Change attributes for an inode. // Change attributes for an inode.
// //
// The kernel calls this for obvious cases like chmod(2), and for less // The kernel calls this for obvious cases like chmod(2), and for less
// obvious cases like ftrunctate(2). // obvious cases like ftrunctate(2).
SetInodeAttributes( type SetInodeAttributesOp struct {
ctx context.Context, }
req *SetInodeAttributesRequest) (*SetInodeAttributesResponse, error)
// Forget an inode ID previously issued (e.g. by LookUpInode or MkDir). The // Forget an inode ID previously issued (e.g. by LookUpInode or MkDir). The
// kernel calls this when removing an inode from its internal caches. // kernel calls this when removing an inode from its internal caches.
ForgetInode( type ForgetInodeOp struct {
ctx context.Context, }
req *ForgetInodeRequest) (*ForgetInodeResponse, error)
/////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Inode creation // Inode creation
/////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Create a directory inode as a child of an existing directory inode. The // Create a directory inode as a child of an existing directory inode. The
// kernel sends this in response to a mkdir(2) call. // kernel sends this in response to a mkdir(2) call.
@ -85,9 +69,8 @@ type FileSystem interface {
// mkdirat calls user_path_create calls filename_create, which verifies: // mkdirat calls user_path_create calls filename_create, which verifies:
// http://goo.gl/FZpLu5). But volatile file systems and paranoid non-volatile // http://goo.gl/FZpLu5). But volatile file systems and paranoid non-volatile
// file systems should check for the reasons described below on CreateFile. // file systems should check for the reasons described below on CreateFile.
MkDir( type MkDirOp struct {
ctx context.Context, }
req *MkDirRequest) (*MkDirResponse, error)
// Create a file inode and open it. // Create a file inode and open it.
// //
@ -102,13 +85,12 @@ type FileSystem interface {
// check themselves, returning EEXIST when the file already exists. This of // check themselves, returning EEXIST when the file already exists. This of
// course particularly applies to file systems that are volatile from the // course particularly applies to file systems that are volatile from the
// kernel's point of view. // kernel's point of view.
CreateFile( type CreateFileOp struct {
ctx context.Context, }
req *CreateFileRequest) (*CreateFileResponse, error)
/////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Inode destruction // Unlinking
/////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Unlink a directory from its parent. Because directories cannot have a link // Unlink a directory from its parent. Because directories cannot have a link
// count above one, this means the directory inode should be deleted as well // count above one, this means the directory inode should be deleted as well
@ -117,22 +99,20 @@ type FileSystem interface {
// The file system is responsible for checking that the directory is empty. // The file system is responsible for checking that the directory is empty.
// //
// Sample implementation in ext2: ext2_rmdir (http://goo.gl/B9QmFf) // Sample implementation in ext2: ext2_rmdir (http://goo.gl/B9QmFf)
RmDir( type RmDirOp struct {
ctx context.Context, }
req *RmDirRequest) (*RmDirResponse, error)
// Unlink a file from its parent. If this brings the inode's link count to // Unlink a file from its parent. If this brings the inode's link count to
// zero, the inode should be deleted once the kernel calls ForgetInode. It // zero, the inode should be deleted once the kernel calls ForgetInode. It
// may still be referenced before then if a user still has the file open. // may still be referenced before then if a user still has the file open.
// //
// Sample implementation in ext2: ext2_unlink (http://goo.gl/hY6r6C) // Sample implementation in ext2: ext2_unlink (http://goo.gl/hY6r6C)
Unlink( type UnlinkOp struct {
ctx context.Context, }
req *UnlinkRequest) (*UnlinkResponse, error)
/////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Directory handles // Directory handles
/////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Open a directory inode. // Open a directory inode.
// //
@ -140,14 +120,12 @@ type FileSystem interface {
// particular inode with type directory, usually in response to an open(2) // particular inode with type directory, usually in response to an open(2)
// call from a user-space process. On OS X it may not be called for every // call from a user-space process. On OS X it may not be called for every
// open(2) (cf. https://github.com/osxfuse/osxfuse/issues/199). // open(2) (cf. https://github.com/osxfuse/osxfuse/issues/199).
OpenDir( type OpenDirOp struct {
ctx context.Context, }
req *OpenDirRequest) (*OpenDirResponse, error)
// Read entries from a directory previously opened with OpenDir. // Read entries from a directory previously opened with OpenDir.
ReadDir( type ReadDirOp struct {
ctx context.Context, }
req *ReadDirRequest) (*ReadDirResponse, error)
// Release a previously-minted directory handle. The kernel calls this when // Release a previously-minted directory handle. The kernel calls this when
// there are no more references to an open directory: all file descriptors // there are no more references to an open directory: all file descriptors
@ -155,13 +133,12 @@ type FileSystem interface {
// //
// The kernel guarantees that the handle ID will not be used in further calls // The kernel guarantees that the handle ID will not be used in further calls
// to the file system (unless it is reissued by the file system). // to the file system (unless it is reissued by the file system).
ReleaseDirHandle( type ReleaseDirHandleOp struct {
ctx context.Context, }
req *ReleaseDirHandleRequest) (*ReleaseDirHandleResponse, error)
/////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// File handles // File handles
/////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Open a file inode. // Open a file inode.
// //
@ -169,18 +146,16 @@ type FileSystem interface {
// particular inode with type file, usually in response to an open(2) call // particular inode with type file, usually in response to an open(2) call
// from a user-space process. On OS X it may not be called for every open(2) // from a user-space process. On OS X it may not be called for every open(2)
// (cf.https://github.com/osxfuse/osxfuse/issues/199). // (cf.https://github.com/osxfuse/osxfuse/issues/199).
OpenFile( type OpenFileOp struct {
ctx context.Context, }
req *OpenFileRequest) (*OpenFileResponse, error)
// Read data from a file previously opened with CreateFile or OpenFile. // 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 // 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 // user; some reads may be served by the page cache. See notes on Write for
// more. // more.
ReadFile( type ReadFileOp struct {
ctx context.Context, }
req *ReadFileRequest) (*ReadFileResponse, error)
// Write data to a file previously opened with CreateFile or OpenFile. // Write data to a file previously opened with CreateFile or OpenFile.
// //
@ -210,9 +185,8 @@ type FileSystem interface {
// * (http://goo.gl/zzvxWv) Only then does fuse_flush finally send the // * (http://goo.gl/zzvxWv) Only then does fuse_flush finally send the
// flush request. // flush request.
// //
WriteFile( type WriteFileOp struct {
ctx context.Context, }
req *WriteFileRequest) (*WriteFileResponse, error)
// Synchronize the current contents of an open file to storage. // Synchronize the current contents of an open file to storage.
// //
@ -230,9 +204,8 @@ type FileSystem interface {
// //
// See also: FlushFile, which may perform a similar purpose when closing a // See also: FlushFile, which may perform a similar purpose when closing a
// file (but which is not used in "real" file systems). // file (but which is not used in "real" file systems).
SyncFile( type SyncFileOp struct {
ctx context.Context, }
req *SyncFileRequest) (*SyncFileResponse, error)
// Flush the current state of an open file to storage upon closing a file // Flush the current state of an open file to storage upon closing a file
// descriptor. // descriptor.
@ -282,9 +255,8 @@ type FileSystem interface {
// data. A file system that writes to remote storage however probably wants // data. A file system that writes to remote storage however probably wants
// to at least schedule a real flush, and maybe do it immediately in order to // to at least schedule a real flush, and maybe do it immediately in order to
// return any errors that occur. // return any errors that occur.
FlushFile( type FlushFileOp struct {
ctx context.Context, }
req *FlushFileRequest) (*FlushFileResponse, error)
// Release a previously-minted file handle. The kernel calls this when there // Release a previously-minted file handle. The kernel calls this when there
// are no more references to an open file: all file descriptors are closed // are no more references to an open file: all file descriptors are closed
@ -292,9 +264,7 @@ type FileSystem interface {
// //
// The kernel guarantees that the handle ID will not be used in further calls // The kernel guarantees that the handle ID will not be used in further calls
// to the file system (unless it is reissued by the file system). // to the file system (unless it is reissued by the file system).
ReleaseFileHandle( type ReleaseFileHandleOp struct {
ctx context.Context,
req *ReleaseFileHandleRequest) (*ReleaseFileHandleResponse, error)
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////