mirror of
https://github.com/ipfs/kubo.git
synced 2025-09-09 17:22:21 +08:00
113 lines
2.1 KiB
Go
113 lines
2.1 KiB
Go
package mfs
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
chunk "github.com/ipfs/go-ipfs/importer/chunk"
|
|
dag "github.com/ipfs/go-ipfs/merkledag"
|
|
ft "github.com/ipfs/go-ipfs/unixfs"
|
|
mod "github.com/ipfs/go-ipfs/unixfs/mod"
|
|
|
|
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
|
|
)
|
|
|
|
type File struct {
|
|
parent childCloser
|
|
|
|
name string
|
|
|
|
desclock sync.RWMutex
|
|
|
|
dserv dag.DAGService
|
|
node *dag.Node
|
|
nodelk sync.Mutex
|
|
}
|
|
|
|
// NewFile returns a NewFile object with the given parameters
|
|
func NewFile(name string, node *dag.Node, parent childCloser, dserv dag.DAGService) (*File, error) {
|
|
return &File{
|
|
dserv: dserv,
|
|
parent: parent,
|
|
name: name,
|
|
node: node,
|
|
}, nil
|
|
}
|
|
|
|
const (
|
|
OpenReadOnly = iota
|
|
OpenWriteOnly
|
|
OpenReadWrite
|
|
)
|
|
|
|
func (fi *File) Open(flags int, sync bool) (FileDescriptor, error) {
|
|
fi.nodelk.Lock()
|
|
node := fi.node
|
|
fi.nodelk.Unlock()
|
|
|
|
switch flags {
|
|
case OpenReadOnly:
|
|
fi.desclock.RLock()
|
|
case OpenWriteOnly, OpenReadWrite:
|
|
fi.desclock.Lock()
|
|
default:
|
|
// TODO: support other modes
|
|
return nil, fmt.Errorf("mode not supported")
|
|
}
|
|
|
|
dmod, err := mod.NewDagModifier(context.TODO(), node, fi.dserv, chunk.DefaultSplitter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &fileDescriptor{
|
|
inode: fi,
|
|
perms: flags,
|
|
sync: sync,
|
|
mod: dmod,
|
|
}, nil
|
|
}
|
|
|
|
// Size returns the size of this file
|
|
func (fi *File) Size() (int64, error) {
|
|
fi.nodelk.Lock()
|
|
defer fi.nodelk.Unlock()
|
|
pbd, err := ft.FromBytes(fi.node.Data)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return int64(pbd.GetFilesize()), nil
|
|
}
|
|
|
|
// GetNode returns the dag node associated with this file
|
|
func (fi *File) GetNode() (*dag.Node, error) {
|
|
fi.nodelk.Lock()
|
|
defer fi.nodelk.Unlock()
|
|
return fi.node, nil
|
|
}
|
|
|
|
func (fi *File) Flush() error {
|
|
// open the file in fullsync mode
|
|
fd, err := fi.Open(OpenWriteOnly, true)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer fd.Close()
|
|
|
|
return fd.Flush()
|
|
}
|
|
|
|
func (fi *File) Sync() error {
|
|
// just being able to take the writelock means the descriptor is synced
|
|
fi.desclock.Lock()
|
|
fi.desclock.Unlock()
|
|
return nil
|
|
}
|
|
|
|
// Type returns the type FSNode this is
|
|
func (fi *File) Type() NodeType {
|
|
return TFile
|
|
}
|