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:
parent
2ce6125fbc
commit
0b64b1feef
14
README.md
14
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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
29
vfs/fs.go
29
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue