Simple memfs edits.

geesefs-0-30-9
Aaron Jacobs 2015-03-24 16:20:32 +11:00
parent fd7866ea8b
commit 05e62e432c
2 changed files with 35 additions and 32 deletions

View File

@ -20,16 +20,15 @@ import (
"os" "os"
"time" "time"
"github.com/googlecloudplatform/gcsfuse/timeutil"
"github.com/jacobsa/fuse" "github.com/jacobsa/fuse"
"github.com/jacobsa/fuse/fuseops"
"github.com/jacobsa/fuse/fuseutil" "github.com/jacobsa/fuse/fuseutil"
"github.com/jacobsa/gcloud/syncutil" "github.com/jacobsa/gcloud/syncutil"
"github.com/googlecloudplatform/gcsfuse/timeutil"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
type memFS struct { type memFS struct {
fuseutil.NotImplementedFileSystem
///////////////////////// /////////////////////////
// Dependencies // Dependencies
///////////////////////// /////////////////////////
@ -44,20 +43,21 @@ type memFS struct {
mu syncutil.InvariantMutex mu syncutil.InvariantMutex
// The collection of live inodes, indexed by ID. IDs of free inodes that may // The collection of live inodes, indexed by ID. IDs of free inodes that may
// be re-used have nil entries. No ID less than fuse.RootInodeID is ever used. // be re-used have nil entries. No ID less than fuseops.RootInodeID is ever
// used.
// //
// INVARIANT: len(inodes) > fuse.RootInodeID // INVARIANT: len(inodes) > fuseops.RootInodeID
// INVARIANT: For all i < fuse.RootInodeID, inodes[i] == nil // INVARIANT: For all i < fuseops.RootInodeID, inodes[i] == nil
// INVARIANT: inodes[fuse.RootInodeID] != nil // INVARIANT: inodes[fuseops.RootInodeID] != nil
// INVARIANT: inodes[fuse.RootInodeID].dir is true // INVARIANT: inodes[fuseops.RootInodeID].dir is true
inodes []*inode // GUARDED_BY(mu) inodes []*inode // GUARDED_BY(mu)
// A list of inode IDs within inodes available for reuse, not including the // A list of inode IDs within inodes available for reuse, not including the
// reserved IDs less than fuse.RootInodeID. // reserved IDs less than fuseops.RootInodeID.
// //
// INVARIANT: This is all and only indices i of 'inodes' such that i > // INVARIANT: This is all and only indices i of 'inodes' such that i >
// fuse.RootInodeID and inodes[i] == nil // fuseops.RootInodeID and inodes[i] == nil
freeInodes []fuse.InodeID // GUARDED_BY(mu) freeInodes []fuseops.InodeID // GUARDED_BY(mu)
} }
// Create a file system that stores data and metadata in memory. // Create a file system that stores data and metadata in memory.
@ -68,21 +68,21 @@ type memFS struct {
func NewMemFS( func NewMemFS(
uid uint32, uid uint32,
gid uint32, gid uint32,
clock timeutil.Clock) fuse.FileSystem { clock timeutil.Clock) fuse.Server {
// Set up the basic struct. // Set up the basic struct.
fs := &memFS{ fs := &memFS{
clock: clock, clock: clock,
inodes: make([]*inode, fuse.RootInodeID+1), inodes: make([]*inode, fuseops.RootInodeID+1),
} }
// Set up the root inode. // Set up the root inode.
rootAttrs := fuse.InodeAttributes{ rootAttrs := fuseops.InodeAttributes{
Mode: 0700 | os.ModeDir, Mode: 0700 | os.ModeDir,
Uid: uid, Uid: uid,
Gid: gid, Gid: gid,
} }
fs.inodes[fuse.RootInodeID] = newInode(clock, rootAttrs) fs.inodes[fuseops.RootInodeID] = newInode(clock, rootAttrs)
// Set up invariant checking. // Set up invariant checking.
fs.mu = syncutil.NewInvariantMutex(fs.checkInvariants) fs.mu = syncutil.NewInvariantMutex(fs.checkInvariants)
@ -94,25 +94,27 @@ func NewMemFS(
// Helpers // Helpers
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
func (fs *memFS) ServeOps(c *fuse.Connection)
func (fs *memFS) checkInvariants() { func (fs *memFS) checkInvariants() {
// Check reserved inodes. // Check reserved inodes.
for i := 0; i < fuse.RootInodeID; i++ { for i := 0; i < fuseops.RootInodeID; i++ {
if fs.inodes[i] != nil { if fs.inodes[i] != nil {
panic(fmt.Sprintf("Non-nil inode for ID: %v", i)) panic(fmt.Sprintf("Non-nil inode for ID: %v", i))
} }
} }
// Check the root inode. // Check the root inode.
if !fs.inodes[fuse.RootInodeID].dir { if !fs.inodes[fuseops.RootInodeID].dir {
panic("Expected root to be a directory.") panic("Expected root to be a directory.")
} }
// Build our own list of free IDs. // Build our own list of free IDs.
freeIDsEncountered := make(map[fuse.InodeID]struct{}) freeIDsEncountered := make(map[fuseops.InodeID]struct{})
for i := fuse.RootInodeID + 1; i < len(fs.inodes); i++ { for i := fuseops.RootInodeID + 1; i < len(fs.inodes); i++ {
inode := fs.inodes[i] inode := fs.inodes[i]
if inode == nil { if inode == nil {
freeIDsEncountered[fuse.InodeID(i)] = struct{}{} freeIDsEncountered[fuseops.InodeID(i)] = struct{}{}
continue continue
} }
} }
@ -138,7 +140,7 @@ func (fs *memFS) checkInvariants() {
// //
// SHARED_LOCKS_REQUIRED(fs.mu) // SHARED_LOCKS_REQUIRED(fs.mu)
// EXCLUSIVE_LOCK_FUNCTION(inode.mu) // EXCLUSIVE_LOCK_FUNCTION(inode.mu)
func (fs *memFS) getInodeForModifyingOrDie(id fuse.InodeID) (inode *inode) { func (fs *memFS) getInodeForModifyingOrDie(id fuseops.InodeID) (inode *inode) {
inode = fs.inodes[id] inode = fs.inodes[id]
if inode == nil { if inode == nil {
panic(fmt.Sprintf("Unknown inode: %v", id)) panic(fmt.Sprintf("Unknown inode: %v", id))
@ -153,7 +155,7 @@ func (fs *memFS) getInodeForModifyingOrDie(id fuse.InodeID) (inode *inode) {
// //
// SHARED_LOCKS_REQUIRED(fs.mu) // SHARED_LOCKS_REQUIRED(fs.mu)
// SHARED_LOCK_FUNCTION(inode.mu) // SHARED_LOCK_FUNCTION(inode.mu)
func (fs *memFS) getInodeForReadingOrDie(id fuse.InodeID) (inode *inode) { func (fs *memFS) getInodeForReadingOrDie(id fuseops.InodeID) (inode *inode) {
inode = fs.inodes[id] inode = fs.inodes[id]
if inode == nil { if inode == nil {
panic(fmt.Sprintf("Unknown inode: %v", id)) panic(fmt.Sprintf("Unknown inode: %v", id))
@ -169,7 +171,7 @@ func (fs *memFS) getInodeForReadingOrDie(id fuse.InodeID) (inode *inode) {
// EXCLUSIVE_LOCKS_REQUIRED(fs.mu) // EXCLUSIVE_LOCKS_REQUIRED(fs.mu)
// EXCLUSIVE_LOCK_FUNCTION(inode.mu) // EXCLUSIVE_LOCK_FUNCTION(inode.mu)
func (fs *memFS) allocateInode( func (fs *memFS) allocateInode(
attrs fuse.InodeAttributes) (id fuse.InodeID, inode *inode) { attrs fuseops.InodeAttributes) (id fuseops.InodeID, inode *inode) {
// Create and lock the inode. // Create and lock the inode.
inode = newInode(fs.clock, attrs) inode = newInode(fs.clock, attrs)
inode.mu.Lock() inode.mu.Lock()
@ -181,7 +183,7 @@ func (fs *memFS) allocateInode(
fs.freeInodes = fs.freeInodes[:numFree-1] fs.freeInodes = fs.freeInodes[:numFree-1]
fs.inodes[id] = inode fs.inodes[id] = inode
} else { } else {
id = fuse.InodeID(len(fs.inodes)) id = fuseops.InodeID(len(fs.inodes))
fs.inodes = append(fs.inodes, inode) fs.inodes = append(fs.inodes, inode)
} }
@ -189,7 +191,7 @@ func (fs *memFS) allocateInode(
} }
// EXCLUSIVE_LOCKS_REQUIRED(fs.mu) // EXCLUSIVE_LOCKS_REQUIRED(fs.mu)
func (fs *memFS) deallocateInode(id fuse.InodeID) { func (fs *memFS) deallocateInode(id fuseops.InodeID) {
fs.freeInodes = append(fs.freeInodes, id) fs.freeInodes = append(fs.freeInodes, id)
fs.inodes[id] = nil fs.inodes[id] = nil
} }
@ -304,7 +306,7 @@ func (fs *memFS) MkDir(
// Set up attributes from the child, using the credentials of the calling // Set up attributes from the child, using the credentials of the calling
// process as owner (matching inode_init_owner, cf. http://goo.gl/5qavg8). // process as owner (matching inode_init_owner, cf. http://goo.gl/5qavg8).
childAttrs := fuse.InodeAttributes{ childAttrs := fuseops.InodeAttributes{
Nlink: 1, Nlink: 1,
Mode: req.Mode, Mode: req.Mode,
Uid: req.Header.Uid, Uid: req.Header.Uid,
@ -345,7 +347,7 @@ func (fs *memFS) CreateFile(
// Set up attributes from the child, using the credentials of the calling // Set up attributes from the child, using the credentials of the calling
// process as owner (matching inode_init_owner, cf. http://goo.gl/5qavg8). // process as owner (matching inode_init_owner, cf. http://goo.gl/5qavg8).
now := fs.clock.Now() now := fs.clock.Now()
childAttrs := fuse.InodeAttributes{ childAttrs := fuseops.InodeAttributes{
Nlink: 1, Nlink: 1,
Mode: req.Mode, Mode: req.Mode,
Atime: now, Atime: now,

View File

@ -20,10 +20,11 @@ import (
"os" "os"
"time" "time"
"github.com/googlecloudplatform/gcsfuse/timeutil"
"github.com/jacobsa/fuse" "github.com/jacobsa/fuse"
"github.com/jacobsa/fuse/fuseops"
"github.com/jacobsa/fuse/fuseutil" "github.com/jacobsa/fuse/fuseutil"
"github.com/jacobsa/gcloud/syncutil" "github.com/jacobsa/gcloud/syncutil"
"github.com/googlecloudplatform/gcsfuse/timeutil"
) )
// Common attributes for files and directories. // Common attributes for files and directories.
@ -53,7 +54,7 @@ type inode struct {
// INVARIANT: If dir, then os.ModeDir is set // INVARIANT: If dir, then os.ModeDir is set
// INVARIANT: If !dir, then os.ModeDir is not set // INVARIANT: If !dir, then os.ModeDir is not set
// INVARIANT: attributes.Size == len(contents) // INVARIANT: attributes.Size == len(contents)
attributes fuse.InodeAttributes // GUARDED_BY(mu) attributes fuseops.InodeAttributes // GUARDED_BY(mu)
// For directories, entries describing the children of the directory. Unused // For directories, entries describing the children of the directory. Unused
// entries are of type DT_Unknown. // entries are of type DT_Unknown.
@ -82,7 +83,7 @@ type inode struct {
// time-related information (the inode object will take care of that). // time-related information (the inode object will take care of that).
func newInode( func newInode(
clock timeutil.Clock, clock timeutil.Clock,
attrs fuse.InodeAttributes) (in *inode) { attrs fuseops.InodeAttributes) (in *inode) {
// Update time info. // Update time info.
now := clock.Now() now := clock.Now()
attrs.Mtime = now attrs.Mtime = now
@ -195,7 +196,7 @@ func (inode *inode) Len() (n int) {
// //
// REQUIRES: inode.dir // REQUIRES: inode.dir
// SHARED_LOCKS_REQUIRED(inode.mu) // SHARED_LOCKS_REQUIRED(inode.mu)
func (inode *inode) LookUpChild(name string) (id fuse.InodeID, ok bool) { func (inode *inode) LookUpChild(name string) (id fuseops.InodeID, ok bool) {
index, ok := inode.findChild(name) index, ok := inode.findChild(name)
if ok { if ok {
id = inode.entries[index].Inode id = inode.entries[index].Inode
@ -210,7 +211,7 @@ func (inode *inode) LookUpChild(name string) (id fuse.InodeID, ok bool) {
// REQUIRES: dt != fuseutil.DT_Unknown // REQUIRES: dt != fuseutil.DT_Unknown
// EXCLUSIVE_LOCKS_REQUIRED(inode.mu) // EXCLUSIVE_LOCKS_REQUIRED(inode.mu)
func (inode *inode) AddChild( func (inode *inode) AddChild(
id fuse.InodeID, id fuseops.InodeID,
name string, name string,
dt fuseutil.DirentType) { dt fuseutil.DirentType) {
var index int var index int