From 8c9b8c09e6894eadc12d0fb8ac2832deaf1179f6 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Mon, 2 Mar 2015 15:35:12 +1100 Subject: [PATCH] Redeclared the inode struct. --- samples/memfs/inode.go | 63 ++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/samples/memfs/inode.go b/samples/memfs/inode.go index ce66cb7..82dade1 100644 --- a/samples/memfs/inode.go +++ b/samples/memfs/inode.go @@ -4,36 +4,57 @@ package memfs import ( - "fmt" - "reflect" - "github.com/jacobsa/fuse" + "github.com/jacobsa/fuse/fuseutil" + "github.com/jacobsa/gcloud/syncutil" ) // Common attributes for files and directories. // // TODO(jacobsa): Add tests for interacting with a file/directory after it has // been unlinked, including creating a new file. Make sure we don't screw up -// and reuse the inode while it is still in use. +// and reuse an inode ID while it is still in use. type inode struct { - // The *memFile or *memDir for this inode, or nil if the inode is available - // for reuse. + ///////////////////////// + // Constant data + ///////////////////////// + + // Is this a directory? If not, it is a file. + bool dir + + ///////////////////////// + // Mutable state + ///////////////////////// + + mu syncutil.InvariantMutex + + // The current attributes of this inode. // - // INVARIANT: impl is nil, or of type *memFile or *memDir - impl interface{} + // INVARIANT: No non-permission mode bits are set besides os.ModeDir + // INVARIANT: If dir, then os.ModeDir is set + // INVARIANT: If !dir, then os.ModeDir is not set + attributes fuse.InodeAttributes // GUARDED_BY(mu) + + // For directories, entries describing the children of the directory. + // + // This array can never be shortened, nor can its elements be moved, because + // we use its indices for Dirent.Offset, which is exposed to the user who + // might be calling readdir in a loop while concurrently modifying the + // directory. Unused entries can, however, be reused. + // + // TODO(jacobsa): Add good tests exercising concurrent modifications while + // doing readdir, seekdir, etc. calls. + // + // INVARIANT: If dir is false, this is nil. + // INVARIANT: For each i, entries[i].Offset == i+1 + entries []fuseutil.Dirent // GUARDED_BY(mu) + + // For files, the current contents of the file. + // + // INVARIANT: If dir is true, this is nil. + contents []byte // GUARDED_BY(mu) } -func (inode *inode) checkInvariants() { - switch inode.impl.(type) { - case nil: - case *memFile: - case *memDir: - default: - panic( - fmt.Sprintf("Unexpected inode impl type: %v", reflect.TypeOf(inode.impl))) - } -} +func newInode(dir bool) (inode *inode) -func (inode *inode) Attributes() fuse.InodeAttributes { - return fuse.InodeAttributes{} -} +func (inode *inode) checkInvariants()