Commit 9f5efdff authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 822366a7
...@@ -378,6 +378,7 @@ package main ...@@ -378,6 +378,7 @@ package main
import ( import (
"context" "context"
"flag" "flag"
"fmt"
stdlog "log" stdlog "log"
"os" "os"
"strings" "strings"
...@@ -520,7 +521,6 @@ func (cc *zodbCacheControl) WantEvict(obj zodb.IPersistent) bool { ...@@ -520,7 +521,6 @@ func (cc *zodbCacheControl) WantEvict(obj zodb.IPersistent) bool {
return false return false
} }
/*
// zwatcher watches for ZODB changes. // zwatcher watches for ZODB changes.
// see "4) when we receive an invalidation message from ZODB ..." // see "4) when we receive an invalidation message from ZODB ..."
func (r *Root) zwatcher(ctx context.Context) (err error) { func (r *Root) zwatcher(ctx context.Context) (err error) {
...@@ -603,6 +603,7 @@ func (r *Root) zhandle1(zevent zodb.WatchEvent) { ...@@ -603,6 +603,7 @@ func (r *Root) zhandle1(zevent zodb.WatchEvent) {
// XXX see "4.4) for all file/blk to in invalidate we do" // XXX see "4.4) for all file/blk to in invalidate we do"
func (f *BigFile) invalidateBlk(ctx context.Context, blk int64) error { func (f *BigFile) invalidateBlk(ctx context.Context, blk int64) error {
fsconn := gfsconn fsconn := gfsconn
blksize := f.zbf.blksize
off := blk*blksize off := blk*blksize
// try to retrieve cache of current head/data[blk] // try to retrieve cache of current head/data[blk]
...@@ -615,11 +616,11 @@ func (f *BigFile) invalidateBlk(ctx context.Context, blk int64) error { ...@@ -615,11 +616,11 @@ func (f *BigFile) invalidateBlk(ctx context.Context, blk int64) error {
// XXX st != OK -> warn? // XXX st != OK -> warn?
blkdata := make([]byte, blksize) blkdata := make([]byte, blksize)
n, st := fsconn.FileRetrieveCache(f.Inode(), off, blkdata) n, st := fsconn.FileRetrieveCache(f.Inode(), off, blkdata)
if n == blksize { if int64(n) == blksize {
// XXX -> go // XXX -> go
// store retrieved data back to OS cache for file @<rev>/file[blk] // store retrieved data back to OS cache for file @<rev>/file[blk]
blkrev, _ := f.δFtail.LastRevOf(blk, f.head.zconn.At()) blkrev, _ := f.δFtail.LastRevOf(blk, f.head.zconn.At())
frev := groot.revisionedFile(ctx, blkrev, f.zbf.POid()) frev, err := groot.mkrevfile(blkrev, f.zbf.POid())
st = fsconn.FileNotifyStoreCache(frev.Inode(), off, blkdata) st = fsconn.FileNotifyStoreCache(frev.Inode(), off, blkdata)
if st != fuse.OK { if st != fuse.OK {
// XXX log - dup wrt readBlk -> common func. // XXX log - dup wrt readBlk -> common func.
...@@ -634,17 +635,42 @@ func (f *BigFile) invalidateBlk(ctx context.Context, blk int64) error { ...@@ -634,17 +635,42 @@ func (f *BigFile) invalidateBlk(ctx context.Context, blk int64) error {
} }
// mkrevfile makes sure inode of /@<rev>/bigfile/<fid> is known to kernel. // mkrevfile makes sure inode ID of /@<rev>/bigfile/<fid> is known to kernel.
// //
// We need node ID to be know to the kernel, when we need to store data into // We need node ID to be know to the kernel, when we need to store data into
// file's kernel cache. // file's kernel cache - if the kernel don't have the node ID for the file in
// // question, FileNotifyStoreCche will just fail.
// For kernel to know node IDmkrevfile has
// //
// XXX why we go through kernel.lookup // For kernel to know the inode mkrevfile issues regular filesystem lookup
func (root *Root) mkrevfile(ctx context.Context, rev zodb.Tid, fid zodb.Oid) (*BigFile, error) { // request which goes to kernel and should go back to wcfs. It is thus not safe
// to use mkrevfile from under FUSE request handler as doing so might deadlock.
func (root *Root) mkrevfile(rev zodb.Tid, fid zodb.Oid) (_ *BigFile, err error) {
fsconn := gfsconn
frevpath := fmt.Sprintf("@%s/bigfile/%s", rev, fid) // relative to fs root for now
defer xerr.Contextf(&err, "/: mkrevfile %s", frevpath)
// first check without going through kernel, whether the inode maybe know already
xfrev := fsconn.LookupNode(root.Inode(), frevpath)
if xfrev != nil {
// FIXME checking for "node{0}" is fragile, but currently no other way
if xfrev.String() != "node{0}" {
return xfrev.Node().(*BigFile), nil
}
}
// we have to ping the kernel
frevospath := gmntpt + "/" + frevpath // now starting from OS /
f, err := os.Open(frevospath)
if err != nil {
return nil, err
}
defer f.Close()
xfrev = fsconn.LookupNode(root.Inode(), frevpath)
// must be !nil as open succeeded
return xfrev.Node().(*BigFile), nil
} }
*/
// ---------------------------------------- // ----------------------------------------
...@@ -1070,8 +1096,14 @@ func (h *Head) readAt() []byte { ...@@ -1070,8 +1096,14 @@ func (h *Head) readAt() []byte {
var groot *Root var groot *Root
var gfsconn *nodefs.FileSystemConnector var gfsconn *nodefs.FileSystemConnector
// file descriptor for opened root of the filesystem // root of the filesystem is mounted here.
var grootf *os.File // XXX -> fd //
// we need to talk to kernel and lookup @<rev>/bigfile/<fid> before uploading
// data to kernel cache there. Referencing root of the filesystem via path is
// vulnerable to bugs wrt e.g. `mount --move` and/or mounting something else
// over wcfs. However keeping opened root fd will prevent wcfs to be unmounted,
// so we still have to reference the root via path.
var gmntpt string
func main() { func main() {
stdlog.SetPrefix("wcfs: ") stdlog.SetPrefix("wcfs: ")
...@@ -1138,6 +1170,7 @@ func main() { ...@@ -1138,6 +1170,7 @@ func main() {
} }
groot = root // FIXME temp workaround (see ^^^) groot = root // FIXME temp workaround (see ^^^)
gfsconn = fsconn // FIXME ----//---- gfsconn = fsconn // FIXME ----//----
gmntpt = mntpt
// we require proper pagecache control (added to Linux 2.6.36 in 2010) // we require proper pagecache control (added to Linux 2.6.36 in 2010)
supports := fssrv.KernelSettings().SupportsNotify supports := fssrv.KernelSettings().SupportsNotify
...@@ -1159,22 +1192,5 @@ func main() { ...@@ -1159,22 +1192,5 @@ func main() {
_ = autoexit _ = autoexit
// serve client requests // serve client requests
done := make(chan struct{}) fssrv.Serve() // XXX Serve returns no error
go func() {
fssrv.Serve() // XXX Serve returns no error
close(done)
}()
err = fssrv.WaitMount()
if err != nil {
log.Fatal(err)
}
grootf, err = os.Open(mntpt)
if err != nil {
fssrv.Unmount()
log.Fatal(err)
}
<-done
} }
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