Commit 22769012 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 5f21e010
...@@ -977,11 +977,11 @@ func (f *BigFile) invalidateBlk(ctx context.Context, blk int64) (err error) { ...@@ -977,11 +977,11 @@ func (f *BigFile) invalidateBlk(ctx context.Context, blk int64) (err error) {
func() { func() {
// 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.LastBlkRev(ctx, blk, f.head.zconn.At()) blkrev, _ := f.LastBlkRev(ctx, blk, f.head.zconn.At())
frev, frelease, err := groot.mkrevfile(blkrev, f.zfile.POid()) frev, funlock, err := groot.lockRevFile(blkrev, f.zfile.POid())
if err != nil { if err != nil {
log.Errorf("BUG: %s: invalidate blk #%d: %s (ignoring, but reading @revX/bigfile will be slow)", f.path(), blk, err) log.Errorf("BUG: %s: invalidate blk #%d: %s (ignoring, but reading @revX/bigfile will be slow)", f.path(), blk, err)
} }
defer frelease() defer funlock()
st := fsconn.FileNotifyStoreCache(frev.Inode(), off, blkdata) st := fsconn.FileNotifyStoreCache(frev.Inode(), off, blkdata)
if st != fuse.OK { if st != fuse.OK {
...@@ -1014,27 +1014,34 @@ func (f *BigFile) invalidateAttr() (err error) { ...@@ -1014,27 +1014,34 @@ func (f *BigFile) invalidateAttr() (err error) {
} }
// mkrevfile makes sure inode ID of /@<rev>/bigfile/<fid> is known to kernel. // lockRevFile makes sure inode ID of /@<rev>/bigfile/<fid> is known to kernel
// and won't change until unlock.
// //
// 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 - if the kernel don't have the node ID for the file in // file's kernel cache - if the kernel don't have the node ID for the file in
// question, FileNotifyStoreCache will just fail. // question, FileNotifyStoreCache will just fail.
// //
// For kernel to know the inode mkrevfile issues regular filesystem lookup // For kernel to know the inode lockRevFile issues regular filesystem lookup
// request which goes to kernel and should go back to wcfs. It is thus not safe // 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. // to use lockRevFile from under FUSE request handler as doing so might deadlock.
// //
// Caller must call release when inode ID is no longer required to be present. // Caller must call unlock when inode ID is no longer required to be present.
func (root *Root) mkrevfile(rev zodb.Tid, fid zodb.Oid) (_ *BigFile, release func(), err error) { // It is safe to simultaneously call multiple lockRevFile with the same arguments.
func (root *Root) lockRevFile(rev zodb.Tid, fid zodb.Oid) (_ *BigFile, unlock func(), err error) {
fsconn := gfsconn fsconn := gfsconn
frevpath := fmt.Sprintf("@%s/bigfile/%s", rev, fid) // relative to fs root for now frevpath := fmt.Sprintf("@%s/bigfile/%s", rev, fid) // relative to fs root for now
defer xerr.Contextf(&err, "/: mkrevfile %s", frevpath) defer xerr.Contextf(&err, "/: lockRevFile %s", frevpath)
// FIXME checking for "node{0}" is fragile: // FIXME checking for "node{0}" is fragile:
// XXX the node could be still forgotten since we are not holding open on it // XXX the node could be still forgotten since we are not holding open on it
// XXX -> always os.open unconditionally for now // XXX -> always os.open unconditionally for now
// or is it ok since it is just a cache? // or is it ok since it is just a cache?
// -> no, not ok: if inode ID is forgotten, the same ID could be
// reallocated to another file and then we'll corrupt in-kernel
// cache by wrongly storing data of one file into cache of
// another file.
// -> to avoid this we need to always lock the inode ID with real open.
// XXX (also disabled for now due to race-detector) // XXX (also disabled for now due to race-detector)
/* /*
// first check without going through kernel, whether the inode maybe known already // first check without going through kernel, whether the inode maybe known already
......
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