From 0b64b1feef1773a780e2a90fe96c83abb48a9501 Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Fri, 16 Jul 2021 13:41:22 +0800 Subject: [PATCH] vfs: Use fuse.Forget instead of cache TTL (#12) * vfs: Use fuse.Forget instead of cache TTL Signed-off-by: Xuanwo * Update docs Signed-off-by: Xuanwo --- README.md | 14 +++++++++++++- fuse/hanwen/fs.go | 4 ++++ meta/badger.go | 7 +------ meta/badger_bench_test.go | 5 ++--- meta/meta.go | 4 +--- vfs/dir.go | 4 ++-- vfs/fs.go | 29 ++++++++++++++++++++++------- 7 files changed, 45 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 76d795a..286aab1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ # BeyondFS -A high-performance, POSIX-ish File System based on [aos-dev/go-storage](https://github.com/aos-dev/go-storage). +A high-performance, POSIX-ish File System based on [beyondstorage/go-storage](https://github.com/beyondstorage/go-storage). + +## Design + +- Only cache metadata +- Sharable +- POSIX-ish + +Refer to [RFC-5: BeyondFS Design](./docs/rfcs/5-beyond-fs-design.md) to know more. + +## Current Status + +We are working on [implement a POSIX-ish file system that only caches metadata locally](https://github.com/beyondstorage/beyond-fs/issues/8) diff --git a/fuse/hanwen/fs.go b/fuse/hanwen/fs.go index 2cb14aa..ef0a26a 100644 --- a/fuse/hanwen/fs.go +++ b/fuse/hanwen/fs.go @@ -166,6 +166,10 @@ func (fs *FS) Lookup(cancel <-chan struct{}, header *fuse.InHeader, name string, } func (fs *FS) Forget(nodeid, nlookup uint64) { + err := fs.fs.DeleteInodeByID(nodeid) + if err != nil { + fs.logger.Error("forget", zap.Error(err)) + } } func (fs *FS) GetAttr(cancel <-chan struct{}, input *fuse.GetAttrIn, out *fuse.AttrOut) (code fuse.Status) { diff --git a/meta/badger.go b/meta/badger.go index 30a1e4d..0cb37cf 100644 --- a/meta/badger.go +++ b/meta/badger.go @@ -2,7 +2,6 @@ package meta import ( "fmt" - "time" "github.com/dgraph-io/badger/v3" ) @@ -38,7 +37,7 @@ func (db badgerDB) Get(key []byte) (value []byte, err error) { return v.ValueCopy(nil) } -func (db badgerDB) Set(key, value []byte, ttl time.Duration) (err error) { +func (db badgerDB) Set(key, value []byte) (err error) { txn := db.db.NewTransaction(true) defer txn.Discard() @@ -47,10 +46,6 @@ func (db badgerDB) Set(key, value []byte, ttl time.Duration) (err error) { Value: value, } - if ttl != 0 { - e.ExpiresAt = uint64(time.Now().Add(ttl).Unix()) - } - err = txn.SetEntry(e) if err != nil { return err diff --git a/meta/badger_bench_test.go b/meta/badger_bench_test.go index 3bbf0f8..5100c58 100644 --- a/meta/badger_bench_test.go +++ b/meta/badger_bench_test.go @@ -3,7 +3,6 @@ package meta import ( "bytes" "testing" - "time" ) func BenchmarkGet(b *testing.B) { @@ -16,7 +15,7 @@ func BenchmarkGet(b *testing.B) { key := bytes.Repeat([]byte{'a'}, 128) value := bytes.Repeat([]byte{'a'}, 1024) - err = srv.Set(key, value, time.Hour) + err = srv.Set(key, value) if err != nil { b.Error(err) return @@ -38,6 +37,6 @@ func BenchmarkSet(b *testing.B) { value := bytes.Repeat([]byte{'a'}, 1024) for i := 0; i < b.N; i++ { - _ = srv.Set(key, value, time.Hour) + _ = srv.Set(key, value) } } diff --git a/meta/meta.go b/meta/meta.go index 89c1ef4..8b86e7c 100644 --- a/meta/meta.go +++ b/meta/meta.go @@ -1,13 +1,11 @@ package meta -import "time" - type Service interface { // Get will get the value with specified key. // // value will be nil if key not found. Get(key []byte) (value []byte, err error) - Set(key, value []byte, ttl time.Duration) (err error) + Set(key, value []byte) (err error) Delete(key []byte) (err error) PrefixDelete(prefix []byte) (err error) Scan(prefix []byte) Iterator diff --git a/vfs/dir.go b/vfs/dir.go index 954ce5f..b5bb0a9 100644 --- a/vfs/dir.go +++ b/vfs/dir.go @@ -5,7 +5,6 @@ import ( "github.com/beyondstorage/beyond-fs/meta" "github.com/beyondstorage/go-storage/v4/types" "sync" - "time" ) type dirHandleMap struct { @@ -58,8 +57,9 @@ func (dh *DirHandle) Next() (ino *Inode, err error) { return nil, err } + // TODO: maybe we can read data from cache instead. ino = newInode(dh.ino.ID, o) - err = dh.fs.SetInode(ino, time.Hour) + err = dh.fs.SetInode(ino) if err != nil { return } diff --git a/vfs/fs.go b/vfs/fs.go index cabd7aa..217b13b 100644 --- a/vfs/fs.go +++ b/vfs/fs.go @@ -2,14 +2,13 @@ package vfs import ( "fmt" - "go.uber.org/atomic" - "time" _ "github.com/beyondstorage/go-service-fs/v3" _ "github.com/beyondstorage/go-service-s3/v2" "github.com/beyondstorage/go-storage/v4/pairs" "github.com/beyondstorage/go-storage/v4/services" "github.com/beyondstorage/go-storage/v4/types" + "go.uber.org/atomic" "go.uber.org/zap" "github.com/beyondstorage/beyond-fs/meta" @@ -65,7 +64,7 @@ func NewFS(cfg *Config) (fs *FS, err error) { o.ID = store.Metadata().WorkDir o.Path = "" o.Mode = types.ModeDir - err = fs.SetInode(newInode(1, o), 0) + err = fs.SetInode(newInode(1, o)) if err != nil { return nil, err } @@ -85,6 +84,10 @@ func (fs *FS) Delete(parent uint64, name string) (err error) { if err != nil { return } + err = fs.DeleteEntry(parent, name) + if err != nil { + return + } return } @@ -118,13 +121,13 @@ func (fs *FS) DeleteDirHandle(dhid uint64) (err error) { return nil } -func (fs *FS) SetInode(ino *Inode, ttl time.Duration) (err error) { +func (fs *FS) SetInode(ino *Inode) (err error) { bs, err := ino.MarshalMsg(nil) if err != nil { return fmt.Errorf("marshal inode: %w", err) } - err = fs.meta.Set(meta.InodeKey(ino.ID), bs, ttl) + err = fs.meta.Set(meta.InodeKey(ino.ID), bs) if err != nil { return fmt.Errorf("set inode: %w", err) } @@ -132,7 +135,7 @@ func (fs *FS) SetInode(ino *Inode, ttl time.Duration) (err error) { // Don't set entry key for root directory. return nil } - err = fs.meta.Set(meta.EntryKey(ino.ParentID, ino.Name), bs, ttl) + err = fs.meta.Set(meta.EntryKey(ino.ParentID, ino.Name), bs) if err != nil { return fmt.Errorf("set entry: %w", err) } @@ -162,7 +165,11 @@ func (fs *FS) DeleteInode(ino *Inode) (err error) { if err != nil { return fmt.Errorf("del inode: %w", err) } - err = fs.meta.Delete(meta.EntryKey(ino.ParentID, ino.Name)) + return +} + +func (fs *FS) DeleteInodeByID(id uint64) (err error) { + err = fs.meta.Delete(meta.InodeKey(id)) if err != nil { return fmt.Errorf("del inode: %w", err) } @@ -186,3 +193,11 @@ func (fs *FS) GetEntry(parent uint64, name string) (ino *Inode, err error) { } return } + +func (fs *FS) DeleteEntry(parent uint64, name string) (err error) { + err = fs.meta.Delete(meta.EntryKey(parent, name)) + if err != nil { + return fmt.Errorf("del inode: %w", err) + } + return +}