Better file handling

This commit is contained in:
Alex Yatskov 2015-05-25 13:27:54 +09:00
parent 205ca11e0c
commit 5597bf4cfc
2 changed files with 47 additions and 21 deletions

11
dir.go
View File

@ -68,20 +68,17 @@ func (this *versionedDir) createDir(name string) (*versionedDir, error) {
func (this *versionedDir) createFile(name string, flags int) (*versionedFile, error) { func (this *versionedDir) createFile(name string, flags int) (*versionedFile, error) {
childPath := path.Join(this.node.path, name) childPath := path.Join(this.node.path, name)
handle, err := os.OpenFile(this.node.ver.rebasePath(childPath), flags, 0644)
if err != nil {
return nil, err
}
defer handle.Close()
node, err := newVersionedNode(childPath, this.node.ver) node, err := newVersionedNode(childPath, this.node.ver)
if err != nil { if err != nil {
return nil, err return nil, err
} }
file := newVersionedFile(node, this) file := newVersionedFile(node, this)
this.files[name] = file if err := file.create(name, flags); err != nil {
return nil, err
}
this.files[name] = file
return file, nil return file, nil
} }

57
file.go
View File

@ -24,8 +24,8 @@ package main
import ( import (
"bazil.org/fuse" "bazil.org/fuse"
"errors"
"golang.org/x/net/context" "golang.org/x/net/context"
"io/ioutil"
"os" "os"
) )
@ -33,6 +33,7 @@ type versionedFile struct {
node *versionedNode node *versionedNode
inode uint64 inode uint64
parent *versionedDir parent *versionedDir
handle *os.File
} }
func newVersionedFile(node *versionedNode, parent *versionedDir) *versionedFile { func newVersionedFile(node *versionedNode, parent *versionedDir) *versionedFile {
@ -42,19 +43,37 @@ func newVersionedFile(node *versionedNode, parent *versionedDir) *versionedFile
parent: parent} parent: parent}
} }
func (this *versionedFile) create(path string, flags int) error {
handle, err := os.OpenFile(this.node.ver.rebasePath(path), flags, 0644)
if err != nil {
return err
}
this.handle = handle
return nil
}
func (this *versionedFile) release() bool {
if this.handle == nil {
return false
}
this.handle.Close()
this.handle = nil
return true
}
func (this *versionedFile) Attr(attr *fuse.Attr) { func (this *versionedFile) Attr(attr *fuse.Attr) {
this.node.attr(attr) this.node.attr(attr)
attr.Inode = this.inode attr.Inode = this.inode
} }
func (this *versionedFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error { func (this *versionedFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error {
file, err := os.OpenFile(this.node.rebasedPath(), os.O_WRONLY, 0666) if this.handle == nil {
if err != nil { return errors.New("attempted to write unopened file")
return err
} }
defer file.Close()
size, err := file.WriteAt(req.Data, req.Offset) size, err := this.handle.WriteAt(req.Data, req.Offset)
if err != nil { if err != nil {
return err return err
} }
@ -74,19 +93,25 @@ func (this *versionedFile) Setattr(ctx context.Context, req *fuse.SetattrRequest
return nil return nil
} }
func (this *versionedFile) Release(ctx context.Context, req *fuse.ReleaseRequest) error {
if this.release() {
return nil
}
return errors.New("attempted to release unopened file")
}
func (this *versionedFile) Fsync(ctx context.Context, req *fuse.FsyncRequest) error { func (this *versionedFile) Fsync(ctx context.Context, req *fuse.FsyncRequest) error {
return nil return nil
} }
func (this *versionedFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { func (this *versionedFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
file, err := os.OpenFile(this.node.rebasedPath(), os.O_RDONLY, 0666) if this.handle == nil {
if err != nil { return errors.New("attempted to read unopened file")
return err
} }
defer file.Close()
resp.Data = make([]byte, req.Size) resp.Data = make([]byte, req.Size)
if _, err = file.ReadAt(resp.Data, req.Offset); err != nil { if _, err := this.handle.ReadAt(resp.Data, req.Offset); err != nil {
return err return err
} }
@ -94,10 +119,14 @@ func (this *versionedFile) Read(ctx context.Context, req *fuse.ReadRequest, resp
} }
func (this *versionedFile) ReadAll(ctx context.Context) ([]byte, error) { func (this *versionedFile) ReadAll(ctx context.Context) ([]byte, error) {
bytes, err := ioutil.ReadFile(this.node.rebasedPath()) if this.handle == nil {
if err != nil { return nil, errors.New("attempted to read unopened file")
}
data := make([]byte, this.node.info.Size())
if _, err := this.handle.Read(data); err != nil {
return nil, err return nil, err
} }
return bytes, nil return data, nil
} }