Check for empty in rmdir.

geesefs-0-30-9
Aaron Jacobs 2015-03-03 14:39:29 +11:00
parent 98f868c319
commit 01371975df
4 changed files with 40 additions and 6 deletions

View File

@ -3,12 +3,17 @@
package fuse
import bazilfuse "bazil.org/fuse"
import (
"syscall"
bazilfuse "bazil.org/fuse"
)
const (
// Errors corresponding to kernel error numbers. These may be treated
// specially when returned by a FileSystem method.
ENOSYS = bazilfuse.ENOSYS
ENOENT = bazilfuse.ENOENT
EIO = bazilfuse.EIO
EIO = bazilfuse.EIO
ENOENT = bazilfuse.ENOENT
ENOSYS = bazilfuse.ENOSYS
ENOTEMPTY = bazilfuse.Errno(syscall.ENOTEMPTY)
)

View File

@ -306,7 +306,22 @@ func (fs *memFS) RmDir(
parent := fs.getInodeForModifyingOrDie(req.Parent)
defer parent.mu.Unlock()
// TODO(jacobsa): Check for empty. (Make sure we have a failing test first.)
// Find the child within the parent.
childID, ok := parent.LookUpChild(req.Name)
if !ok {
err = fuse.ENOENT
return
}
// Grab the child.
child := fs.getInodeForModifyingOrDie(childID)
defer child.mu.Unlock()
// Make sure the child is empty.
if child.Len() != 0 {
err = fuse.ENOTEMPTY
return
}
// Remove the entry within the parent.
parent.RemoveChild(req.Name)

View File

@ -143,6 +143,20 @@ func (inode *inode) findChild(name string) (i int, ok bool) {
// Public methods
////////////////////////////////////////////////////////////////////////
// Return the number of children of the directory.
//
// REQUIRES: inode.dir
// SHARED_LOCKS_REQUIRED(inode.mu)
func (inode *inode) Len() (n int) {
for _, e := range inode.entries {
if e.Type != fuseutil.DT_Unknown {
n++
}
}
return
}
// Find an entry for the given child name and return its inode ID.
//
// REQUIRES: inode.dir

View File

@ -334,7 +334,7 @@ func (t *MemFSTest) Rmdir_NonEmpty() {
err = os.Remove(path.Join(t.mfs.Dir(), "foo"))
AssertNe(nil, err)
ExpectThat(err, Error(HasSubstr("non-empty")))
ExpectThat(err, Error(HasSubstr("not empty")))
}
func (t *MemFSTest) Rmdir_Empty() {