fusego/samples/memfs/dir.go

67 lines
1.5 KiB
Go
Raw Normal View History

2015-02-27 08:32:01 +03:00
// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)
package memfs
import (
2015-03-02 06:44:16 +03:00
"fmt"
2015-02-27 08:32:01 +03:00
"github.com/jacobsa/fuse"
"github.com/jacobsa/fuse/fuseutil"
"github.com/jacobsa/gcloud/syncutil"
)
type memDir struct {
/////////////////////////
// Mutable state
/////////////////////////
mu syncutil.InvariantMutex
// The contents of the directory. An entry with inode zero is unused.
//
// 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.
2015-03-02 06:16:17 +03:00
//
// TODO(jacobsa): Add good tests exercising concurrent modifications while
// doing readdir, seekdir, etc. calls.
//
2015-03-02 06:44:16 +03:00
// INVARIANT: For each i, entries[i].Offset == i+1
2015-02-27 08:32:01 +03:00
entries []fuseutil.Dirent
}
2015-03-02 06:44:16 +03:00
func newDir() (d *memDir) {
d = &memDir{}
d.mu = syncutil.NewInvariantMutex(d.checkInvariants)
return
}
2015-03-02 06:44:16 +03:00
func (d *memDir) checkInvariants() {
for i, e := range d.entries {
if e.Offset != fuse.DirOffset(i+1) {
panic(fmt.Sprintf("Unexpected offset in entry: %v", e))
}
}
}
2015-03-02 07:18:23 +03:00
// Find the inode ID of the child with the given name.
//
// LOCKS_EXCLUDED(d.mu)
2015-03-02 07:19:20 +03:00
func (d *memDir) LookUpInode(name string) (id fuse.InodeID, ok bool) {
d.mu.RLock()
defer d.mu.RUnlock()
for _, e := range d.entries {
if e.Name == name {
ok = true
id = e.Inode
return
}
}
return
}