Commit ccac1138 authored by Aaron Jacobs's avatar Aaron Jacobs

Updated inode contents.

parent e9e97851
...@@ -34,13 +34,6 @@ type inode struct { ...@@ -34,13 +34,6 @@ type inode struct {
clock timeutil.Clock clock timeutil.Clock
/////////////////////////
// Constant data
/////////////////////////
// Is this a directory? If not, it is a file.
dir bool
///////////////////////// /////////////////////////
// Mutable state // Mutable state
///////////////////////// /////////////////////////
...@@ -49,11 +42,10 @@ type inode struct { ...@@ -49,11 +42,10 @@ type inode struct {
// The current attributes of this inode. // The current attributes of this inode.
// //
// INVARIANT: No non-permission mode bits are set besides os.ModeDir // INVARIANT: attrs.Mode &^ (os.ModePerm|os.ModeDir|os.ModeSymlink) == 0
// INVARIANT: If dir, then os.ModeDir is set // INVARIANT: !(isDir() && isSymlink())
// INVARIANT: If !dir, then os.ModeDir is not set // INVARIANT: attrs.Size == len(contents)
// INVARIANT: attributes.Size == len(contents) attrs fuseops.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.
...@@ -63,15 +55,22 @@ type inode struct { ...@@ -63,15 +55,22 @@ type inode struct {
// might be calling readdir in a loop while concurrently modifying the // might be calling readdir in a loop while concurrently modifying the
// directory. Unused entries can, however, be reused. // directory. Unused entries can, however, be reused.
// //
// INVARIANT: If dir is false, this is nil. // INVARIANT: If !isDir(), len(entries) == 0
// INVARIANT: For each i, entries[i].Offset == i+1 // INVARIANT: For each i, entries[i].Offset == i+1
// INVARIANT: Contains no duplicate names in used entries. // INVARIANT: Contains no duplicate names in used entries.
entries []fuseutil.Dirent // GUARDED_BY(mu) entries []fuseutil.Dirent // GUARDED_BY(mu)
// For files, the current contents of the file. // For files, the current contents of the file.
// //
// INVARIANT: If dir is true, this is nil. // INVARIANT: If !isFile(), len(contents) == 0
contents []byte // GUARDED_BY(mu) contents []byte // GUARDED_BY(mu)
// For symlinks, the target of the symlink.
//
// INVARIANT: If !isSymlink(), len(target) == 0
//
// GUARDED_BY(mu)
target string
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -99,78 +98,75 @@ func newInode( ...@@ -99,78 +98,75 @@ func newInode(
return return
} }
func (inode *inode) checkInvariants() { func (in *inode) checkInvariants() {
// No non-permission mode bits should be set besides os.ModeDir. // INVARIANT: attrs.Mode &^ (os.ModePerm|os.ModeDir|os.ModeSymlink) == 0
if inode.attributes.Mode & ^(os.ModePerm|os.ModeDir) != 0 { if !(in.attrs.Mode&^(os.ModePerm|os.ModeDir|os.ModeSymlink) == 0) {
panic(fmt.Sprintf("Unexpected mode: %v", inode.attributes.Mode)) panic(fmt.Sprintf("Unexpected mode: %v", in.attrs.Mode))
} }
// Check os.ModeDir. // INVARIANT: !(isDir() && isSymlink())
if inode.dir != (inode.attributes.Mode&os.ModeDir == os.ModeDir) { if in.isDir() && in.isSymlink() {
panic( panic(fmt.Sprintf("Unexpected mode: %v", in.attrs.Mode))
fmt.Sprintf(
"Unexpected mode: %v, dir: %v",
inode.attributes.Mode,
inode.dir))
} }
// Check directory-specific stuff. // INVARIANT: attrs.Size == len(contents)
if inode.dir { if in.attrs.Size != len(in.contents) {
if inode.contents != nil { panic(fmt.Sprintf(
panic("Non-nil contents in a directory.") "Size mismatch: %d vs. %d",
} in.attrs.Size,
len(in.contents)))
}
childNames := make(map[string]struct{}) // INVARIANT: If !isDir(), len(entries) == 0
for i, e := range inode.entries { if !in.isDir() && len(entries) != 0 {
if e.Offset != fuseops.DirOffset(i+1) { panic(fmt.Sprintf("Unexpected entries length: %d", len(entries)))
panic(fmt.Sprintf("Unexpected offset: %v", e.Offset)) }
}
if e.Type != fuseutil.DT_Unknown { // INVARIANT: For each i, entries[i].Offset == i+1
if _, ok := childNames[e.Name]; ok { for i, e := range in.entries {
panic(fmt.Sprintf("Duplicate name: %s", e.Name)) if !(e.Offset == i+1) {
} panic(fmt.Sprintf("Unexpected offset for index %d: %d", i, e.Offset))
}
}
childNames[e.Name] = struct{}{} // INVARIANT: Contains no duplicate names in used entries.
childNames := make(map[string]struct{})
for i, e := range inode.entries {
if e.Type != fuseutil.DT_Unknown {
if _, ok := childNames[e.Name]; ok {
panic(fmt.Sprintf("Duplicate name: %s", e.Name))
} }
childNames[e.Name] = struct{}{}
} }
} }
// Check file-specific stuff. // INVARIANT: If !isFile(), len(contents) == 0
if !inode.dir { if !in.isFile() && len(in.contents) != 0 {
if inode.entries != nil { panic(fmt.Sprintf("Unexpected length: %d", len(in.contents)))
panic("Non-nil entries in a file.")
}
} }
// Check the size. // INVARIANT: If !isSymlink(), len(target) == 0
if inode.attributes.Size != uint64(len(inode.contents)) { if !in.isSymlink() && len(in.target) != 0 {
panic( panic(fmt.Sprintf("Unexpected target length: %d", len(in.target)))
fmt.Sprintf(
"Unexpected size: %v vs. %v",
inode.attributes.Size,
len(inode.contents)))
} }
return
} }
// Return the index of the child within inode.entries, if it exists. // LOCKS_REQUIRED(in.mu)
// func (in *inode) isDir() bool {
// REQUIRES: inode.dir return in.attrs.Mode&os.ModeDir != 0
// SHARED_LOCKS_REQUIRED(inode.mu) }
func (inode *inode) findChild(name string) (i int, ok bool) {
if !inode.dir {
panic("findChild called on non-directory.")
}
var e fuseutil.Dirent // LOCKS_REQUIRED(in.mu)
for i, e = range inode.entries { func (in *inode) isSymlink() bool {
if e.Name == name { return in.attrs.Mode&os.ModeSymlink != 0
ok = true }
return
}
}
return // LOCKS_REQUIRED(in.mu)
func (in *inode) isFile() bool {
return !(in.isDir() || in.isSymlink())
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment