Commit 96451811 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 6fdd5467
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
// where /bigfile/<bigfileX> represent bigfile data as of revision <revX>. // where /bigfile/<bigfileX> represent bigfile data as of revision <revX>.
// //
// Unless accessed {head,@<revX>}/bigfile/<bigfileX> are not automatically visible in // Unless accessed {head,@<revX>}/bigfile/<bigfileX> are not automatically visible in
// wcfs filesystem. Similarly @<revX>/ should be explicitly created by client via mkdir. XXX -> just @<revX> access. // wcfs filesystem. Similarly @<revX>/ become visible only after accessed.
// //
// //
// Invalidation protocol // Invalidation protocol
...@@ -1002,19 +1002,19 @@ func (bfdir *BigFileDir) lookup(out *fuse.Attr, name string, fctx *fuse.Context) ...@@ -1002,19 +1002,19 @@ func (bfdir *BigFileDir) lookup(out *fuse.Attr, name string, fctx *fuse.Context)
// XXX do we need to support unlink? -> no, @<revX>/ are automatically garbage-collected. // XXX do we need to support unlink? -> no, @<revX>/ are automatically garbage-collected.
// / -> Mkdir receives client request to create @<rev>/. // / -> Lookup receives client request to create @<rev>/.
// func (root *Root) Lookup(out *fuse.Attr, name string, fctx *fuse.Context) (*nodefs.Inode, fuse.Status) {
// it is not an error if @<rev>/ already exists - mkdir succeeds and EEXIST is not returned. revd, err := root.lookup(name, fctx)
// in other words mkdir behaves here similarly to `mkdir -p`. var inode *nodefs.Inode
// if revd != nil {
// XXX -> remove mkdir and just create @revX/ on lookup. inode = revd.Inode()
func (root *Root) Mkdir(name string, mode uint32, fctx *fuse.Context) (*nodefs.Inode, fuse.Status) { _ = revd.GetAttr(out, nil, fctx) // always ok
inode, err := root.mkdir(name, fctx) // XXX ok to ignore mode? }
return inode, err2LogStatus(err) return inode, err2LogStatus(err)
} }
func (root *Root) mkdir(name string, fctx *fuse.Context) (_ *nodefs.Inode, err error) { func (root *Root) lookup(name string, fctx *fuse.Context) (_ *Head, err error) {
defer xerr.Contextf(&err, "/: mkdir %q", name) defer xerr.Contextf(&err, "/: lookup %q", name) // XXX name -> path?
var rev zodb.Tid var rev zodb.Tid
ok := false ok := false
...@@ -1029,11 +1029,11 @@ func (root *Root) mkdir(name string, fctx *fuse.Context) (_ *nodefs.Inode, err e ...@@ -1029,11 +1029,11 @@ func (root *Root) mkdir(name string, fctx *fuse.Context) (_ *nodefs.Inode, err e
// check to see if dir(rev) is already there // check to see if dir(rev) is already there
root.revMu.Lock() root.revMu.Lock()
_, already := root.revTab[rev] revDir, already := root.revTab[rev]
root.revMu.Unlock() root.revMu.Unlock()
if already { if already {
return nil, syscall.EEXIST return revDir, nil
} }
// not there - without revMu lock proceed to open @rev view of ZODB // not there - without revMu lock proceed to open @rev view of ZODB
...@@ -1044,19 +1044,20 @@ func (root *Root) mkdir(name string, fctx *fuse.Context) (_ *nodefs.Inode, err e ...@@ -1044,19 +1044,20 @@ func (root *Root) mkdir(name string, fctx *fuse.Context) (_ *nodefs.Inode, err e
return nil, err return nil, err
} }
// relock root and either mkdir or EEXIST if the directory was maybe // relock root and either register new revX/ directory or, if the
// simultaneously created while we were not holding revMu. // directory was maybe simultaneously created while we were not holding
// revMu, return that.
root.revMu.Lock() root.revMu.Lock()
_, already = root.revTab[rev] revDir, already = root.revTab[rev]
if already { if already {
root.revMu.Unlock() root.revMu.Unlock()
// zconnRev.Release() // zconnRev.Release()
transaction.Current(zconnRev.txnCtx).Abort() transaction.Current(zconnRev.txnCtx).Abort()
return nil, syscall.EEXIST return revDir, nil
} }
// XXX -> newHead() // XXX -> newHead()
revDir := &Head{ revDir = &Head{
Node: newDefaultNode(), Node: newDefaultNode(),
rev: rev, rev: rev,
zconn: zconnRev, zconn: zconnRev,
...@@ -1078,7 +1079,7 @@ func (root *Root) mkdir(name string, fctx *fuse.Context) (_ *nodefs.Inode, err e ...@@ -1078,7 +1079,7 @@ func (root *Root) mkdir(name string, fctx *fuse.Context) (_ *nodefs.Inode, err e
mkdir(revDir, "bigfile", bfdir) mkdir(revDir, "bigfile", bfdir)
// XXX + "at" // XXX + "at"
return revDir.Inode(), nil return revDir, nil
} }
...@@ -1159,6 +1160,21 @@ func (f *BigFile) Close() error { ...@@ -1159,6 +1160,21 @@ func (f *BigFile) Close() error {
return nil return nil
} }
// /(head|<rev>)/ -> Getattr serves stat.
func (head *Head) GetAttr(out *fuse.Attr, _ nodefs.File, _ *fuse.Context) fuse.Status {
at := head.rev
if at == 0 {
head.zconnMu.RLock()
at = head.zconn.At()
head.zconnMu.RUnlock()
}
t := at.Time().Time
out.Mode = fuse.S_IFDIR | 0555
out.SetTimes(/*atime=*/nil, /*mtime=*/&t, /*ctime=*/&t)
return fuse.OK
}
// /(head|<rev>)/bigfile/<bigfileX> -> Getattr serves stat. // /(head|<rev>)/bigfile/<bigfileX> -> Getattr serves stat.
func (f *BigFile) GetAttr(out *fuse.Attr, _ nodefs.File, _ *fuse.Context) fuse.Status { func (f *BigFile) GetAttr(out *fuse.Attr, _ nodefs.File, _ *fuse.Context) fuse.Status {
f.head.zconnMu.RLock() f.head.zconnMu.RLock()
......
...@@ -264,7 +264,6 @@ def test_wcfs(): ...@@ -264,7 +264,6 @@ def test_wcfs():
rev1 = wc.mountpoint + ("/@%s" % h(tcommit1)) rev1 = wc.mountpoint + ("/@%s" % h(tcommit1))
fpath1 = rev1 + "/bigfile/" + h(f._p_oid) fpath1 = rev1 + "/bigfile/" + h(f._p_oid)
os.mkdir(rev1)
st = os.stat(fpath1) st = os.stat(fpath1)
assert st.st_size == fsize1 assert st.st_size == fsize1
#assert st.st_mtime == tidtime(tcommit1) FIXME proper sync #assert st.st_mtime == tidtime(tcommit1) FIXME proper sync
......
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