Renaming vars

This commit is contained in:
Alex Yatskov 2015-06-17 20:18:55 +09:00
parent 48faaa74f4
commit b5dc9e3db7
8 changed files with 180 additions and 178 deletions

View File

@ -23,11 +23,12 @@
package main package main
import ( import (
"bazil.org/fuse/fs"
"io/ioutil" "io/ioutil"
"path" "path"
"path/filepath" "path/filepath"
"sort" "sort"
"bazil.org/fuse/fs"
) )
// //
@ -48,32 +49,32 @@ func newDatabase(dir string) (*database, error) {
return db, nil return db, nil
} }
func (this *database) load(dir string) error { func (db *database) load(dir string) error {
var err error var err error
this.base, err = filepath.Abs(dir) db.base, err = filepath.Abs(dir)
if err != nil { if err != nil {
return err return err
} }
if err := buildNewVersion(this.base); err != nil { if err := buildNewVersion(db.base); err != nil {
return err return err
} }
this.vers, err = this.buildVersions(this.base) db.vers, err = db.buildVersions(db.base)
if err != nil { if err != nil {
return err return err
} }
if lastVer := this.lastVersion(); lastVer != nil { if lastVer := db.lastVersion(); lastVer != nil {
return lastVer.resolve() return lastVer.resolve()
} }
return nil return nil
} }
func (this *database) save() error { func (db *database) save() error {
for _, ver := range this.vers { for _, ver := range db.vers {
if err := ver.finalize(); err != nil { if err := ver.finalize(); err != nil {
return err return err
} }
@ -82,7 +83,7 @@ func (this *database) save() error {
return nil return nil
} }
func (this *database) buildVersions(base string) (versionList, error) { func (db *database) buildVersions(base string) (versionList, error) {
nodes, err := ioutil.ReadDir(base) nodes, err := ioutil.ReadDir(base)
if err != nil { if err != nil {
return nil, err return nil, err
@ -99,7 +100,7 @@ func (this *database) buildVersions(base string) (versionList, error) {
return nil, err return nil, err
} }
ver, err := newVersion(path.Join(base, node.Name()), timestamp, this) ver, err := newVersion(path.Join(base, node.Name()), timestamp, db)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -118,15 +119,15 @@ func (this *database) buildVersions(base string) (versionList, error) {
return vers, nil return vers, nil
} }
func (this *database) lastVersion() *version { func (db *database) lastVersion() *version {
count := len(this.vers) count := len(db.vers)
if count == 0 { if count == 0 {
return nil return nil
} }
return this.vers[count-1] return db.vers[count-1]
} }
func (this *database) Root() (fs.Node, error) { func (db *database) Root() (fs.Node, error) {
return this.lastVersion().root, nil return db.lastVersion().root, nil
} }

90
dir.go
View File

@ -51,89 +51,89 @@ func newVersionedDir(node *versionedNode, parent *versionedDir) *versionedDir {
return &versionedDir{dirs, files, node, allocInode(), parent} return &versionedDir{dirs, files, node, allocInode(), parent}
} }
func (this *versionedDir) version() error { func (vd *versionedDir) version() error {
if this.node.flags&NodeFlagVer == NodeFlagVer { if vd.node.flags&NodeFlagVer == NodeFlagVer {
return nil return nil
} }
node := newVersionedNode(this.node.path, this.node.ver.db.lastVersion(), this.node, NodeFlagDir|NodeFlagVer) node := newVersionedNode(vd.node.path, vd.node.ver.db.lastVersion(), vd.node, NodeFlagDir|NodeFlagVer)
if err := os.MkdirAll(node.rebasedPath(), 0755); err != nil { if err := os.MkdirAll(node.rebasedPath(), 0755); err != nil {
return err return err
} }
node.ver.meta.modifyNode(node.path) node.ver.meta.modifyNode(node.path)
this.node = node vd.node = node
return nil return nil
} }
func (this *versionedDir) createDir(name string) (*versionedDir, error) { func (vd *versionedDir) createDir(name string) (*versionedDir, error) {
if err := this.version(); err != nil { if err := vd.version(); err != nil {
return nil, err return nil, err
} }
childPath := path.Join(this.node.path, name) childPath := path.Join(vd.node.path, name)
if err := os.Mkdir(this.node.ver.rebasePath(childPath), 0755); err != nil { if err := os.Mkdir(vd.node.ver.rebasePath(childPath), 0755); err != nil {
return nil, err return nil, err
} }
node := newVersionedNode(childPath, this.node.ver, nil, NodeFlagDir) node := newVersionedNode(childPath, vd.node.ver, nil, NodeFlagDir)
dir := newVersionedDir(node, this) dir := newVersionedDir(node, vd)
this.dirs[name] = dir vd.dirs[name] = dir
node.ver.meta.createNode(node.path) node.ver.meta.createNode(node.path)
return dir, nil return dir, nil
} }
func (this *versionedDir) createFile(name string, flags int) (*versionedFile, error) { func (vd *versionedDir) createFile(name string, flags int) (*versionedFile, error) {
if err := this.version(); err != nil { if err := vd.version(); err != nil {
return nil, err return nil, err
} }
childPath := path.Join(this.node.path, name) childPath := path.Join(vd.node.path, name)
handle, err := os.OpenFile(this.node.ver.rebasePath(childPath), flags, 0644) handle, err := os.OpenFile(vd.node.ver.rebasePath(childPath), flags, 0644)
if err != nil { if err != nil {
return nil, err return nil, err
} }
node := newVersionedNode(childPath, this.node.ver, nil, 0) node := newVersionedNode(childPath, vd.node.ver, nil, 0)
file := newVersionedFile(node, this) file := newVersionedFile(node, vd)
file.handle = handle file.handle = handle
this.files[name] = file vd.files[name] = file
node.ver.meta.createNode(node.path) node.ver.meta.createNode(node.path)
return file, nil return file, nil
} }
func (this *versionedDir) Attr(ctx context.Context, attr *fuse.Attr) error { func (vd *versionedDir) Attr(ctx context.Context, attr *fuse.Attr) error {
if err := this.node.attr(attr); err != nil { if err := vd.node.attr(attr); err != nil {
return err return err
} }
attr.Inode = this.inode attr.Inode = vd.inode
return nil return nil
} }
func (this *versionedDir) Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error { func (vd *versionedDir) Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error {
return this.Attr(ctx, &resp.Attr) return vd.Attr(ctx, &resp.Attr)
} }
func (this *versionedDir) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { func (vd *versionedDir) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error {
this.version() vd.version()
return this.node.setAttr(req, resp) return vd.node.setAttr(req, resp)
} }
func (this *versionedDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (node fs.Node, handle fs.Handle, err error) { func (vd *versionedDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (node fs.Node, handle fs.Handle, err error) {
if req.Mode.IsDir() { if req.Mode.IsDir() {
var dir *versionedDir var dir *versionedDir
if dir, err = this.createDir(req.Name); err == nil { if dir, err = vd.createDir(req.Name); err == nil {
node = dir node = dir
handle = dir handle = dir
} }
} else if req.Mode.IsRegular() { } else if req.Mode.IsRegular() {
var file *versionedFile var file *versionedFile
if file, err = this.createFile(req.Name, int(req.Flags)); err == nil { if file, err = vd.createFile(req.Name, int(req.Flags)); err == nil {
node = file node = file
handle = file handle = file
} }
@ -144,13 +144,13 @@ func (this *versionedDir) Create(ctx context.Context, req *fuse.CreateRequest, r
return return
} }
func (this *versionedDir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) { func (vd *versionedDir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
return this.createDir(req.Name) return vd.createDir(req.Name)
} }
func (this *versionedDir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { func (vd *versionedDir) Remove(ctx context.Context, req *fuse.RemoveRequest) error {
if req.Dir { if req.Dir {
node := this.dirs[req.Name].node node := vd.dirs[req.Name].node
ver := node.ver ver := node.ver
if node.flags&NodeFlagVer == NodeFlagVer { if node.flags&NodeFlagVer == NodeFlagVer {
@ -162,9 +162,9 @@ func (this *versionedDir) Remove(ctx context.Context, req *fuse.RemoveRequest) e
} }
ver.meta.removeNode(node.path) ver.meta.removeNode(node.path)
delete(this.dirs, req.Name) delete(vd.dirs, req.Name)
} else { } else {
node := this.files[req.Name].node node := vd.files[req.Name].node
ver := node.ver ver := node.ver
if node.flags&NodeFlagVer == NodeFlagVer { if node.flags&NodeFlagVer == NodeFlagVer {
@ -176,25 +176,25 @@ func (this *versionedDir) Remove(ctx context.Context, req *fuse.RemoveRequest) e
} }
ver.meta.removeNode(node.path) ver.meta.removeNode(node.path)
delete(this.files, req.Name) delete(vd.files, req.Name)
} }
return nil return nil
} }
func (this *versionedDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { func (vd *versionedDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
entries := []fuse.Dirent{{Inode: this.inode, Name: ".", Type: fuse.DT_Dir}} entries := []fuse.Dirent{{Inode: vd.inode, Name: ".", Type: fuse.DT_Dir}}
if this.parent != nil { if vd.parent != nil {
entry := fuse.Dirent{Inode: this.parent.inode, Name: "..", Type: fuse.DT_Dir} entry := fuse.Dirent{Inode: vd.parent.inode, Name: "..", Type: fuse.DT_Dir}
entries = append(entries, entry) entries = append(entries, entry)
} }
for name, dir := range this.dirs { for name, dir := range vd.dirs {
entry := fuse.Dirent{Inode: dir.inode, Name: name, Type: fuse.DT_Dir} entry := fuse.Dirent{Inode: dir.inode, Name: name, Type: fuse.DT_Dir}
entries = append(entries, entry) entries = append(entries, entry)
} }
for name, file := range this.files { for name, file := range vd.files {
entry := fuse.Dirent{Inode: file.inode, Name: name, Type: fuse.DT_File} entry := fuse.Dirent{Inode: file.inode, Name: name, Type: fuse.DT_File}
entries = append(entries, entry) entries = append(entries, entry)
} }
@ -202,12 +202,12 @@ func (this *versionedDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error)
return entries, nil return entries, nil
} }
func (this *versionedDir) Lookup(ctx context.Context, name string) (fs.Node, error) { func (vd *versionedDir) Lookup(ctx context.Context, name string) (fs.Node, error) {
if dir, ok := this.dirs[name]; ok { if dir, ok := vd.dirs[name]; ok {
return dir, nil return dir, nil
} }
if file, ok := this.files[name]; ok { if file, ok := vd.files[name]; ok {
return file, nil return file, nil
} }

91
file.go
View File

@ -24,7 +24,6 @@ package main
import ( import (
"errors" "errors"
"io"
"os" "os"
"bazil.org/fuse" "bazil.org/fuse"
@ -47,94 +46,94 @@ func newVersionedFile(node *versionedNode, parent *versionedDir) *versionedFile
return &versionedFile{node, allocInode(), parent, nil} return &versionedFile{node, allocInode(), parent, nil}
} }
func (this *versionedFile) version() error { func (vf *versionedFile) version() error {
if this.node.flags&NodeFlagVer == NodeFlagVer { if vf.node.flags&NodeFlagVer == NodeFlagVer {
return nil return nil
} }
node := newVersionedNode(this.node.path, this.node.ver.db.lastVersion(), this.node, NodeFlagVer) node := newVersionedNode(vf.node.path, vf.node.ver.db.lastVersion(), vf.node, NodeFlagVer)
if _, err := fileCopy(this.node.rebasedPath(), node.rebasedPath()); err != nil { if _, err := fileCopy(vf.node.rebasedPath(), node.rebasedPath()); err != nil {
return err return err
} }
node.ver.meta.modifyNode(node.path) node.ver.meta.modifyNode(node.path)
this.node = node vf.node = node
return nil return nil
} }
func (this *versionedFile) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) { func (vf *versionedFile) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
if this.handle != nil { if vf.handle != nil {
return nil, errors.New("attempted to open already opened file") return nil, errors.New("attempted to open already opened file")
} }
if !req.Flags.IsReadOnly() { if !req.Flags.IsReadOnly() {
if err := this.version(); err != nil { if err := vf.version(); err != nil {
return nil, err return nil, err
} }
} }
handle, err := os.OpenFile(this.node.rebasedPath(), int(req.Flags), 0644) handle, err := os.OpenFile(vf.node.rebasedPath(), int(req.Flags), 0644)
if err != nil { if err != nil {
return nil, err return nil, err
} }
this.handle = handle vf.handle = handle
return this, nil return vf, nil
} }
func (this *versionedFile) Attr(ctx context.Context, attr *fuse.Attr) error { func (vf *versionedFile) Attr(ctx context.Context, attr *fuse.Attr) error {
this.node.attr(attr) vf.node.attr(attr)
attr.Inode = this.inode attr.Inode = vf.inode
return nil return nil
} }
func (this *versionedFile) Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error { func (vf *versionedFile) Getattr(ctx context.Context, req *fuse.GetattrRequest, resp *fuse.GetattrResponse) error {
return this.Attr(ctx, &resp.Attr) return vf.Attr(ctx, &resp.Attr)
} }
func (this *versionedFile) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { func (vf *versionedFile) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error {
return this.node.setAttr(req, resp) return vf.node.setAttr(req, resp)
} }
func (this *versionedFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { func (vf *versionedFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
if this.handle == nil { if vf.handle == nil {
return errors.New("attempted to read from unopened file") return errors.New("attempted to read from unopened file")
} }
resp.Data = make([]byte, req.Size) resp.Data = make([]byte, req.Size)
if _, err := this.handle.ReadAt(resp.Data, req.Offset); err != nil { if _, err := vf.handle.ReadAt(resp.Data, req.Offset); err != nil {
return err return err
} }
return nil return nil
} }
func (this *versionedFile) ReadAll(ctx context.Context) ([]byte, error) { func (vf *versionedFile) ReadAll(ctx context.Context) ([]byte, error) {
if this.handle == nil { if vf.handle == nil {
return nil, errors.New("attempted to read from unopened file") return nil, errors.New("attempted to read from unopened file")
} }
info, err := os.Stat(this.node.rebasedPath()) info, err := os.Stat(vf.node.rebasedPath())
if err != nil { if err != nil {
return nil, err return nil, err
} }
data := make([]byte, info.Size()) data := make([]byte, info.Size())
if _, err := this.handle.Read(data); err != nil { if _, err := vf.handle.Read(data); err != nil {
return nil, err return nil, err
} }
return data, nil return data, nil
} }
func (this *versionedFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error { func (vf *versionedFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error {
if this.handle == nil { if vf.handle == nil {
return errors.New("attempted to write to unopened file") return errors.New("attempted to write to unopened file")
} }
size, err := this.handle.WriteAt(req.Data, req.Offset) size, err := vf.handle.WriteAt(req.Data, req.Offset)
if err != nil { if err != nil {
return err return err
} }
@ -143,41 +142,21 @@ func (this *versionedFile) Write(ctx context.Context, req *fuse.WriteRequest, re
return nil return nil
} }
func (this *versionedFile) Release(ctx context.Context, req *fuse.ReleaseRequest) error { func (vf *versionedFile) Release(ctx context.Context, req *fuse.ReleaseRequest) error {
if this.handle == nil { if vf.handle == nil {
return errors.New("attempted to release unopened file") return errors.New("attempted to release unopened file")
} }
this.handle.Close() vf.handle.Close()
this.handle = nil vf.handle = nil
return nil return nil
} }
func (this *versionedFile) Fsync(ctx context.Context, req *fuse.FsyncRequest) error { func (vf *versionedFile) Fsync(ctx context.Context, req *fuse.FsyncRequest) error {
if this.handle == nil { if vf.handle == nil {
return errors.New("attempted to sync unopened file") return errors.New("attempted to sync unopened file")
} }
return this.handle.Sync() return vf.handle.Sync()
}
//
// file helpers
//
func fileCopy(src, dst string) (int64, error) {
srcFile, err := os.Open(src)
if err != nil {
return 0, err
}
defer srcFile.Close()
dstFile, err := os.Create(dst)
if err != nil {
return 0, err
}
defer dstFile.Close()
return io.Copy(srcFile, dstFile)
} }

36
meta.go
View File

@ -48,8 +48,8 @@ func newVersionMetadata(path string) (*versionMetadata, error) {
return meta, nil return meta, nil
} }
func (this *versionMetadata) filter(nodes versionedNodeMap) { func (m *versionMetadata) filter(nodes versionedNodeMap) {
for _, delPath := range this.Deleted { for _, delPath := range m.Deleted {
for name, node := range nodes { for name, node := range nodes {
if strings.HasPrefix(node.path, delPath) { if strings.HasPrefix(node.path, delPath) {
delete(nodes, name) delete(nodes, name)
@ -58,47 +58,47 @@ func (this *versionMetadata) filter(nodes versionedNodeMap) {
} }
} }
func (this *versionMetadata) removeNode(path string) { func (m *versionMetadata) removeNode(path string) {
this.Deleted = append(this.Deleted, path) m.Deleted = append(m.Deleted, path)
this.dirty = true m.dirty = true
} }
func (this *versionMetadata) createNode(path string) { func (m *versionMetadata) createNode(path string) {
this.dirty = true m.dirty = true
} }
func (this *versionMetadata) modifyNode(path string) { func (m *versionMetadata) modifyNode(path string) {
this.dirty = true m.dirty = true
} }
func (this *versionMetadata) load() error { func (m *versionMetadata) load() error {
this.dirty = false m.dirty = false
if _, err := os.Stat(this.path); os.IsNotExist(err) { if _, err := os.Stat(m.path); os.IsNotExist(err) {
return nil return nil
} }
bytes, err := ioutil.ReadFile(this.path) bytes, err := ioutil.ReadFile(m.path)
if err != nil { if err != nil {
return err return err
} }
if err := json.Unmarshal(bytes, &this); err != nil { if err := json.Unmarshal(bytes, &m); err != nil {
return err return err
} }
return nil return nil
} }
func (this *versionMetadata) save() error { func (m *versionMetadata) save() error {
if !this.dirty { if !m.dirty {
return nil return nil
} }
js, err := json.Marshal(this) js, err := json.Marshal(m)
if err != nil { if err != nil {
return err return err
} }
return ioutil.WriteFile(this.path, js, 0644) return ioutil.WriteFile(m.path, js, 0644)
} }

26
node.go
View File

@ -50,13 +50,13 @@ func newVersionedNode(path string, ver *version, parent *versionedNode, flags in
return &versionedNode{path, ver, parent, flags} return &versionedNode{path, ver, parent, flags}
} }
func (this *versionedNode) setAttr(req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error { func (n *versionedNode) setAttr(req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error {
if err := this.attr(&resp.Attr); err != nil { if err := n.attr(&resp.Attr); err != nil {
return err return err
} }
if req.Valid&fuse.SetattrMode != 0 { if req.Valid&fuse.SetattrMode != 0 {
if err := os.Chmod(this.rebasedPath(), req.Mode); err != nil { if err := os.Chmod(n.rebasedPath(), req.Mode); err != nil {
return err return err
} }
@ -71,7 +71,7 @@ func (this *versionedNode) setAttr(req *fuse.SetattrRequest, resp *fuse.SetattrR
resp.Attr.Uid = req.Uid resp.Attr.Uid = req.Uid
} }
if err := os.Chown(this.rebasedPath(), int(resp.Attr.Uid), int(resp.Attr.Gid)); err != nil { if err := os.Chown(n.rebasedPath(), int(resp.Attr.Uid), int(resp.Attr.Gid)); err != nil {
return err return err
} }
} }
@ -84,7 +84,7 @@ func (this *versionedNode) setAttr(req *fuse.SetattrRequest, resp *fuse.SetattrR
resp.Attr.Mtime = req.Mtime resp.Attr.Mtime = req.Mtime
} }
if err := os.Chtimes(this.rebasedPath(), resp.Attr.Atime, resp.Attr.Mtime); err != nil { if err := os.Chtimes(n.rebasedPath(), resp.Attr.Atime, resp.Attr.Mtime); err != nil {
return err return err
} }
} }
@ -92,25 +92,25 @@ func (this *versionedNode) setAttr(req *fuse.SetattrRequest, resp *fuse.SetattrR
return nil return nil
} }
func (this *versionedNode) rebasedPath() string { func (n *versionedNode) rebasedPath() string {
return this.ver.rebasePath(this.path) return n.ver.rebasePath(n.path)
} }
func (this *versionedNode) owner(stat syscall.Stat_t) (gid, uid uint32) { func (n *versionedNode) owner(stat syscall.Stat_t) (gid, uid uint32) {
gid = stat.Gid gid = stat.Gid
uid = stat.Uid uid = stat.Uid
return return
} }
func (this *versionedNode) times(stat syscall.Stat_t) (atime, mtime, ctime time.Time) { func (n *versionedNode) times(stat syscall.Stat_t) (atime, mtime, ctime time.Time) {
atime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) atime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
mtime = time.Unix(int64(stat.Mtim.Sec), int64(stat.Mtim.Nsec)) mtime = time.Unix(int64(stat.Mtim.Sec), int64(stat.Mtim.Nsec))
ctime = time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)) ctime = time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec))
return return
} }
func (this *versionedNode) attr(attr *fuse.Attr) error { func (n *versionedNode) attr(attr *fuse.Attr) error {
info, err := os.Stat(this.rebasedPath()) info, err := os.Stat(n.rebasedPath())
if err != nil { if err != nil {
return err return err
} }
@ -119,10 +119,10 @@ func (this *versionedNode) attr(attr *fuse.Attr) error {
attr.Size = uint64(stat.Size) attr.Size = uint64(stat.Size)
attr.Blocks = uint64(stat.Blocks) attr.Blocks = uint64(stat.Blocks)
attr.Atime, attr.Mtime, attr.Ctime = this.times(*stat) attr.Atime, attr.Mtime, attr.Ctime = n.times(*stat)
attr.Mode = info.Mode() attr.Mode = info.Mode()
attr.Nlink = uint32(stat.Nlink) attr.Nlink = uint32(stat.Nlink)
attr.Gid, attr.Uid = this.owner(*stat) attr.Gid, attr.Uid = n.owner(*stat)
attr.Rdev = uint32(stat.Rdev) attr.Rdev = uint32(stat.Rdev)
return nil return nil

22
util.go
View File

@ -22,7 +22,11 @@
package main package main
import "sync/atomic" import (
"io"
"os"
"sync/atomic"
)
// //
// utilities // utilities
@ -33,3 +37,19 @@ var inodeCnt uint64
func allocInode() uint64 { func allocInode() uint64 {
return atomic.AddUint64(&inodeCnt, 1) return atomic.AddUint64(&inodeCnt, 1)
} }
func fileCopy(src, dst string) (int64, error) {
srcFile, err := os.Open(src)
if err != nil {
return 0, err
}
defer srcFile.Close()
dstFile, err := os.Create(dst)
if err != nil {
return 0, err
}
defer dstFile.Close()
return io.Copy(srcFile, dstFile)
}

View File

@ -23,7 +23,6 @@
package main package main
import ( import (
"bazil.org/fuse/fs"
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -33,6 +32,8 @@ import (
"regexp" "regexp"
"strconv" "strconv"
"time" "time"
"bazil.org/fuse/fs"
) )
// //
@ -57,22 +58,22 @@ func newVersion(base string, timestamp time.Time, db *database) (*version, error
return &version{base, nil, timestamp, meta, nil, db}, nil return &version{base, nil, timestamp, meta, nil, db}, nil
} }
func (this *version) scanDir(path string) (versionedNodeMap, error) { func (v *version) scanDir(path string) (versionedNodeMap, error) {
var baseNodes versionedNodeMap var baseNodes versionedNodeMap
if this.parent != nil { if v.parent != nil {
var err error var err error
baseNodes, err = this.parent.scanDir(path) baseNodes, err = v.parent.scanDir(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
this.meta.filter(baseNodes) v.meta.filter(baseNodes)
} }
ownNodes := make(versionedNodeMap) ownNodes := make(versionedNodeMap)
{ {
infos, err := ioutil.ReadDir(this.rebasePath(path)) infos, err := ioutil.ReadDir(v.rebasePath(path))
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
if err != nil { if err != nil {
return nil, err return nil, err
@ -87,11 +88,11 @@ func (this *version) scanDir(path string) (versionedNodeMap, error) {
childName := info.Name() childName := info.Name()
childPath := filepath.Join(path, childName) childPath := filepath.Join(path, childName)
ownNodes[childName] = newVersionedNode(childPath, this, nil, childFlags) ownNodes[childName] = newVersionedNode(childPath, v, nil, childFlags)
} }
} }
this.meta.filter(ownNodes) v.meta.filter(ownNodes)
} }
if baseNodes == nil { if baseNodes == nil {
@ -106,8 +107,8 @@ func (this *version) scanDir(path string) (versionedNodeMap, error) {
return baseNodes, nil return baseNodes, nil
} }
func (this *version) buildDir(dir *versionedDir) error { func (v *version) buildDir(dir *versionedDir) error {
nodes, err := this.scanDir(dir.node.path) nodes, err := v.scanDir(dir.node.path)
if err != nil { if err != nil {
return err return err
} }
@ -115,7 +116,7 @@ func (this *version) buildDir(dir *versionedDir) error {
for name, node := range nodes { for name, node := range nodes {
if node.flags&NodeFlagDir == NodeFlagDir { if node.flags&NodeFlagDir == NodeFlagDir {
subDir := newVersionedDir(node, dir) subDir := newVersionedDir(node, dir)
if err := this.buildDir(subDir); err != nil { if err := v.buildDir(subDir); err != nil {
return err return err
} }
@ -128,29 +129,29 @@ func (this *version) buildDir(dir *versionedDir) error {
return nil return nil
} }
func (this *version) resolve() error { func (v *version) resolve() error {
node := newVersionedNode("/", this, nil, NodeFlagDir) node := newVersionedNode("/", v, nil, NodeFlagDir)
root := newVersionedDir(node, nil) root := newVersionedDir(node, nil)
if err := this.buildDir(root); err != nil { if err := v.buildDir(root); err != nil {
return err return err
} }
this.root = root v.root = root
return nil return nil
} }
func (this *version) rebasePath(paths ...string) string { func (v *version) rebasePath(paths ...string) string {
combined := append([]string{this.base, "root"}, paths...) combined := append([]string{v.base, "root"}, paths...)
return filepath.Join(combined...) return filepath.Join(combined...)
} }
func (this *version) finalize() error { func (v *version) finalize() error {
return this.meta.save() return v.meta.save()
} }
func (this *version) Root() (fs.Node, error) { func (v *version) Root() (fs.Node, error) {
return this.root, nil return v.root, nil
} }
// //
@ -159,16 +160,16 @@ func (this *version) Root() (fs.Node, error) {
type versionList []*version type versionList []*version
func (this versionList) Len() int { func (v versionList) Len() int {
return len(this) return len(v)
} }
func (this versionList) Swap(i, j int) { func (v versionList) Swap(i, j int) {
this[i], this[j] = this[j], this[i] v[i], v[j] = v[j], v[i]
} }
func (this versionList) Less(i, j int) bool { func (v versionList) Less(i, j int) bool {
return this[i].timestamp.Unix() < this[j].timestamp.Unix() return v[i].timestamp.Unix() < v[j].timestamp.Unix()
} }
// //

7
vfs.go
View File

@ -23,13 +23,14 @@
package main package main
import ( import (
"bazil.org/fuse"
"bazil.org/fuse/fs"
_ "bazil.org/fuse/fs/fstestutil"
"flag" "flag"
"fmt" "fmt"
"log" "log"
"os" "os"
"bazil.org/fuse"
"bazil.org/fuse/fs"
_ "bazil.org/fuse/fs/fstestutil"
) )
func usage() { func usage() {