Commit 5e8fa0ba authored by Ivan Krasin's avatar Ivan Krasin

FileSystem.Open is introduced and the interface File { Read, Close }

parent dd090e86
...@@ -13,9 +13,15 @@ const ( ...@@ -13,9 +13,15 @@ const (
bufSize = 66000 bufSize = 66000
) )
type File interface {
Read(offset uint64) (data []byte, status Status)
Close() (status Status)
}
type FileSystem interface { type FileSystem interface {
List(parent string) (names []string, status Status) List(parent string) (names []string, status Status)
GetAttr(path string) (out Attr, status Status) GetAttr(path string) (out Attr, status Status)
Open(path string) (file File, status Status)
} }
type Mounted interface { type Mounted interface {
...@@ -417,6 +423,7 @@ type fileResponse struct { ...@@ -417,6 +423,7 @@ type fileResponse struct {
type fileHandle struct { type fileHandle struct {
fh uint64 fh uint64
nodeId uint64 nodeId uint64
file File
req chan *fileRequest req chan *fileRequest
} }
...@@ -538,18 +545,25 @@ func (m *manager) openDir(req *managerRequest) (resp *managerResponse) { ...@@ -538,18 +545,25 @@ func (m *manager) openDir(req *managerRequest) (resp *managerResponse) {
func (m *manager) open(req *managerRequest) (resp *managerResponse) { func (m *manager) open(req *managerRequest) (resp *managerResponse) {
resp = new(managerResponse) resp = new(managerResponse)
path, ok := m.nodes[req.nodeId]
if !ok {
resp.status = ENOENT
return
}
var file File
file, resp.status = m.fs.Open(path)
if resp.status != OK {
return
}
m.cnt++ m.cnt++
h := new(fileHandle) h := new(fileHandle)
h.fh = m.cnt h.fh = m.cnt
h.nodeId = req.nodeId h.nodeId = req.nodeId
h.file = file
h.req = make(chan *fileRequest, 1) h.req = make(chan *fileRequest, 1)
m.fileHandles[h.fh] = h m.fileHandles[h.fh] = h
filepath, ok := m.nodes[req.nodeId] go readFileRoutine(m.fs, m.client, h)
if !ok {
resp.status = ENOENT
return
}
go readFileRoutine(filepath, m.fs, m.client, h.req)
resp.fh = h.fh resp.fh = h.fh
return return
} }
...@@ -599,8 +613,10 @@ func (m *manager) closeFile(req *managerRequest) (resp *managerResponse) { ...@@ -599,8 +613,10 @@ func (m *manager) closeFile(req *managerRequest) (resp *managerResponse) {
resp.status = ENOENT resp.status = ENOENT
return return
} }
file := h.file
m.fileHandles[h.fh] = nil, false m.fileHandles[h.fh] = nil, false
close(h.req) close(h.req)
resp.status = file.Close()
return return
} }
...@@ -675,14 +691,15 @@ func readDirRoutine(dir string, fs FileSystem, c *managerClient, requests chan * ...@@ -675,14 +691,15 @@ func readDirRoutine(dir string, fs FileSystem, c *managerClient, requests chan *
} }
} }
func readFileRoutine(filepath string, fs FileSystem, c *managerClient, requests chan *fileRequest) { func readFileRoutine(fs FileSystem, c *managerClient, h *fileHandle) {
defer close(requests) defer close(h.req)
filepath = path.Clean(filepath)
offset := uint64(0) offset := uint64(0)
for req := range requests { for req := range h.req {
if req.offset != offset { if req.offset != offset {
req.resp <- &fileResponse { nil, OK } req.resp <- &fileResponse { nil, OK }
} }
req.resp <- &fileResponse { []byte("Hello world!"), OK } data, status := h.file.Read(offset)
req.resp <- &fileResponse { data, status }
offset += uint64(len(data))
} }
} }
...@@ -21,10 +21,10 @@ type testFuse struct{} ...@@ -21,10 +21,10 @@ type testFuse struct{}
func (fs *testFuse) GetAttr(path string) (out Attr, code Status) { func (fs *testFuse) GetAttr(path string) (out Attr, code Status) {
if strings.HasSuffix(path, ".txt") { if strings.HasSuffix(path, ".txt") {
out.Mode = S_IFREG + 0644 out.Mode = S_IFREG + 0644
out.Size = 13
} else { } else {
out.Mode = S_IFDIR + 0755 out.Mode = S_IFDIR + 0755
} }
out.Size = 12
out.Mtime = uint64(time.Seconds()) out.Mtime = uint64(time.Seconds())
return return
} }
...@@ -34,6 +34,24 @@ func (fs *testFuse) List(dir string) (names []string, code Status) { ...@@ -34,6 +34,24 @@ func (fs *testFuse) List(dir string) (names []string, code Status) {
return return
} }
func (fs *testFuse) Open(path string) (file File, code Status) {
file = &testFile{}
return
}
type testFile struct {}
func (f *testFile) Read(offset uint64) (data []byte, code Status) {
if offset < 13 {
return []byte("Hello world!\n"[offset:]), OK
}
return nil, OK
}
func (f *testFile) Close() (status Status) {
return OK
}
func errorHandler(errors chan os.Error) { func errorHandler(errors chan os.Error) {
for err := range errors { for err := range errors {
log.Stderr("MountPoint.errorHandler: ", err) log.Stderr("MountPoint.errorHandler: ", err)
......
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