Only mark as unlinked in rmdir.

geesefs-0-30-9
Aaron Jacobs 2015-03-03 14:56:55 +11:00
parent 140bd18863
commit 651984dc1a
2 changed files with 16 additions and 3 deletions

View File

@ -332,9 +332,8 @@ func (fs *memFS) RmDir(
// Remove the entry within the parent. // Remove the entry within the parent.
parent.RemoveChild(req.Name) parent.RemoveChild(req.Name)
// TODO(jacobsa): Don't remove the child until it's forgotten. Can we get a // Mark the child as unlinked.
// failing test by continuing to read from an opened dir handle? child.linkCount--
fs.deallocateInode(childID)
return return
} }

View File

@ -31,6 +31,13 @@ type inode struct {
mu syncutil.InvariantMutex mu syncutil.InvariantMutex
// The number of times this inode is linked into a parent directory. This may
// be zero if the inode has been unlinked but not yet forgotten, because some
// process still has an open file handle.
//
// INVARIANT: linkCount >= 0
linkCount int // GUARDED_BY(mu)
// The current attributes of this inode. // The current attributes of this inode.
// //
// INVARIANT: No non-permission mode bits are set besides os.ModeDir // INVARIANT: No non-permission mode bits are set besides os.ModeDir
@ -64,8 +71,10 @@ type inode struct {
// Helpers // Helpers
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Initially the link count is one.
func newInode(attrs fuse.InodeAttributes) (in *inode) { func newInode(attrs fuse.InodeAttributes) (in *inode) {
in = &inode{ in = &inode{
linkCount: 1,
dir: (attrs.Mode&os.ModeDir != 0), dir: (attrs.Mode&os.ModeDir != 0),
attributes: attrs, attributes: attrs,
} }
@ -75,6 +84,11 @@ func newInode(attrs fuse.InodeAttributes) (in *inode) {
} }
func (inode *inode) checkInvariants() { func (inode *inode) checkInvariants() {
// Check the link count.
if inode.linkCount < 0 {
panic(fmt.Sprintf("Negative link count: %v", inode.linkCount))
}
// No non-permission mode bits should be set besides os.ModeDir. // No non-permission mode bits should be set besides os.ModeDir.
if inode.attributes.Mode & ^(os.ModePerm|os.ModeDir) != 0 { if inode.attributes.Mode & ^(os.ModePerm|os.ModeDir) != 0 {
panic(fmt.Sprintf("Unexpected mode: %v", inode.attributes.Mode)) panic(fmt.Sprintf("Unexpected mode: %v", inode.attributes.Mode))