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 # 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) { 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) { 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 ( import (
"fmt" "fmt"
"time"
"github.com/dgraph-io/badger/v3" "github.com/dgraph-io/badger/v3"
) )
@ -38,7 +37,7 @@ func (db badgerDB) Get(key []byte) (value []byte, err error) {
return v.ValueCopy(nil) 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) txn := db.db.NewTransaction(true)
defer txn.Discard() defer txn.Discard()
@ -47,10 +46,6 @@ func (db badgerDB) Set(key, value []byte, ttl time.Duration) (err error) {
Value: value, Value: value,
} }
if ttl != 0 {
e.ExpiresAt = uint64(time.Now().Add(ttl).Unix())
}
err = txn.SetEntry(e) err = txn.SetEntry(e)
if err != nil { if err != nil {
return err return err

View File

@ -3,7 +3,6 @@ package meta
import ( import (
"bytes" "bytes"
"testing" "testing"
"time"
) )
func BenchmarkGet(b *testing.B) { func BenchmarkGet(b *testing.B) {
@ -16,7 +15,7 @@ func BenchmarkGet(b *testing.B) {
key := bytes.Repeat([]byte{'a'}, 128) key := bytes.Repeat([]byte{'a'}, 128)
value := bytes.Repeat([]byte{'a'}, 1024) value := bytes.Repeat([]byte{'a'}, 1024)
err = srv.Set(key, value, time.Hour) err = srv.Set(key, value)
if err != nil { if err != nil {
b.Error(err) b.Error(err)
return return
@ -38,6 +37,6 @@ func BenchmarkSet(b *testing.B) {
value := bytes.Repeat([]byte{'a'}, 1024) value := bytes.Repeat([]byte{'a'}, 1024)
for i := 0; i < b.N; i++ { 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 package meta
import "time"
type Service interface { type Service interface {
// Get will get the value with specified key. // Get will get the value with specified key.
// //
// value will be nil if key not found. // value will be nil if key not found.
Get(key []byte) (value []byte, err error) 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) Delete(key []byte) (err error)
PrefixDelete(prefix []byte) (err error) PrefixDelete(prefix []byte) (err error)
Scan(prefix []byte) Iterator Scan(prefix []byte) Iterator

View File

@ -5,7 +5,6 @@ import (
"github.com/beyondstorage/beyond-fs/meta" "github.com/beyondstorage/beyond-fs/meta"
"github.com/beyondstorage/go-storage/v4/types" "github.com/beyondstorage/go-storage/v4/types"
"sync" "sync"
"time"
) )
type dirHandleMap struct { type dirHandleMap struct {
@ -58,8 +57,9 @@ func (dh *DirHandle) Next() (ino *Inode, err error) {
return nil, err return nil, err
} }
// TODO: maybe we can read data from cache instead.
ino = newInode(dh.ino.ID, o) ino = newInode(dh.ino.ID, o)
err = dh.fs.SetInode(ino, time.Hour) err = dh.fs.SetInode(ino)
if err != nil { if err != nil {
return return
} }

View File

@ -2,14 +2,13 @@ package vfs
import ( import (
"fmt" "fmt"
"go.uber.org/atomic"
"time"
_ "github.com/beyondstorage/go-service-fs/v3" _ "github.com/beyondstorage/go-service-fs/v3"
_ "github.com/beyondstorage/go-service-s3/v2" _ "github.com/beyondstorage/go-service-s3/v2"
"github.com/beyondstorage/go-storage/v4/pairs" "github.com/beyondstorage/go-storage/v4/pairs"
"github.com/beyondstorage/go-storage/v4/services" "github.com/beyondstorage/go-storage/v4/services"
"github.com/beyondstorage/go-storage/v4/types" "github.com/beyondstorage/go-storage/v4/types"
"go.uber.org/atomic"
"go.uber.org/zap" "go.uber.org/zap"
"github.com/beyondstorage/beyond-fs/meta" "github.com/beyondstorage/beyond-fs/meta"
@ -65,7 +64,7 @@ func NewFS(cfg *Config) (fs *FS, err error) {
o.ID = store.Metadata().WorkDir o.ID = store.Metadata().WorkDir
o.Path = "" o.Path = ""
o.Mode = types.ModeDir o.Mode = types.ModeDir
err = fs.SetInode(newInode(1, o), 0) err = fs.SetInode(newInode(1, o))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -85,6 +84,10 @@ func (fs *FS) Delete(parent uint64, name string) (err error) {
if err != nil { if err != nil {
return return
} }
err = fs.DeleteEntry(parent, name)
if err != nil {
return
}
return return
} }
@ -118,13 +121,13 @@ func (fs *FS) DeleteDirHandle(dhid uint64) (err error) {
return nil 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) bs, err := ino.MarshalMsg(nil)
if err != nil { if err != nil {
return fmt.Errorf("marshal inode: %w", err) 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 { if err != nil {
return fmt.Errorf("set inode: %w", err) 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. // Don't set entry key for root directory.
return nil 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 { if err != nil {
return fmt.Errorf("set entry: %w", err) return fmt.Errorf("set entry: %w", err)
} }
@ -162,7 +165,11 @@ func (fs *FS) DeleteInode(ino *Inode) (err error) {
if err != nil { if err != nil {
return fmt.Errorf("del inode: %w", err) 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 { if err != nil {
return fmt.Errorf("del inode: %w", err) return fmt.Errorf("del inode: %w", err)
} }
@ -186,3 +193,11 @@ func (fs *FS) GetEntry(parent uint64, name string) (ino *Inode, err error) {
} }
return 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
}