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