blob: be44eb5eadb8c5b958fe616160b1c78013739cb5 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// +build !build_with_native_toolchain
package pkgfs
import (
"log"
"strings"
"sync"
"time"
"go.fuchsia.dev/fuchsia/src/lib/thinfs/fs"
)
type ctlDirectory struct {
unsupportedDirectory
fs *Filesystem
mu sync.RWMutex
dirs map[string]fs.Directory
}
func (d *ctlDirectory) Dup() (fs.Directory, error) {
return d, nil
}
func (d *ctlDirectory) Open(name string, flags fs.OpenFlags) (fs.File, fs.Directory, *fs.Remote, error) {
name = clean(name)
if name == "" {
return nil, d, nil, nil
}
parts := strings.SplitN(name, "/", 2)
d.mu.RLock()
subdir, ok := d.dirs[parts[0]]
d.mu.RUnlock()
if !ok {
return nil, nil, nil, fs.ErrNotFound
}
if len(parts) == 1 {
return nil, subdir, nil, nil
}
return subdir.Open(parts[1], flags)
}
func (d *ctlDirectory) Read() ([]fs.Dirent, error) {
d.mu.RLock()
dirs := make([]fs.Dirent, 0, len(d.dirs))
for n := range d.dirs {
dirs = append(dirs, dirDirEnt(n))
}
d.mu.RUnlock()
return dirs, nil
}
func (d *ctlDirectory) Close() error {
return nil
}
func (d *ctlDirectory) Stat() (int64, time.Time, time.Time, error) {
return 0, d.fs.mountTime, d.fs.mountTime, nil
}
func (d *ctlDirectory) Unlink(path string) error {
// the "garbage" file is a special control file. When it is unlinked,
// we trigger garbage collection.
if path == "do-not-use-this-garbage" {
if err := d.fs.GC(); err != nil {
log.Printf("unlink garbage: %s", err)
}
return nil
}
return d.unsupportedDirectory.Unlink(path)
}
func (d *ctlDirectory) Sync() error {
return d.fs.blobfs.Sync()
}