Commit b720f172 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 2f9c12da
...@@ -425,8 +425,9 @@ type Root struct { ...@@ -425,8 +425,9 @@ type Root struct {
// /(head|<rev>)/ - served by Head. // /(head|<rev>)/ - served by Head.
type Head struct { type Head struct {
nodefs.Node nodefs.Node
rev zodb.Tid // 0 for head/, !0 for @<rev>/ rev zodb.Tid // 0 for head/, !0 for @<rev>/
// bigfile/, at, watch, etc - all implicitly linked to by fs bfdir *BigFileDir
// at, watch, etc - all implicitly linked to by fs
// ZODB connection for everything under this head // ZODB connection for everything under this head
zconnMu sync.RWMutex // protects access to zconn & live _objects_ associated with it zconnMu sync.RWMutex // protects access to zconn & live _objects_ associated with it
...@@ -541,10 +542,13 @@ func (r *Root) zwatcher(ctx context.Context) (err error) { ...@@ -541,10 +542,13 @@ func (r *Root) zwatcher(ctx context.Context) (err error) {
// zhandle1 handles 1 event from ZODB notification. // zhandle1 handles 1 event from ZODB notification.
func (r *Root) zhandle1(zevent zodb.WatchEvent) { func (r *Root) zhandle1(zevent zodb.WatchEvent) {
// XXX locking correct? XXX too coarse? -> lock only around "resync .zhead ..." ? // while we are invalidating OS cache, make sure that nothing, that
// even reads /head/bigfile/*, is running (see 4.6).
r.head.zconnMu.Lock() r.head.zconnMu.Lock()
defer r.head.zconnMu.Unlock() defer r.head.zconnMu.Unlock()
zhead := r.head.zconn zhead := r.head.zconn
bfdir := r.head.bfdir
toinvalidate := map[*BigFile]SetI64{} // {} file -> set(#blk) toinvalidate := map[*BigFile]SetI64{} // {} file -> set(#blk)
...@@ -570,11 +574,21 @@ func (r *Root) zhandle1(zevent zodb.WatchEvent) { ...@@ -570,11 +574,21 @@ func (r *Root) zhandle1(zevent zodb.WatchEvent) {
// since we write-locked head.zconnMu and bindZFile is // since we write-locked head.zconnMu and bindZFile is
// run when loading objects - thus when head.zconnMu is // run when loading objects - thus when head.zconnMu is
// read-locked. // read-locked.
//
// bfdir locking: similarly not needed, since we are
// exclusively holding head lock.
for zfile, objBlk := range obj.blkBoundTo() { for zfile, objBlk := range obj.blkBoundTo() {
blkmap, ok := toinvalidate[zfile] file, ok := bfdir.tab[zfile.POid()]
if !ok {
// even though zfile is in ZODB cache, the
// filesystem already forgot about this file.
continue
}
blkmap, ok := toinvalidate[file]
if !ok { if !ok {
blkmap = SetI64{} blkmap = SetI64{}
toinvalidate[zfile] = blkmap toinvalidate[file] = blkmap
} }
blkmap.Update(objBlk) blkmap.Update(objBlk)
} }
...@@ -791,22 +805,27 @@ func (root *Root) mkdir(name string, fctx *fuse.Context) (_ *nodefs.Inode, err e ...@@ -791,22 +805,27 @@ func (root *Root) mkdir(name string, fctx *fuse.Context) (_ *nodefs.Inode, err e
return nil, syscall.EEXIST return nil, syscall.EEXIST
} }
// XXX -> newHead()
revDir := &Head{ revDir := &Head{
Node: nodefs.NewDefaultNode(), Node: nodefs.NewDefaultNode(),
rev: rev, rev: rev,
zconn: zconnRev, zconn: zconnRev,
} }
bfdir := &BigFileDir{
Node: nodefs.NewDefaultNode(),
head: revDir,
tab: make(map[zodb.Oid]*BigFile),
}
revDir.bfdir = bfdir
root.revTab[rev] = revDir root.revTab[rev] = revDir
root.revMu.Unlock() root.revMu.Unlock()
// mkdir takes filesystem treeLock - do it outside revMu. // mkdir takes filesystem treeLock - do it outside revMu.
mkdir(root, name, revDir) mkdir(root, name, revDir)
mkdir(revDir, "bigfile", &BigFileDir{ mkdir(revDir, "bigfile", bfdir)
Node: nodefs.NewDefaultNode(), // XXX + "at"
head: revDir,
tab: make(map[zodb.Oid]*BigFile),
})
return revDir.Inode(), nil return revDir.Inode(), nil
} }
...@@ -1144,11 +1163,18 @@ func main() { ...@@ -1144,11 +1163,18 @@ func main() {
zhead.Cache().SetControl(&zodbCacheControl{}) // XXX +locking? zhead.Cache().SetControl(&zodbCacheControl{}) // XXX +locking?
// mount root + head/ // mount root + head/
// XXX -> newHead()
head := &Head{ head := &Head{
Node: nodefs.NewDefaultNode(), Node: nodefs.NewDefaultNode(),
rev: 0, rev: 0,
zconn: zhead, zconn: zhead,
} }
bfdir := &BigFileDir{
Node: nodefs.NewDefaultNode(),
head: head,
tab: make(map[zodb.Oid]*BigFile),
}
head.bfdir = bfdir
root := &Root{ root := &Root{
Node: nodefs.NewDefaultNode(), Node: nodefs.NewDefaultNode(),
...@@ -1183,11 +1209,7 @@ func main() { ...@@ -1183,11 +1209,7 @@ func main() {
// add entries to / // add entries to /
mkfile(root, ".wcfs", NewStaticFile([]byte(zurl))) mkfile(root, ".wcfs", NewStaticFile([]byte(zurl)))
mkdir(root, "head", head) mkdir(root, "head", head)
mkdir(head, "bigfile", &BigFileDir{ mkdir(head, "bigfile", bfdir)
Node: nodefs.NewDefaultNode(),
head: head,
tab: make(map[zodb.Oid]*BigFile),
})
mkfile(head, "at", NewSmallFile(head.readAt)) // TODO mtime(at) = tidtime(at) mkfile(head, "at", NewSmallFile(head.readAt)) // TODO mtime(at) = tidtime(at)
// TODO handle autoexit // TODO handle autoexit
......
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