Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jacobsa-fuse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
jacobsa-fuse
Commits
10b71ca5
Commit
10b71ca5
authored
Jun 25, 2015
by
Aaron Jacobs
Browse files
Options
Browse Files
Download
Plain Diff
Simplified memfs locking.
parents
bb3046cd
c7c0b23b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
15 additions
and
51 deletions
+15
-51
samples/memfs/inode.go
samples/memfs/inode.go
+4
-19
samples/memfs/memfs.go
samples/memfs/memfs.go
+11
-32
No files found.
samples/memfs/inode.go
View file @
10b71ca5
...
...
@@ -22,11 +22,12 @@ import (
"github.com/jacobsa/fuse/fuseops"
"github.com/jacobsa/fuse/fuseutil"
"github.com/jacobsa/syncutil"
"github.com/jacobsa/timeutil"
)
// Common attributes for files and directories.
//
// External synchronization is required.
type
inode
struct
{
/////////////////////////
// Dependencies
...
...
@@ -38,8 +39,6 @@ type inode struct {
// Mutable state
/////////////////////////
mu
syncutil
.
InvariantMutex
// The current attributes of this inode.
//
// INVARIANT: attrs.Mode &^ (os.ModePerm|os.ModeDir|os.ModeSymlink) == 0
...
...
@@ -93,11 +92,10 @@ func newInode(
attrs
:
attrs
,
}
in
.
mu
=
syncutil
.
NewInvariantMutex
(
in
.
checkInvariants
)
return
}
func
(
in
*
inode
)
c
heckInvariants
()
{
func
(
in
*
inode
)
C
heckInvariants
()
{
// INVARIANT: attrs.Mode &^ (os.ModePerm|os.ModeDir|os.ModeSymlink) == 0
if
!
(
in
.
attrs
.
Mode
&^
(
os
.
ModePerm
|
os
.
ModeDir
|
os
.
ModeSymlink
)
==
0
)
{
panic
(
fmt
.
Sprintf
(
"Unexpected mode: %v"
,
in
.
attrs
.
Mode
))
...
...
@@ -153,25 +151,21 @@ func (in *inode) checkInvariants() {
return
}
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
isDir
()
bool
{
return
in
.
attrs
.
Mode
&
os
.
ModeDir
!=
0
}
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
isSymlink
()
bool
{
return
in
.
attrs
.
Mode
&
os
.
ModeSymlink
!=
0
}
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
isFile
()
bool
{
return
!
(
in
.
isDir
()
||
in
.
isSymlink
())
}
// Return the index of the child within in.entries, if it exists.
//
// REQUIRES: in.dir
// LOCKS_REQUIRED(in.mu)
// REQUIRES: in.isDir()
func
(
in
*
inode
)
findChild
(
name
string
)
(
i
int
,
ok
bool
)
{
if
!
in
.
isDir
()
{
panic
(
"findChild called on non-directory."
)
...
...
@@ -195,7 +189,6 @@ func (in *inode) findChild(name string) (i int, ok bool) {
// Return the number of children of the directory.
//
// REQUIRES: in.isDir()
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
Len
()
(
n
int
)
{
for
_
,
e
:=
range
in
.
entries
{
if
e
.
Type
!=
fuseutil
.
DT_Unknown
{
...
...
@@ -209,7 +202,6 @@ func (in *inode) Len() (n int) {
// Find an entry for the given child name and return its inode ID.
//
// REQUIRES: in.isDir()
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
LookUpChild
(
name
string
)
(
id
fuseops
.
InodeID
,
ok
bool
)
{
index
,
ok
:=
in
.
findChild
(
name
)
if
ok
{
...
...
@@ -223,7 +215,6 @@ func (in *inode) LookUpChild(name string) (id fuseops.InodeID, ok bool) {
//
// REQUIRES: in.isDir()
// REQUIRES: dt != fuseutil.DT_Unknown
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
AddChild
(
id
fuseops
.
InodeID
,
name
string
,
...
...
@@ -263,7 +254,6 @@ func (in *inode) AddChild(
//
// REQUIRES: in.isDir()
// REQUIRES: An entry for the given name exists.
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
RemoveChild
(
name
string
)
{
// Update the modification time.
in
.
attrs
.
Mtime
=
in
.
clock
.
Now
()
...
...
@@ -284,7 +274,6 @@ func (in *inode) RemoveChild(name string) {
// Serve a ReadDir request.
//
// REQUIRES: in.isDir()
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
ReadDir
(
offset
int
,
size
int
)
(
data
[]
byte
,
err
error
)
{
if
!
in
.
isDir
()
{
panic
(
"ReadDir called on non-directory."
)
...
...
@@ -313,7 +302,6 @@ func (in *inode) ReadDir(offset int, size int) (data []byte, err error) {
// Read from the file's contents. See documentation for ioutil.ReaderAt.
//
// REQUIRES: in.isFile()
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
ReadAt
(
p
[]
byte
,
off
int64
)
(
n
int
,
err
error
)
{
if
!
in
.
isFile
()
{
panic
(
"ReadAt called on non-file."
)
...
...
@@ -337,7 +325,6 @@ func (in *inode) ReadAt(p []byte, off int64) (n int, err error) {
// Write to the file's contents. See documentation for ioutil.WriterAt.
//
// REQUIRES: in.isFile()
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
WriteAt
(
p
[]
byte
,
off
int64
)
(
n
int
,
err
error
)
{
if
!
in
.
isFile
()
{
panic
(
"WriteAt called on non-file."
)
...
...
@@ -366,8 +353,6 @@ func (in *inode) WriteAt(p []byte, off int64) (n int, err error) {
}
// Update attributes from non-nil parameters.
//
// LOCKS_REQUIRED(in.mu)
func
(
in
*
inode
)
SetAttributes
(
size
*
uint64
,
mode
*
os
.
FileMode
,
...
...
samples/memfs/memfs.go
View file @
10b71ca5
...
...
@@ -40,13 +40,13 @@ type memFS struct {
// Mutable state
/////////////////////////
// When acquiring this lock, the caller must hold no inode locks.
mu
syncutil
.
InvariantMutex
// The collection of live inodes, indexed by ID. IDs of free inodes that may
// be re-used have nil entries. No ID less than fuseops.RootInodeID is ever
// used.
//
// INVARIANT: For each inode in, in.CheckInvariants() does not panic.
// INVARIANT: len(inodes) > fuseops.RootInodeID
// INVARIANT: For all i < fuseops.RootInodeID, inodes[i] == nil
// INVARIANT: inodes[fuseops.RootInodeID] != nil
...
...
@@ -132,33 +132,32 @@ func (fs *memFS) checkInvariants() {
panic
(
fmt
.
Sprintf
(
"Unexected free inode ID: %v"
,
id
))
}
}
// INVARIANT: For each inode in, in.CheckInvariants() does not panic.
for
_
,
in
:=
range
fs
.
inodes
{
in
.
CheckInvariants
()
}
}
// Find the given inode and return it with its lock held. Panic if it doesn't
// exist.
// Find the given inode. Panic if it doesn't exist.
//
// LOCKS_REQUIRED(fs.mu)
// LOCK_FUNCTION(inode.mu)
func
(
fs
*
memFS
)
getInodeOrDie
(
id
fuseops
.
InodeID
)
(
inode
*
inode
)
{
inode
=
fs
.
inodes
[
id
]
if
inode
==
nil
{
panic
(
fmt
.
Sprintf
(
"Unknown inode: %v"
,
id
))
}
inode
.
mu
.
Lock
()
return
}
// Allocate a new inode, assigning it an ID that is not in use. Return it with
// its lock held.
// Allocate a new inode, assigning it an ID that is not in use.
//
// EXCLUSIVE_LOCKS_REQUIRED(fs.mu)
// EXCLUSIVE_LOCK_FUNCTION(inode.mu)
// LOCKS_REQUIRED(fs.mu)
func
(
fs
*
memFS
)
allocateInode
(
attrs
fuseops
.
InodeAttributes
)
(
id
fuseops
.
InodeID
,
inode
*
inode
)
{
// Create
and lock
the inode.
// Create the inode.
inode
=
newInode
(
fs
.
clock
,
attrs
)
inode
.
mu
.
Lock
()
// Re-use a free ID if possible. Otherwise mint a new one.
numFree
:=
len
(
fs
.
freeInodes
)
...
...
@@ -174,7 +173,7 @@ func (fs *memFS) allocateInode(
return
}
//
EXCLUSIVE_
LOCKS_REQUIRED(fs.mu)
// LOCKS_REQUIRED(fs.mu)
func
(
fs
*
memFS
)
deallocateInode
(
id
fuseops
.
InodeID
)
{
fs
.
freeInodes
=
append
(
fs
.
freeInodes
,
id
)
fs
.
inodes
[
id
]
=
nil
...
...
@@ -191,7 +190,6 @@ func (fs *memFS) LookUpInode(
// Grab the parent directory.
inode
:=
fs
.
getInodeOrDie
(
op
.
Parent
)
defer
inode
.
mu
.
Unlock
()
// Does the directory have an entry with the given name?
childID
,
ok
:=
inode
.
LookUpChild
(
op
.
Name
)
...
...
@@ -202,7 +200,6 @@ func (fs *memFS) LookUpInode(
// Grab the child.
child
:=
fs
.
getInodeOrDie
(
childID
)
defer
child
.
mu
.
Unlock
()
// Fill in the response.
op
.
Entry
.
Child
=
childID
...
...
@@ -223,7 +220,6 @@ func (fs *memFS) GetInodeAttributes(
// Grab the inode.
inode
:=
fs
.
getInodeOrDie
(
op
.
Inode
)
defer
inode
.
mu
.
Unlock
()
// Fill in the response.
op
.
Attributes
=
inode
.
attrs
...
...
@@ -242,7 +238,6 @@ func (fs *memFS) SetInodeAttributes(
// Grab the inode.
inode
:=
fs
.
getInodeOrDie
(
op
.
Inode
)
defer
inode
.
mu
.
Unlock
()
// Handle the request.
inode
.
SetAttributes
(
op
.
Size
,
op
.
Mode
,
op
.
Mtime
)
...
...
@@ -264,7 +259,6 @@ func (fs *memFS) MkDir(
// Grab the parent, which we will update shortly.
parent
:=
fs
.
getInodeOrDie
(
op
.
Parent
)
defer
parent
.
mu
.
Unlock
()
// Ensure that the name doesn't already exist, so we don't wind up with a
// duplicate.
...
...
@@ -285,7 +279,6 @@ func (fs *memFS) MkDir(
// Allocate a child.
childID
,
child
:=
fs
.
allocateInode
(
childAttrs
)
defer
child
.
mu
.
Unlock
()
// Add an entry in the parent.
parent
.
AddChild
(
childID
,
op
.
Name
,
fuseutil
.
DT_Directory
)
...
...
@@ -309,7 +302,6 @@ func (fs *memFS) CreateFile(
// Grab the parent, which we will update shortly.
parent
:=
fs
.
getInodeOrDie
(
op
.
Parent
)
defer
parent
.
mu
.
Unlock
()
// Ensure that the name doesn't already exist, so we don't wind up with a
// duplicate.
...
...
@@ -335,7 +327,6 @@ func (fs *memFS) CreateFile(
// Allocate a child.
childID
,
child
:=
fs
.
allocateInode
(
childAttrs
)
defer
child
.
mu
.
Unlock
()
// Add an entry in the parent.
parent
.
AddChild
(
childID
,
op
.
Name
,
fuseutil
.
DT_File
)
...
...
@@ -361,7 +352,6 @@ func (fs *memFS) CreateSymlink(
// Grab the parent, which we will update shortly.
parent
:=
fs
.
getInodeOrDie
(
op
.
Parent
)
defer
parent
.
mu
.
Unlock
()
// Ensure that the name doesn't already exist, so we don't wind up with a
// duplicate.
...
...
@@ -387,7 +377,6 @@ func (fs *memFS) CreateSymlink(
// Allocate a child.
childID
,
child
:=
fs
.
allocateInode
(
childAttrs
)
defer
child
.
mu
.
Unlock
()
// Set up its target.
child
.
target
=
op
.
Target
...
...
@@ -414,7 +403,6 @@ func (fs *memFS) RmDir(
// Grab the parent, which we will update shortly.
parent
:=
fs
.
getInodeOrDie
(
op
.
Parent
)
defer
parent
.
mu
.
Unlock
()
// Find the child within the parent.
childID
,
ok
:=
parent
.
LookUpChild
(
op
.
Name
)
...
...
@@ -425,7 +413,6 @@ func (fs *memFS) RmDir(
// Grab the child.
child
:=
fs
.
getInodeOrDie
(
childID
)
defer
child
.
mu
.
Unlock
()
// Make sure the child is empty.
if
child
.
Len
()
!=
0
{
...
...
@@ -449,7 +436,6 @@ func (fs *memFS) Unlink(
// Grab the parent, which we will update shortly.
parent
:=
fs
.
getInodeOrDie
(
op
.
Parent
)
defer
parent
.
mu
.
Unlock
()
// Find the child within the parent.
childID
,
ok
:=
parent
.
LookUpChild
(
op
.
Name
)
...
...
@@ -460,7 +446,6 @@ func (fs *memFS) Unlink(
// Grab the child.
child
:=
fs
.
getInodeOrDie
(
childID
)
defer
child
.
mu
.
Unlock
()
// Remove the entry within the parent.
parent
.
RemoveChild
(
op
.
Name
)
...
...
@@ -480,7 +465,6 @@ func (fs *memFS) OpenDir(
// inode that doesn't exist, something screwed up earlier (a lookup, a
// cache invalidation, etc.).
inode
:=
fs
.
getInodeOrDie
(
op
.
Inode
)
defer
inode
.
mu
.
Unlock
()
if
!
inode
.
isDir
()
{
panic
(
"Found non-dir."
)
...
...
@@ -496,7 +480,6 @@ func (fs *memFS) ReadDir(
// Grab the directory.
inode
:=
fs
.
getInodeOrDie
(
op
.
Inode
)
defer
inode
.
mu
.
Unlock
()
// Serve the request.
op
.
Data
,
err
=
inode
.
ReadDir
(
int
(
op
.
Offset
),
op
.
Size
)
...
...
@@ -517,7 +500,6 @@ func (fs *memFS) OpenFile(
// inode that doesn't exist, something screwed up earlier (a lookup, a
// cache invalidation, etc.).
inode
:=
fs
.
getInodeOrDie
(
op
.
Inode
)
defer
inode
.
mu
.
Unlock
()
if
!
inode
.
isFile
()
{
panic
(
"Found non-file."
)
...
...
@@ -533,7 +515,6 @@ func (fs *memFS) ReadFile(
// Find the inode in question.
inode
:=
fs
.
getInodeOrDie
(
op
.
Inode
)
defer
inode
.
mu
.
Unlock
()
// Serve the request.
op
.
Data
=
make
([]
byte
,
op
.
Size
)
...
...
@@ -555,7 +536,6 @@ func (fs *memFS) WriteFile(
// Find the inode in question.
inode
:=
fs
.
getInodeOrDie
(
op
.
Inode
)
defer
inode
.
mu
.
Unlock
()
// Serve the request.
_
,
err
=
inode
.
WriteAt
(
op
.
Data
,
op
.
Offset
)
...
...
@@ -570,7 +550,6 @@ func (fs *memFS) ReadSymlink(
// Find the inode in question.
inode
:=
fs
.
getInodeOrDie
(
op
.
Inode
)
defer
inode
.
mu
.
Unlock
()
// Serve the request.
op
.
Target
=
inode
.
target
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment