Skip to content
This repository has been archived by the owner on Jun 19, 2023. It is now read-only.

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
djdv committed Jun 29, 2019
1 parent 95220b3 commit 9f28d54
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 54 deletions.
24 changes: 14 additions & 10 deletions filesystem/interface/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,25 @@ import (

type (
ParseFn func(ctx context.Context, name string) (Node, error)
Kind int
Flag string
Flags []struct{Flag;bool}
Kind int
Flag string
Flags []struct {
Flag
bool
}
)

const (
FRead Flag ="File Read"
FWrite = "File Write"
FSync = "File Sync"
FRead Flag = "File Read"
FWrite = "File Write"
FSync = "File Sync"
)

const (
UfsFile = Kind(unixfs.TFile)
UfsFile = Kind(unixfs.TFile)
UfsDirectory = Kind(unixfs.TDirectory)
UfsHAMT = Kind(unixfs.THAMTShard)
UfsSymlink = Kind(unixfs.TSymlink)
UfsHAMT = Kind(unixfs.THAMTShard)
UfsSymlink = Kind(unixfs.TSymlink)
)

type FsError interface {
Expand All @@ -48,7 +51,8 @@ var (
ErrRoot = FsError(errors.New("root initialization exception"))
ErrRecurse = FsError(errors.New("hit recursion limit"))
//
ErrNoHandler = FsError(errors.New("no handler registered for this request"))
ErrNoHandler = FsError(errors.New("no handler registered for this request"))
ErrNotImplemented = FsError(errors.New("operation not implemented"))
)

// Provides standard convention wrappers around an index
Expand Down
58 changes: 42 additions & 16 deletions filesystem/node/soft/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fsnode

import (
"context"
"strings"
"sync"

"github.com/billziss-gh/cgofuse/fuse"
Expand All @@ -11,7 +12,7 @@ import (

type BaseNode struct {
sync.RWMutex
path string
path string
version uint

metadata Metadata
Expand All @@ -20,20 +21,20 @@ type BaseNode struct {
// implementation of Metadata interface
type Metadata struct {
//apiPath string
fStat fuse.Stat_t
fStat fuse.Stat_t
ipfsFlags fs.Flags
}

func (md *Metadata) Type() fs.Kind {
t := coreiface.TUnknown
t := coreiface.TUnknown

switch md.fStat.Mode & fuse.S_IFMT {
case fuse.S_IFREG:
t= coreiface.TFile
t = coreiface.TFile
case fuse.S_IFDIR:
t= coreiface.TDirectory
t = coreiface.TDirectory
case fuse.S_IFLNK:
t= coreiface.TSymlink
t = coreiface.TSymlink
}

return fs.Kind(t)
Expand All @@ -48,7 +49,7 @@ func (md *Metadata) Size() uint {
}

// conversion between fStat and interface
func (rb *BaseNode) Metadata() (fs.Metadata, error) {
func (rb *BaseNode) Metadata(_ context.Context) (fs.Metadata, error) {
return &rb.metadata, nil
}

Expand All @@ -60,14 +61,35 @@ func (rb *BaseNode) String() string {
return rb.path
}

func (rb *BaseNode) Remove(_ context.Context) (int, error) {
return -fuse.EROFS, fs.ErrReadOnly
func (rb *BaseNode) Remove(_ context.Context) error {
return fs.ErrNotImplemented
}

func (rb *BaseNode) Create(_ context.Context, _ fs.Kind) error {
return fs.ErrNotImplemented
}

//Core API Path interface
func (rb *BaseNode) IsValid() error {
return fs.ErrNotImplemented
}

func (rb *BaseNode) Mutable() bool {
return false
}

func (rb *BaseNode) Namespace() string {
i := strings.IndexRune(rb.path[1:], '/')
if i == -1 {
return "root"
}
return rb.path[1:i]
}

const (
IRWXA = fuse.S_IRWXU | fuse.S_IRWXG | fuse.S_IRWXO
IRXA = IRWXA &^ (fuse.S_IWUSR | fuse.S_IWGRP | fuse.S_IWOTH)
)
IRXA = IRWXA &^ (fuse.S_IWUSR | fuse.S_IWGRP | fuse.S_IWOTH)
)

func (rb *BaseNode) InitMetadata(_ context.Context) (*fuse.Stat_t, error) {
now := fuse.Now()
Expand All @@ -88,10 +110,14 @@ func (rb *BaseNode) typeCheck(nodeType fs.Kind) (err error) {

func typeCheck(pMode uint32, nodeType fs.Kind) bool {
switch nodeType {
case fs.UfsFile: return fuse.S_IFREG == (pMode & fuse.S_IFDIR)
case fs.UfsDirectory: return fuse.S_IFDIR == (pMode & fuse.S_IFDIR)
case fs.UfsSymlink: return fuse.S_IFLNK == (pMode & fuse.S_IFDIR)
default: return false
case fs.UfsFile:
return fuse.S_IFREG == (pMode & fuse.S_IFDIR)
case fs.UfsDirectory:
return fuse.S_IFDIR == (pMode & fuse.S_IFDIR)
case fs.UfsSymlink:
return fuse.S_IFLNK == (pMode & fuse.S_IFDIR)
default:
return false
}
}

Expand All @@ -104,4 +130,4 @@ func genQueryID(path string, md fs.Metadata) (cid.Cid) {
prefix := cid.V1Builder{Codec: cid.DagCBOR, MhType: multihash.BLAKE2B_MIN}
return prefix.Sum(append([]byte(path), mdBuf...))
}
*/
*/
20 changes: 13 additions & 7 deletions filesystem/node/soft/pinRoot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package fsnode
import (
"context"
"time"

//TODO: consider /ipfs/interface-go-ipfs-filesystem/node ?
coreiface "github.com/ipfs/interface-go-ipfs-core"
fs "github.com/ipfs/interface-go-ipfs-core/filesystem/interface"
Expand All @@ -14,26 +15,31 @@ type pinRoot struct {
pinAPI coreiface.PinAPI
}

func (pr *pinRoot) YieldIo(ctx context.Context) (io interface{}, err error) {
//TODO: some way to ping the pinapi or coreapi here
return pr, nil
}

func PinParser(pinAPI coreiface.PinAPI, epoch time.Time) fs.ParseFn {
return func(_ context.Context, path string) (fs.Node, error) {
if path != "" {
return nil, fs.ErrInvalidPath
}
return &pinRoot{pinAPI: pinAPI, softDirRoot: csd(path, epoch)}, nil
return &pinRoot{pinAPI: pinAPI, SoftDirRoot: csd(path, epoch)}, nil
}
}

func (pr *pinRoot) Version() uint {
pr.version++ //TODO: we need a "has changed" signal from the pinservice to be cache friendly
return pr.version
}

func (pr *pinRoot) YieldIo(ctx context.Context) (io interface{}, err error) {
//TODO: some way to ping the pinapi or coreapi here
return pr, nil
}

func (pr *pinRoot) Read(ctx context.Context, offset int64) <-chan string {
pins, err := pr.pinAPI.Ls(ctx, coreoptions.Pin.Type.Recursive())
if err != nil {
return nil
}
return stringStream(ctx, pins)
return pinMux(ctx, pins...)
}

func (pr *pinRoot) Entries() int {
Expand Down
19 changes: 0 additions & 19 deletions filesystem/node/soft/roots.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,29 +44,10 @@ func (sd *SoftDirRoot) InitMetadata(ctx context.Context) (*fuse.Stat_t, error) {
return nodeStat, nil
}


func (sd *SoftDirRoot) Create(ctx context.Context, nodeType fs.Kind) error {
return fs.ErrIOType
}

func (mr *mountRoot) YieldIo(ctx context.Context) (io interface{}, err error) {
return mr, nil
}

func stringStream(ctx context.Context, strings...string) <-chan string {
stringChan := make(chan string)
go func (){
for _, s := range strings {
select {
case ctx.Done():return
case stringChan <-s:
}
}
close(stringChan)
}()
return stringChan
}

func (mr *mountRoot) Read(ctx context.Context, offset int64) <-chan string {
return stringStream(ctx, mr.subroots)
}
Expand Down
42 changes: 40 additions & 2 deletions filesystem/node/soft/utils.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package fsnode

func csd(path string, now fuse.Timespec) softDirRoot {
import (
"context"
"time"

"github.com/billziss-gh/cgofuse/fuse"
)

func csd(path string, metaTimes time.Time) softDirRoot {
sd := softDirRoot{recordBase: crb(path)}
now := fuse.NewTimespec(metaTimes)
meta := &sd.recordBase.metadata
meta.Birthtim, meta.Mtim, meta.Ctim = now, now, now // !!!
meta.Atim = fuse.Now()
Expand All @@ -10,4 +18,34 @@ func csd(path string, now fuse.Timespec) softDirRoot {

func crb(path string) fsnode.BaseNode {
return fsnode.BaseNode{path: path, ioHandles: make(nodeHandles)}
}
}

func stringStream(ctx context.Context, strings ...string) <-chan string {
stringChan := make(chan string)
go func() {
for _, s := range strings {
select {
case ctx.Done():
return
case stringChan <- s:
}
}
close(stringChan)
}()
return stringChan
}

func pinMux(ctx context.Context, pins ...coreiface.Pin) <-chan string {
pinChan := make(chan string)
go func() {
for _, pin := range pins {
select {
case ctx.Done():
return
case pinChan <- pin.String():
}
}
close(pinChan)
}()
return pinChan
}

0 comments on commit 9f28d54

Please sign in to comment.