vfs: Use fuse.Forget instead of cache TTL (#12)

* vfs: Use fuse.Forget instead of cache TTL

Signed-off-by: Xuanwo <github@xuanwo.io>

* Update docs

Signed-off-by: Xuanwo <github@xuanwo.io>
This commit is contained in:
Xuanwo 2021-07-16 13:41:22 +08:00 committed by GitHub
parent 2ce6125fbc
commit 0b64b1feef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 22 deletions

View File

@ -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)

View File

@ -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) {

View File

@ -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

View File

@ -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)
}
}

View File

@ -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

View File

@ -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
}

View File

@ -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
}