Commit 2c972a0a authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Return slice rather than channel for OpenDir.

parent 5514ae72
......@@ -50,17 +50,12 @@ func (me *StatFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.
return e, fuse.OK
}
func (me *StatFs) OpenDir(name string, context *fuse.Context) (stream chan fuse.DirEntry, status fuse.Status) {
func (me *StatFs) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) {
entries := me.dirs[name]
if entries == nil {
return nil, fuse.ENOENT
}
stream = make(chan fuse.DirEntry, len(entries))
for _, e := range entries {
stream <- e
}
close(stream)
return stream, fuse.OK
return entries, fuse.OK
}
func NewStatFs() *StatFs {
......
......@@ -26,11 +26,9 @@ func (me *HelloFs) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse
return nil, fuse.ENOENT
}
func (me *HelloFs) OpenDir(name string, context *fuse.Context) (c chan fuse.DirEntry, code fuse.Status) {
func (me *HelloFs) OpenDir(name string, context *fuse.Context) (c []fuse.DirEntry, code fuse.Status) {
if name == "" {
c = make(chan fuse.DirEntry, 1)
c <- fuse.DirEntry{Name: "file.txt", Mode: fuse.S_IFREG}
close(c)
c = []fuse.DirEntry{{Name: "file.txt", Mode: fuse.S_IFREG}}
return c, fuse.OK
}
return nil, fuse.ENOENT
......
......@@ -59,7 +59,7 @@ type FsNode interface {
// Files
Create(name string, flags uint32, mode uint32, context *Context) (file File, fi *Attr, newNode FsNode, code Status)
Open(flags uint32, context *Context) (file File, code Status)
OpenDir(context *Context) (chan DirEntry, Status)
OpenDir(context *Context) ([]DirEntry, Status)
// XAttrs
GetXAttr(attribute string, context *Context) (data []byte, code Status)
......@@ -129,7 +129,7 @@ type FileSystem interface {
Create(name string, flags uint32, mode uint32, context *Context) (file File, code Status)
// Directory handling
OpenDir(name string, context *Context) (stream chan DirEntry, code Status)
OpenDir(name string, context *Context) (stream []DirEntry, code Status)
// Symlinks.
Symlink(value string, linkName string, context *Context) (code Status)
......
......@@ -71,7 +71,7 @@ func (fs *DefaultFileSystem) Open(name string, flags uint32, context *Context) (
return nil, ENOSYS
}
func (fs *DefaultFileSystem) OpenDir(name string, context *Context) (stream chan DirEntry, status Status) {
func (fs *DefaultFileSystem) OpenDir(name string, context *Context) (stream []DirEntry, status Status) {
return nil, ENOSYS
}
......
......@@ -104,16 +104,15 @@ func (n *DefaultFsNode) Flush(file File, openFlags uint32, context *Context) (co
return ENOSYS
}
func (n *DefaultFsNode) OpenDir(context *Context) (chan DirEntry, Status) {
func (n *DefaultFsNode) OpenDir(context *Context) ([]DirEntry, Status) {
ch := n.Inode().Children()
s := make(chan DirEntry, len(ch))
s := make([]DirEntry, len(ch))
for name, child := range ch {
fi, code := child.FsNode().GetAttr(nil, context)
if code.Ok() {
s <- DirEntry{Name: name, Mode: fi.Mode}
s = append(s, DirEntry{Name: name, Mode: fi.Mode})
}
}
close(s)
return s, OK
}
......
......@@ -79,14 +79,14 @@ type rawDir interface {
}
type connectorDir struct {
extra []DirEntry
stream chan DirEntry
stream []DirEntry
leftOver DirEntry
lastOffset uint64
}
// TODO - use index into []stream for seeking correctly.
func (d *connectorDir) ReadDir(input *ReadIn) (*DirEntryList, Status) {
if d.stream == nil && len(d.extra) == 0 {
if d.stream == nil {
return nil, OK
}
......@@ -98,35 +98,17 @@ func (d *connectorDir) ReadDir(input *ReadIn) (*DirEntryList, Status) {
}
d.leftOver.Name = ""
}
for len(d.extra) > 0 {
e := d.extra[len(d.extra)-1]
d.extra = d.extra[:len(d.extra)-1]
for len(d.stream) > 0 {
e := d.stream[len(d.stream)-1]
success := list.AddDirEntry(e)
if !success {
d.leftOver = e
return list, OK
}
}
for {
de, isOpen := <-d.stream
if !isOpen {
d.stream = nil
break
}
if !list.AddDirEntry(de) {
d.leftOver = de
break
}
d.stream = d.stream[:len(d.stream)-1]
}
return list, OK
}
// Read everything so we make goroutines exit.
func (d *connectorDir) Release() {
for ok := true; ok && d.stream != nil; {
_, ok = <-d.stream
if !ok {
break
}
}
}
......@@ -103,6 +103,7 @@ func (c *FileSystemConnector) GetAttr(header *raw.InHeader, input *raw.GetAttrIn
out = node.mount.fillAttr(rawAttr, header.NodeId)
return out, OK
}
func (c *FileSystemConnector) OpenDir(header *raw.InHeader, input *raw.OpenIn) (flags uint32, handle uint64, code Status) {
......@@ -112,11 +113,10 @@ func (c *FileSystemConnector) OpenDir(header *raw.InHeader, input *raw.OpenIn) (
return 0, 0, err
}
stream = append(stream, node.getMountDirEntries()...)
de := &connectorDir{
extra: node.getMountDirEntries(),
stream: stream,
stream: append(stream, DirEntry{S_IFDIR, "."}, DirEntry{S_IFDIR, ".."}),
}
de.extra = append(de.extra, DirEntry{S_IFDIR, "."}, DirEntry{S_IFDIR, ".."})
h, opened := node.mount.registerFileHandle(node, de, nil, input.Flags)
// TODO - implement seekable directories
......
......@@ -91,7 +91,7 @@ func (fs *LockingFileSystem) Open(name string, flags uint32, context *Context) (
return fs.FileSystem.Open(name, flags, context)
}
func (fs *LockingFileSystem) OpenDir(name string, context *Context) (stream chan DirEntry, status Status) {
func (fs *LockingFileSystem) OpenDir(name string, context *Context) (stream []DirEntry, status Status) {
defer fs.locked()()
return fs.FileSystem.OpenDir(name, context)
}
......
......@@ -55,7 +55,9 @@ func (fs *LoopbackFileSystem) GetAttr(name string, context *Context) (a *Attr, c
return a, OK
}
func (fs *LoopbackFileSystem) OpenDir(name string, context *Context) (stream chan DirEntry, status Status) {
var _ = (FileSystem)((*LoopbackFileSystem)(nil))
func (fs *LoopbackFileSystem) OpenDir(name string, context *Context) (stream []DirEntry, status Status) {
// What other ways beyond O_RDONLY are there to open
// directories?
f, err := os.Open(fs.GetPath(name))
......@@ -63,8 +65,7 @@ func (fs *LoopbackFileSystem) OpenDir(name string, context *Context) (stream cha
return nil, ToStatus(err)
}
want := 500
output := make(chan DirEntry, want)
go func() {
output := make([]DirEntry, 0, want)
for {
infos, err := f.Readdir(want)
for i := range infos {
......@@ -77,7 +78,7 @@ func (fs *LoopbackFileSystem) OpenDir(name string, context *Context) (stream cha
} else {
log.Println("ReadDir entry %q for %q has no stat info", n, name)
}
output <- d
output = append(output, d)
}
if len(infos) < want || err == io.EOF {
break
......@@ -87,9 +88,7 @@ func (fs *LoopbackFileSystem) OpenDir(name string, context *Context) (stream cha
break
}
}
close(output)
f.Close()
}()
return output, OK
}
......
......@@ -372,7 +372,7 @@ func (n *pathInode) Flush(file File, openFlags uint32, context *Context) (code S
return file.Flush()
}
func (n *pathInode) OpenDir(context *Context) (chan DirEntry, Status) {
func (n *pathInode) OpenDir(context *Context) ([]DirEntry, Status) {
return n.fs.OpenDir(n.GetPath(), context)
}
......
......@@ -67,7 +67,7 @@ func (fs *PrefixFileSystem) Open(name string, flags uint32, context *Context) (f
return fs.FileSystem.Open(fs.prefixed(name), flags, context)
}
func (fs *PrefixFileSystem) OpenDir(name string, context *Context) (stream chan DirEntry, status Status) {
func (fs *PrefixFileSystem) OpenDir(name string, context *Context) (stream []DirEntry, status Status) {
return fs.FileSystem.OpenDir(fs.prefixed(name), context)
}
......
......@@ -65,7 +65,7 @@ func (fs *ReadonlyFileSystem) Open(name string, flags uint32, context *Context)
return &ReadOnlyFile{file}, code
}
func (fs *ReadonlyFileSystem) OpenDir(name string, context *Context) (stream chan DirEntry, status Status) {
func (fs *ReadonlyFileSystem) OpenDir(name string, context *Context) (stream []DirEntry, status Status) {
return fs.FileSystem.OpenDir(name, context)
}
......
......@@ -326,22 +326,14 @@ func (fs *AutoUnionFs) GetAttr(path string, context *fuse.Context) (*fuse.Attr,
return nil, fuse.ENOENT
}
func (fs *AutoUnionFs) StatusDir() (stream chan fuse.DirEntry, status fuse.Status) {
stream = make(chan fuse.DirEntry, 10)
stream <- fuse.DirEntry{
Name: _VERSION,
Mode: fuse.S_IFREG | 0644,
}
stream <- fuse.DirEntry{
Name: _DEBUG,
Mode: fuse.S_IFREG | 0644,
}
stream <- fuse.DirEntry{
Name: _ROOT,
Mode: syscall.S_IFLNK | 0644,
func (fs *AutoUnionFs) StatusDir() (stream []fuse.DirEntry, status fuse.Status) {
stream = make([]fuse.DirEntry, 0, 10)
stream = []fuse.DirEntry{
{Name: _VERSION, Mode: fuse.S_IFREG | 0644},
{Name: _DEBUG, Mode: fuse.S_IFREG | 0644},
{Name: _ROOT, Mode: syscall.S_IFLNK | 0644},
}
close(stream)
return stream, fuse.OK
}
......@@ -416,7 +408,7 @@ func (fs *AutoUnionFs) Truncate(name string, offset uint64, context *fuse.Contex
return fuse.OK
}
func (fs *AutoUnionFs) OpenDir(name string, context *fuse.Context) (stream chan fuse.DirEntry, status fuse.Status) {
func (fs *AutoUnionFs) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) {
switch name {
case _STATUS:
return fs.StatusDir()
......@@ -432,27 +424,26 @@ func (fs *AutoUnionFs) OpenDir(name string, context *fuse.Context) (stream chan
fs.lock.RLock()
defer fs.lock.RUnlock()
stream = make(chan fuse.DirEntry, len(fs.knownFileSystems)+5)
stream = make( []fuse.DirEntry, 0, len(fs.knownFileSystems)+5)
if name == _CONFIG {
for k := range fs.knownFileSystems {
stream <- fuse.DirEntry{
stream = append(stream, fuse.DirEntry{
Name: k,
Mode: syscall.S_IFLNK | 0644,
}
})
}
}
if name == "" {
stream <- fuse.DirEntry{
stream = append(stream, fuse.DirEntry{
Name: _CONFIG,
Mode: uint32(fuse.S_IFDIR | 0755),
}
stream <- fuse.DirEntry{
},
fuse.DirEntry{
Name: _STATUS,
Mode: uint32(fuse.S_IFDIR | 0755),
})
}
}
close(stream)
return stream, status
}
......
......@@ -46,17 +46,10 @@ func readDir(fs fuse.FileSystem, name string) *dirResponse {
origStream, code := fs.OpenDir(name, nil)
r := &dirResponse{nil, code}
if code != fuse.OK {
if !code.Ok() {
return r
}
for {
d, ok := <-origStream
if !ok {
break
}
r.entries = append(r.entries, d)
}
r.entries = origStream
return r
}
......@@ -135,18 +128,9 @@ func (fs *CachingFileSystem) Readlink(name string, context *fuse.Context) (strin
return r.linkContent, r.Status
}
func (fs *CachingFileSystem) OpenDir(name string, context *fuse.Context) (stream chan fuse.DirEntry, status fuse.Status) {
func (fs *CachingFileSystem) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) {
r := fs.dirs.Get(name).(*dirResponse)
if r.Status.Ok() {
stream = make(chan fuse.DirEntry, len(r.entries))
for _, d := range r.entries {
stream <- d
}
close(stream)
return stream, r.Status
}
return nil, r.Status
return r.entries, r.Status
}
func (fs *CachingFileSystem) String() string {
......
......@@ -59,7 +59,7 @@ func TestCachingFs(t *testing.T) {
}
results := make(map[string]uint32)
for v := range stream {
for _, v := range stream {
results[v.Name] = v.Mode &^ 07777
}
expected := map[string]uint32{
......
......@@ -18,7 +18,7 @@ func newDirnameMap(fs fuse.FileSystem, dir string) map[string]bool {
}
result := make(map[string]bool)
for e := range stream {
for _, e := range stream {
if e.Mode&fuse.S_IFREG != 0 {
result[e.Name] = true
}
......
......@@ -431,11 +431,11 @@ func (fs *UnionFs) Mkdir(path string, mode uint32, context *fuse.Context) (code
fs.branchCache.Set(path, branchResult{attr, fuse.OK, 0})
}
var stream chan fuse.DirEntry
var stream []fuse.DirEntry
stream, code = fs.OpenDir(path, context)
if code.Ok() {
// This shouldn't happen, but let's be safe.
for entry := range stream {
for _, entry := range stream {
fs.putDeletion(filepath.Join(path, entry.Name))
}
}
......@@ -712,7 +712,7 @@ func (fs *UnionFs) GetXAttr(name string, attr string, context *fuse.Context) ([]
return nil, fuse.ENOENT
}
func (fs *UnionFs) OpenDir(directory string, context *fuse.Context) (stream chan fuse.DirEntry, status fuse.Status) {
func (fs *UnionFs) OpenDir(directory string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) {
dirBranch := fs.getBranch(directory)
if dirBranch.branch < 0 {
return nil, fuse.ENOENT
......@@ -741,11 +741,7 @@ func (fs *UnionFs) OpenDir(directory string, context *fuse.Context) (stream chan
go func(j int, pfs fuse.FileSystem) {
ch, s := pfs.OpenDir(directory, context)
statuses[j] = s
for s.Ok() {
v, ok := <-ch
if !ok {
break
}
for _, v := range ch {
entries[j][v.Name] = v.Mode
}
wg.Done()
......@@ -795,14 +791,13 @@ func (fs *UnionFs) OpenDir(directory string, context *fuse.Context) (stream chan
}
}
stream = make(chan fuse.DirEntry, len(results))
stream = make([]fuse.DirEntry, 0, len(results))
for k, v := range results {
stream <- fuse.DirEntry{
stream = append(stream, fuse.DirEntry{
Name: k,
Mode: v,
})
}
}
close(stream)
return stream, fuse.OK
}
......@@ -820,9 +815,9 @@ func (fs *UnionFs) recursivePromote(path string, pathResult branchResult, contex
}
if code.Ok() && pathResult.attr != nil && pathResult.attr.IsDir() {
var stream chan fuse.DirEntry
var stream []fuse.DirEntry
stream, code = fs.OpenDir(path, context)
for e := range stream {
for _, e := range stream {
if !code.Ok() {
break
}
......
......@@ -66,20 +66,19 @@ func (n *memNode) Lookup(name string, c *fuse.Context) (fi *fuse.Attr, node fuse
return nil, nil, fuse.ENOENT
}
func (n *memNode) OpenDir(context *fuse.Context) (stream chan fuse.DirEntry, code fuse.Status) {
func (n *memNode) OpenDir(context *fuse.Context) (stream []fuse.DirEntry, code fuse.Status) {
children := n.Inode().Children()
stream = make(chan fuse.DirEntry, len(children))
stream = make([]fuse.DirEntry, 0, len(children))
for k, v := range children {
mode := fuse.S_IFREG | 0666
if v.IsDir() {
mode = fuse.S_IFDIR | 0777
}
stream <- fuse.DirEntry{
stream = append(stream, fuse.DirEntry{
Name: k,
Mode: uint32(mode),
})
}
}
close(stream)
return stream, fuse.OK
}
......
......@@ -18,6 +18,7 @@ import (
)
var _ = log.Printf
var _ = (fuse.FileSystem)((*MultiZipFs)(nil))
const (
CONFIG_PREFIX = "config/"
......@@ -50,16 +51,16 @@ func (fs *MultiZipFs) OnMount(nodeFs *fuse.PathNodeFs) {
fs.nodeFs = nodeFs
}
func (fs *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan fuse.DirEntry, code fuse.Status) {
func (fs *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, code fuse.Status) {
fs.lock.RLock()
defer fs.lock.RUnlock()
stream = make(chan fuse.DirEntry, len(fs.zips)+2)
stream = make([]fuse.DirEntry, 0, len(fs.zips)+2)
if name == "" {
var d fuse.DirEntry
d.Name = "config"
d.Mode = fuse.S_IFDIR | 0700
stream <- fuse.DirEntry(d)
stream = append(stream, fuse.DirEntry(d))
}
if name == "config" {
......@@ -67,11 +68,10 @@ func (fs *MultiZipFs) OpenDir(name string, context *fuse.Context) (stream chan f
var d fuse.DirEntry
d.Name = k
d.Mode = fuse.S_IFLNK
stream <- fuse.DirEntry(d)
stream = append(stream, fuse.DirEntry(d))
}
}
close(stream)
return stream, fuse.OK
}
......
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