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 }