Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Joshua
wendelin.core
Commits
a6874733
Commit
a6874733
authored
Jun 27, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
7126b78b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
37 additions
and
37 deletions
+37
-37
wcfs/wcfs.go
wcfs/wcfs.go
+36
-36
wcfs/wcfs_test.py
wcfs/wcfs_test.py
+1
-1
No files found.
wcfs/wcfs.go
View file @
a6874733
...
...
@@ -310,7 +310,7 @@ package main
// 4.6) processing ZODB invalidations and serving file reads (see 7) are
// organized to be mutually exclusive.
//
// (TODO head.z
conn
Mu -> special mutex with Lock(ctx) so that Lock could be canceled)
// (TODO head.z
head
Mu -> special mutex with Lock(ctx) so that Lock could be canceled)
//
// 5) after OS file cache was invalidated, we resync zhead to new database
// view corresponding to tid.
...
...
@@ -419,7 +419,7 @@ package main
// XXX describe locking
//
// head.z
conn
Mu write by handleδZ; read by read
// head.z
head
Mu write by handleδZ; read by read
// -> rlockZHead() + lockZHead() ?
// ...
...
...
@@ -489,7 +489,7 @@ type Head struct {
// ZODB connection for everything under this head
// protects access to zconn & live _objects_ associated with it.
//
zheadMu
protects access to zconn & live _objects_ associated with it.
// while it is rlocked zconn is guaranteed to stay viewing database at
// particular view.
//
...
...
@@ -499,7 +499,7 @@ type Head struct {
// it is also kept rlocked by OS cache uploaders (see BigFile.uploadBlk)
// with additional locking protocol to avoid deadlocks (see below for
// pauseOSCacheUpload + ...).
z
connMu
sync
.
RWMutex
// XXX -> zheadMu ?
z
headMu
sync
.
RWMutex
zconn
*
ZConn
// for head/ zwatcher resyncs head.zconn; others only read zconn objects.
// zwatcher signals to uploadBlk to pause/continue uploads to OS cache to avoid deadlocks.
...
...
@@ -512,7 +512,7 @@ type Head struct {
// XXX move zconn's current transaction to Head here?
// head/watch opens
// XXX protected by ...
head.zconn
Mu ?
// XXX protected by ...
zhead
Mu ?
wlinkTab
map
[
*
WatchLink
]
struct
{}
}
...
...
@@ -736,12 +736,12 @@ func (root *Root) handleδZ(δZ *zodb.EventCommit) {
continueOSCacheUpload
:=
make
(
chan
struct
{})
retry
:
for
{
head
.
z
conn
Mu
.
Lock
()
head
.
z
head
Mu
.
Lock
()
head
.
pauseOSCacheUpload
=
true
head
.
continueOSCacheUpload
=
continueOSCacheUpload
if
head
.
inflightOSCacheUploads
!=
0
{
head
.
z
conn
Mu
.
Unlock
()
head
.
z
head
Mu
.
Unlock
()
continue
retry
}
...
...
@@ -751,11 +751,11 @@ retry:
defer
func
()
{
head
.
pauseOSCacheUpload
=
false
head
.
continueOSCacheUpload
=
nil
head
.
z
conn
Mu
.
Unlock
()
head
.
z
head
Mu
.
Unlock
()
close
(
continueOSCacheUpload
)
}()
// head.z
conn
Mu locked and all cache uploaders are paused
// head.z
head
Mu locked and all cache uploaders are paused
zhead
:=
head
.
zconn
bfdir
:=
head
.
bfdir
...
...
@@ -785,8 +785,8 @@ retry:
case zBlk: // ZBlk*
// blkBoundTo locking: no other bindZFile are running,
// since we write-locked head.z
conn
Mu and bindZFile is
// run when loading objects - thus when head.z
conn
Mu is
// since we write-locked head.z
head
Mu and bindZFile is
// run when loading objects - thus when head.z
head
Mu is
// read-locked.
//
// bfdir locking: similarly not needed, since we are
...
...
@@ -923,7 +923,7 @@ retry:
//
// see "4.4) for all file/blk to in invalidate we do"
//
// called with f.head.z
conn
Mu wlocked.
// called with f.head.z
head
Mu wlocked.
func
(
f
*
BigFile
)
invalidateBlk
(
ctx
context
.
Context
,
blk
int64
)
(
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"%s: invalidate blk #%d:"
,
f
.
path
(),
blk
)
...
...
@@ -936,7 +936,7 @@ func (f *BigFile) invalidateBlk(ctx context.Context, blk int64) (err error) {
// first try to retrieve f.loading[blk];
// make sure f.loading[blk] is invalidated.
//
// we are running with z
conn
Mu wlocked - no need to lock f.loadMu
// we are running with z
head
Mu wlocked - no need to lock f.loadMu
loading
,
ok
:=
f
.
loading
[
blk
]
if
ok
{
if
loading
.
err
==
nil
{
...
...
@@ -1045,8 +1045,8 @@ func (root *Root) mkrevfile(rev zodb.Tid, fid zodb.Oid) (_ *BigFile, release fun
// /(head|<rev>)/bigfile/<bigfileX> -> Read serves reading bigfile data.
func
(
f
*
BigFile
)
Read
(
_
nodefs
.
File
,
dest
[]
byte
,
off
int64
,
fctx
*
fuse
.
Context
)
(
fuse
.
ReadResult
,
fuse
.
Status
)
{
f
.
head
.
z
conn
Mu
.
RLock
()
defer
f
.
head
.
z
conn
Mu
.
RUnlock
()
f
.
head
.
z
head
Mu
.
RLock
()
defer
f
.
head
.
z
head
Mu
.
RUnlock
()
// cap read request to file size
end
:=
off
+
int64
(
len
(
dest
))
// XXX overflow?
...
...
@@ -1097,7 +1097,7 @@ func (f *BigFile) Read(_ nodefs.File, dest []byte, off int64, fctx *fuse.Context
// see "7) when we receive a FUSE read(#blk) request ..." in overview.
//
// len(dest) == blksize.
// called with head.z
conn
Mu rlocked.
// called with head.z
head
Mu rlocked.
func
(
f
*
BigFile
)
readBlk
(
ctx
context
.
Context
,
blk
int64
,
dest
[]
byte
)
(
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"%s: readblk #%d"
,
f
.
path
(),
blk
)
...
...
@@ -1174,7 +1174,7 @@ func (f *BigFile) readBlk(ctx context.Context, blk int64, dest []byte) (err erro
//
// See "7.2) for all registered client@at watchers ..."
//
// Called with f.head.z
conn
Mu rlocked.
// Called with f.head.z
head
Mu rlocked.
//
// XXX do we really need to use/propagate caller context here? ideally update
// watchers should be synchronous, and in practice we just use 30s timeout.
...
...
@@ -1256,17 +1256,17 @@ func (f *BigFile) updateWatchers(ctx context.Context, blk int64, treepath []btre
func
(
f
*
BigFile
)
uploadBlk
(
blk
int64
,
loading
*
blkLoadState
)
{
head
:=
f
.
head
// rlock z
conn
Mu and make sure zwatcher is not asking us to pause.
// rlock z
head
Mu and make sure zwatcher is not asking us to pause.
// if it does - wait for a safer time not to deadlock.
// see notes.txt -> "Kernel locks page on read/cache store/..." for details.
retry
:
for
{
head
.
z
conn
Mu
.
RLock
()
head
.
z
head
Mu
.
RLock
()
// help zwatcher if it asks us to pause uploadings, so it can
// take z
conn
Mu wlocked without deadlocks.
// take z
head
Mu wlocked without deadlocks.
if
head
.
pauseOSCacheUpload
{
ready
:=
head
.
continueOSCacheUpload
head
.
z
conn
Mu
.
RUnlock
()
head
.
z
head
Mu
.
RUnlock
()
<-
ready
continue
retry
}
...
...
@@ -1282,17 +1282,17 @@ retry:
loading_
:=
f
.
loading
[
blk
]
f
.
loadMu
.
Unlock
()
if
loading
!=
loading_
{
head
.
z
conn
Mu
.
RUnlock
()
head
.
z
head
Mu
.
RUnlock
()
return
}
oid
:=
f
.
zfile
.
POid
()
// signal to zwatcher not to run while we are performing the upload.
// upload with released z
conn
Mu so that zwatcher can lock it even if to
// upload with released z
head
Mu so that zwatcher can lock it even if to
// check inflightOSCacheUploads status.
atomic
.
AddInt32
(
&
head
.
inflightOSCacheUploads
,
+
1
)
head
.
z
conn
Mu
.
RUnlock
()
head
.
z
head
Mu
.
RUnlock
()
st
:=
gfsconn
.
FileNotifyStoreCache
(
f
.
Inode
(),
blk
*
f
.
blksize
,
loading
.
blkdata
)
...
...
@@ -1390,7 +1390,7 @@ func (wlink *WatchLink) setupWatch(ctx context.Context, foid zodb.Oid, at zodb.T
bfdir
:=
head
.
bfdir
// XXX locking
// XXX head.z
conn
Mu.RLock() + defer unlock (see vvv for unpin vs pin and locked head)
// XXX head.z
head
Mu.RLock() + defer unlock (see vvv for unpin vs pin and locked head)
// XXX if watch was already established - we need to update it
w
:=
wlink
.
byfile
[
foid
]
...
...
@@ -1784,8 +1784,8 @@ func (bfdir *BigFileDir) lookup(out *fuse.Attr, name string, fctx *fuse.Context)
return
nil
,
eINVALf
(
"not oid"
)
}
bfdir
.
head
.
z
conn
Mu
.
RLock
()
defer
bfdir
.
head
.
z
conn
Mu
.
RUnlock
()
bfdir
.
head
.
z
head
Mu
.
RLock
()
defer
bfdir
.
head
.
z
head
Mu
.
RUnlock
()
defer
func
()
{
if
f
!=
nil
{
...
...
@@ -1997,8 +1997,8 @@ func (f *BigFile) Close() error {
// /(head|<rev>)/at -> readAt serves read.
func
(
h
*
Head
)
readAt
()
[]
byte
{
h
.
z
conn
Mu
.
RLock
()
defer
h
.
z
conn
Mu
.
RUnlock
()
h
.
z
head
Mu
.
RLock
()
defer
h
.
z
head
Mu
.
RUnlock
()
return
[]
byte
(
h
.
zconn
.
At
()
.
String
())
}
...
...
@@ -2007,9 +2007,9 @@ func (h *Head) readAt() []byte {
func
(
head
*
Head
)
GetAttr
(
out
*
fuse
.
Attr
,
_
nodefs
.
File
,
_
*
fuse
.
Context
)
fuse
.
Status
{
at
:=
head
.
rev
if
at
==
0
{
head
.
z
conn
Mu
.
RLock
()
head
.
z
head
Mu
.
RLock
()
at
=
head
.
zconn
.
At
()
head
.
z
conn
Mu
.
RUnlock
()
head
.
z
head
Mu
.
RUnlock
()
}
t
:=
at
.
Time
()
.
Time
...
...
@@ -2020,8 +2020,8 @@ func (head *Head) GetAttr(out *fuse.Attr, _ nodefs.File, _ *fuse.Context) fuse.S
// /(head|<rev>)/bigfile/<bigfileX> -> Getattr serves stat.
func
(
f
*
BigFile
)
GetAttr
(
out
*
fuse
.
Attr
,
_
nodefs
.
File
,
_
*
fuse
.
Context
)
fuse
.
Status
{
f
.
head
.
z
conn
Mu
.
RLock
()
defer
f
.
head
.
z
conn
Mu
.
RUnlock
()
f
.
head
.
z
head
Mu
.
RLock
()
defer
f
.
head
.
z
head
Mu
.
RUnlock
()
f
.
getattr
(
out
)
return
fuse
.
OK
...
...
@@ -2061,7 +2061,7 @@ var gmntpt string
// debugging
var
gdebug
=
struct
{
// .wcfs/zhead opens
// protected by groot.head.z
conn
Mu
// protected by groot.head.z
head
Mu
zheadSockTab
map
[
*
FileSock
]
struct
{}
}{}
...
...
@@ -2079,8 +2079,8 @@ func (zh *_wcfs_Zhead) Open(flags uint32, fctx *fuse.Context) (nodefs.File, fuse
sk
:=
NewFileSock
()
sk
.
CloseRead
()
groot
.
head
.
z
conn
Mu
.
Lock
()
defer
groot
.
head
.
z
conn
Mu
.
Unlock
()
groot
.
head
.
z
head
Mu
.
Lock
()
defer
groot
.
head
.
z
head
Mu
.
Unlock
()
// XXX del zheadSockTab[sk] on sk.File.Release (= client drops opened handle)
gdebug
.
zheadSockTab
[
sk
]
=
struct
{}{}
...
...
wcfs/wcfs_test.py
View file @
a6874733
...
...
@@ -1448,7 +1448,7 @@ def test_wcfs_pintimeout_kill():
# watch with @at > head - must wait for head to become >= at
# XXX too far ahead -
error
?
# XXX too far ahead -
reject
?
@
func
def
test_wcfs_watch_setup_ahead
():
t
=
tDB
();
zf
=
t
.
zfile
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment