Commit dad9f3f8 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Fixes for base FUSE library:

* Lookup a directory before trying to mount it.

* Cleanup stream closing for PathFileSystemConnector.
parent 655a5066
...@@ -69,7 +69,7 @@ func (self *PassThroughFuse) OpenDir(name string) (stream chan fuse.DirEntry, st ...@@ -69,7 +69,7 @@ func (self *PassThroughFuse) OpenDir(name string) (stream chan fuse.DirEntry, st
break break
} }
} }
close(output) output <- fuse.DirEntry{}
f.Close() f.Close()
}() }()
......
...@@ -73,6 +73,7 @@ func (me *ZipDirTree) FindDir(name string) *ZipDirTree { ...@@ -73,6 +73,7 @@ func (me *ZipDirTree) FindDir(name string) *ZipDirTree {
type ZipFileFuse struct { type ZipFileFuse struct {
zipReader *zip.Reader zipReader *zip.Reader
tree *ZipDirTree tree *ZipDirTree
ZipFileName string
fuse.DefaultPathFilesystem fuse.DefaultPathFilesystem
} }
...@@ -99,17 +100,23 @@ func zipFilesToTree(files []*zip.File) *ZipDirTree { ...@@ -99,17 +100,23 @@ func zipFilesToTree(files []*zip.File) *ZipDirTree {
return t return t
} }
func NewZipFileFuse(name string) *ZipFileFuse { func NewZipFileFuse(name string) *ZipFileFuse {
z := new(ZipFileFuse) z := new(ZipFileFuse)
r, err := zip.OpenReader(name) r, err := zip.OpenReader(name)
if err != nil { if err != nil {
panic("zip open error") // TODO - return os.Error instead.
log.Println("NewZipFileFuse(): " + err.String())
return nil
} }
z.ZipFileName = name
z.zipReader = r z.zipReader = r
z.tree = zipFilesToTree(r.File) z.tree = zipFilesToTree(r.File)
return z return z
} }
const zip_DIRMODE uint32 = fuse.S_IFDIR | 0700 const zip_DIRMODE uint32 = fuse.S_IFDIR | 0700
const zip_FILEMODE uint32 = fuse.S_IFREG | 0600 const zip_FILEMODE uint32 = fuse.S_IFREG | 0600
...@@ -160,8 +167,7 @@ func (self *ZipFileFuse) OpenDir(name string) (stream chan fuse.DirEntry, code f ...@@ -160,8 +167,7 @@ func (self *ZipFileFuse) OpenDir(name string) (stream chan fuse.DirEntry, code f
Mode: zip_DIRMODE, Mode: zip_DIRMODE,
} }
} }
stream <- fuse.DirEntry{}
close(stream)
}() }()
return stream, fuse.OK return stream, fuse.OK
} }
......
package fuse package fuse
import (
"log"
)
var _ = log.Println
func (self *DefaultRawFuseFileSystem) Init(h *InHeader, input *InitIn) (*InitOut, Status) { func (self *DefaultRawFuseFileSystem) Init(h *InHeader, input *InitIn) (*InitOut, Status) {
return new(InitOut), OK return new(InitOut), OK
} }
......
...@@ -82,6 +82,10 @@ func (me *FuseDir) inode(name string) uint64 { ...@@ -82,6 +82,10 @@ func (me *FuseDir) inode(name string) uint64 {
} }
func (me *FuseDir) ReadDir(input *ReadIn) (*DirEntryList, Status) { func (me *FuseDir) ReadDir(input *ReadIn) (*DirEntryList, Status) {
if me.stream == nil {
return nil, OK
}
list := NewDirEntryList(int(input.Size)) list := NewDirEntryList(int(input.Size))
if me.leftOver.Name != "" { if me.leftOver.Name != "" {
...@@ -97,6 +101,8 @@ func (me *FuseDir) ReadDir(input *ReadIn) (*DirEntryList, Status) { ...@@ -97,6 +101,8 @@ func (me *FuseDir) ReadDir(input *ReadIn) (*DirEntryList, Status) {
for { for {
d := <-me.stream d := <-me.stream
if d.Name == "" { if d.Name == "" {
close(me.stream)
me.stream = nil
break break
} }
i := me.inode(d.Name) i := me.inode(d.Name)
...@@ -110,6 +116,5 @@ func (me *FuseDir) ReadDir(input *ReadIn) (*DirEntryList, Status) { ...@@ -110,6 +116,5 @@ func (me *FuseDir) ReadDir(input *ReadIn) (*DirEntryList, Status) {
} }
func (me *FuseDir) ReleaseDir() { func (me *FuseDir) ReleaseDir() {
// TODO - should close ?
} }
...@@ -33,6 +33,7 @@ type inodeData struct { ...@@ -33,6 +33,7 @@ type inodeData struct {
LookupCount int LookupCount int
Type uint32 Type uint32
// Number of inodeData that have this as parent. // Number of inodeData that have this as parent.
RefCount int RefCount int
...@@ -310,14 +311,23 @@ func (self *PathFileSystemConnector) SetOptions(opts PathFileSystemConnectorOpti ...@@ -310,14 +311,23 @@ func (self *PathFileSystemConnector) SetOptions(opts PathFileSystemConnectorOpti
} }
func (self *PathFileSystemConnector) Mount(path string, fs PathFilesystem) Status { func (self *PathFileSystemConnector) Mount(mountPoint string, fs PathFilesystem) Status {
node := self.findInode(path) var node *inodeData
if mountPoint != "/" {
dirParent, base := path.Split(mountPoint)
dirParentNode := self.findInode(dirParent)
// Make sure we know the mount point.
attr, _ := self.internalLookup(dirParentNode.NodeId, base, 0)
}
node = self.findInode(mountPoint)
// TODO - check that fs was not mounted elsewhere. // TODO - check that fs was not mounted elsewhere.
if node.RefCount > 0 { if node.RefCount > 0 {
return EBUSY return EBUSY
} }
if node.Type&ModeToType(S_IFDIR) == 0 { if node.Type&ModeToType(S_IFDIR) == 0 {
return EINVAL return EINVAL
} }
...@@ -325,13 +335,13 @@ func (self *PathFileSystemConnector) Mount(path string, fs PathFilesystem) Statu ...@@ -325,13 +335,13 @@ func (self *PathFileSystemConnector) Mount(path string, fs PathFilesystem) Statu
code := fs.Mount(self) code := fs.Mount(self)
if code != OK { if code != OK {
if self.Debug { if self.Debug {
log.Println("Mount error: ", path, code) log.Println("Mount error: ", mountPoint, code)
} }
return code return code
} }
if self.Debug { if self.Debug {
log.Println("Mount: ", fs, "on", path, node) log.Println("Mount: ", fs, "on", mountPoint, node)
} }
// TODO - this is technically a race-condition? // TODO - this is technically a race-condition?
...@@ -392,7 +402,11 @@ func (self *PathFileSystemConnector) Destroy(h *InHeader, input *InitIn) { ...@@ -392,7 +402,11 @@ func (self *PathFileSystemConnector) Destroy(h *InHeader, input *InitIn) {
} }
func (self *PathFileSystemConnector) Lookup(header *InHeader, name string) (out *EntryOut, status Status) { func (self *PathFileSystemConnector) Lookup(header *InHeader, name string) (out *EntryOut, status Status) {
parent := self.getInodeData(header.NodeId) return self.internalLookup(header.NodeId, name, 1)
}
func (self *PathFileSystemConnector) internalLookup(nodeid uint64, name string, lookupCount int) (out *EntryOut, status Status) {
parent := self.getInodeData(nodeid)
// TODO - fuse.c has special case code for name == "." and // TODO - fuse.c has special case code for name == "." and
// "..", those lookups happen if FUSE_EXPORT_SUPPORT is set in // "..", those lookups happen if FUSE_EXPORT_SUPPORT is set in
...@@ -413,8 +427,8 @@ func (self *PathFileSystemConnector) Lookup(header *InHeader, name string) (out ...@@ -413,8 +427,8 @@ func (self *PathFileSystemConnector) Lookup(header *InHeader, name string) (out
return nil, err return nil, err
} }
data := self.lookupUpdate(header.NodeId, name) data := self.lookupUpdate(nodeid, name)
data.LookupCount++ data.LookupCount += lookupCount
data.Type = ModeToType(attr.Mode) data.Type = ModeToType(attr.Mode)
out = new(EntryOut) out = new(EntryOut)
......
...@@ -539,7 +539,7 @@ type RawFileSystem interface { ...@@ -539,7 +539,7 @@ type RawFileSystem interface {
type RawFuseFile interface { type RawFuseFile interface {
Read(*ReadIn, *BufferPool) ([]byte, Status) Read(*ReadIn, *BufferPool) ([]byte, Status)
// u32 <-> u64 ? // u32 <-> u64 ?
Write(*WriteIn, []byte) (uint32, Status) Write(*WriteIn, []byte) (written uint32, code Status)
Flush() Status Flush() Status
Release() Release()
Fsync(*FsyncIn) (code Status) Fsync(*FsyncIn) (code Status)
......
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