Commit 2b18dfc1 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 8b60658b
......@@ -112,11 +112,17 @@ func asctx(fctx *fuse.Context) context.Context {
// In wcfs we have dynamic files (e.g. /head/watch) and this way we have to
// avoid returning ENOSYS on nodes, that do not need file handles.
//
// fsNode is like nodefs.defaultNode, but Open returns to kernel fh=0 and
// FOPEN_KEEP_CACHE - similarly how openless case is handled there.
type fsNode struct{
// fsNode is like nodefs.defaultNode, but by default Open returns to kernel
// fh=0 and FOPEN_KEEP_CACHE - similarly how openless case is handled there.
//
// fsNode behaviour can be additionally controlled via fsOptions.
//
// fsNode should be created via newFSNode.
type fsNode struct {
nodefs.Node
opt *fsOptions
// cache for path
// we don't use hardlinks / don't want to pay locks + traversal price every time.
xpath atomic.Value
......@@ -129,9 +135,23 @@ func (n *fsNode) Open(flags uint32, fctx *fuse.Context) (nodefs.File, fuse.Statu
}, fuse.OK
}
func newFSNode() fsNode { // NOTE not pointer
// fsOptions allows to tune fsNode behaviour.
type fsOptions struct {
// Sticky nodes are not removed from inode tree on FORGET.
// Correspondingly OnForget is never called on a sticky node.
Sticky bool
}
var fSticky = &fsOptions{Sticky: true} // frequently used shortcut XXX -> newFSticky?
func (n *fsNode) Deletable() bool {
return !n.opt.Sticky
}
func newFSNode(opt *fsOptions) fsNode { // NOTE not pointer
return fsNode{
Node: nodefs.NewDefaultNode(),
opt: opt,
}
}
......@@ -161,6 +181,8 @@ func (n *fsNode) path() string {
// NewStaticFile creates nodefs.Node for file with static data.
//
// Created file is sticky.
func NewStaticFile(data []byte) *SmallFile {
return newSmallFile(func() []byte {
return data
......@@ -178,13 +200,15 @@ type SmallFile struct {
func newSmallFile(readData func() []byte, fuseFlags uint32) *SmallFile {
return &SmallFile{
fsNode: newFSNode(),
fsNode: newFSNode(&fsOptions{Sticky: true}),
fuseFlags: fuseFlags,
readData: readData,
}
}
// NewSmallFile creates nodefs.Node for file with dynamic, but always small, data.
//
// Created file is sticky.
func NewSmallFile(readData func() []byte) *SmallFile {
return newSmallFile(readData, fuse.FOPEN_DIRECT_IO)
}
......
......@@ -1078,13 +1078,13 @@ func (root *Root) lookup(name string, fctx *fuse.Context) (_ *Head, err error) {
// XXX -> newHead()
revDir = &Head{
fsNode: newFSNode(),
fsNode: newFSNode(&fsOptions{Sticky: false}), // XXX + Head.OnForget() -> del root.revTab[]
rev: rev,
zconn: zconnRev,
}
bfdir := &BigFileDir{
fsNode: newFSNode(),
fsNode: newFSNode(&fsOptions{Sticky: false}), // XXX + BigFileDir.OnForget()
head: revDir,
fileTab: make(map[zodb.Oid]*BigFile),
indexLooked: nil, // δbtree index not needed/used for @revX/
......@@ -1151,7 +1151,7 @@ func (head *Head) bigopen(ctx context.Context, oid zodb.Oid) (_ *BigFile, err er
// zconn.Incref()
f := &BigFile{
fsNode: newFSNode(),
fsNode: newFSNode(&fsOptions{Sticky: false}), // XXX + BigFile.OnForget -> del .head.bfdir.fileTab[]
head: head,
zbf: zbf,
zbfSize: zbfSize,
......@@ -1548,12 +1548,12 @@ func main() {
// mount root + head/
// XXX -> newHead()
head := &Head{
fsNode: newFSNode(),
fsNode: newFSNode(fSticky),
rev: 0,
zconn: zhead,
}
bfdir := &BigFileDir{
fsNode: newFSNode(),
fsNode: newFSNode(fSticky),
head: head,
fileTab: make(map[zodb.Oid]*BigFile),
indexLooked: δbtree.NewPathSet(),
......@@ -1561,7 +1561,7 @@ func main() {
head.bfdir = bfdir
root := &Root{
fsNode: newFSNode(),
fsNode: newFSNode(fSticky),
zstor: zstor,
zdb: zdb,
head: head,
......@@ -1601,7 +1601,7 @@ func main() {
mkfile(head, "at", NewSmallFile(head.readAt)) // TODO mtime(at) = tidtime(at)
// for debugging/testing
_wcfs := newFSNode()
_wcfs := newFSNode(fSticky)
mkdir(root, ".wcfs", &_wcfs)
mkfile(&_wcfs, "zurl", NewStaticFile([]byte(zurl)))
......@@ -1612,7 +1612,7 @@ func main() {
// There can be multiple openers. Once opened, the file must be read,
// as wcfs blocks waiting for data to be read before XXX.
mkfile(&_wcfs, "zhead", &_wcfs_Zhead{
fsNode: newFSNode(),
fsNode: newFSNode(fSticky),
})
// XXX place = ok?
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment