// RmdirAt implements vfs.FilesystemImpl.RmdirAt.
RmdirAt implements vfs.FilesystemImpl.RmdirAt.
// RmdirAt implements vfs . FilesystemImpl . RmdirAt .
func (fs *filesystem) RmdirAt(ctx context.Context, rp *vfs.ResolvingPath) error {
	fs.mu.Lock()
	defer fs.mu.Unlock()
	parentDir, err := walkParentDirLocked(ctx, rp, rp.Start().Impl().(*dentry))
	if err != nil {
		return err
	}
	if err := parentDir.inode.checkPermissions(rp.Credentials(), vfs.MayWrite|vfs.MayExec); err != nil {
		return err
	}
	name := rp.Component()
	if name == "." {
		return syserror.EINVAL
	}
	if name == ".." {
		return syserror.ENOTEMPTY
	}
	child, ok := parentDir.childMap[name]
	if !ok {
		return syserror.ENOENT
	}
	if err := parentDir.mayDelete(rp.Credentials(), child); err != nil {
		return err
	}
	childDir, ok := child.inode.impl.(*directory)
	if !ok {
		return syserror.ENOTDIR
	}
	if len(childDir.childMap) != 0 {
		return syserror.ENOTEMPTY
	}
	mnt := rp.Mount()
	if err := mnt.CheckBeginWrite(); err != nil {
		return err
	}
	defer mnt.EndWrite()
	vfsObj := rp.VirtualFilesystem()
	mntns := vfs.MountNamespaceFromContext(ctx)
	defer mntns.DecRef(ctx)
	if err := vfsObj.PrepareDeleteDentry(mntns, &child.vfsd); err != nil {
		return err
	}
	parentDir.removeChildLocked(child)
	parentDir.inode.watches.Notify(ctx, name, linux.IN_DELETE|linux.IN_ISDIR, 0, vfs.InodeEvent, true )
	child.inode.decLinksLocked(ctx)
	child.inode.decLinksLocked(ctx)
	parentDir.inode.decLinksLocked(ctx)
	vfsObj.CommitDeleteDentry(ctx, &child.vfsd)
	parentDir.inode.touchCMtime()
	return nil
}
func ( fs * filesystem ) RmdirAt ( ctx context . Context , rp * vfs . ResolvingPath ) error { fs . mu . Lock ( ) defer fs . mu . Unlock ( ) parentDir , err := walkParentDirLocked ( ctx , rp , rp . Start ( ) . Impl ( ) . ( * dentry ) ) if err != nil { return err } if err := parentDir . inode . checkPermissions ( rp . Credentials ( ) , vfs . MayWrite | vfs . MayExec ) ; err != nil { return err } name := rp . Component ( ) if name == " " { return syserror . EINVAL } if name == " " { return syserror . ENOTEMPTY } child , ok := parentDir . childMap [ name ] if ! ok { return syserror . ENOENT } if err := parentDir . mayDelete ( rp . Credentials ( ) , child ) ; err != nil { return err } childDir , ok := child . inode . impl . ( * directory ) if ! ok { return syserror . ENOTDIR } if len ( childDir . childMap ) != 0 { return syserror . ENOTEMPTY } mnt := rp . Mount ( ) if err := mnt . CheckBeginWrite ( ) ; err != nil { return err } defer mnt . EndWrite ( ) vfsObj := rp . VirtualFilesystem ( ) mntns := vfs . MountNamespaceFromContext ( ctx ) defer mntns . DecRef ( ctx ) if err := vfsObj . PrepareDeleteDentry ( mntns , & child . vfsd ) ; err != nil { return err } parentDir . removeChildLocked ( child ) parentDir . inode . watches . Notify ( ctx , name , linux . IN_DELETE | linux . IN_ISDIR , 0 , vfs . InodeEvent , true ) child . inode . decLinksLocked ( ctx ) child . inode . decLinksLocked ( ctx ) parentDir . inode . decLinksLocked ( ctx ) vfsObj . CommitDeleteDentry ( ctx , & child . vfsd ) parentDir . inode . touchCMtime ( ) return nil }
RmdirAt implements vfs.FilesystemImpl.RmdirAt.
RmdirAt implements vfs . FilesystemImpl . RmdirAt .
/* unlinked */ // Remove links for child, child/., and child/..