Skip to content

Commit

Permalink
refactoring and changelog
Browse files Browse the repository at this point in the history
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
  • Loading branch information
butonic committed Sep 21, 2020
1 parent 1e60927 commit bbe22ea
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 49 deletions.
7 changes: 7 additions & 0 deletions changelog/unreleased/ocis-synctime-accounting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: introduce ocis driver treetime accounting

We added tree time accounting to the ocis storage driver which is modeled after [eos synctime accounting](http://eos-docs.web.cern.ch/eos-docs/configuration/namespace.html#enable-subtree-accounting).
It can be enabled using the new `treetime_accounting` option, which defaults to `false`
The `tmtime` is stored in an extended attribute `user.ocis.tmtime`. The treetime accounting is enabled for nodes which have the `user.ocis.propagation` extended attribute set to `"1"`. Currently, propagation is in sync.

https://github.com/cs3org/reva/pull/1180
45 changes: 37 additions & 8 deletions pkg/storage/fs/ocis/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,15 +265,8 @@ func (n *Node) AsResourceInfo(ctx context.Context) (ri *provider.ResourceInfo, e
if _, err := io.WriteString(h, n.ID); err != nil {
return nil, err
}
var b []byte
var tmTime time.Time
if b, err = xattr.Get(nodePath, treeMTimeAttr); err == nil {
if tmTime, err = time.Parse(time.RFC3339Nano, string(b)); err != nil {
// invalid format, overwrite
log.Error().Err(err).Interface("node", n).Str("tmtime", string(b)).Msg("invalid format, ignoring")
tmTime = fi.ModTime()
}
} else {
if tmTime, err = n.GetTMTime(); err != nil {
// no tmtime, use mtime
tmTime = fi.ModTime()
}
Expand Down Expand Up @@ -325,3 +318,39 @@ func (n *Node) AsResourceInfo(ctx context.Context) (ri *provider.ResourceInfo, e

return ri, nil
}

// HasPropagation checks if the propagation attribute exists and is set to "1"
func (n *Node) HasPropagation() (propagation bool) {
nodePath := filepath.Join(n.pw.Root, "nodes", n.ID)
if b, err := xattr.Get(nodePath, propagationAttr); err == nil {
return string(b) == "1"
}
return false
}

// GetTMTime reads the tmtime from the extended attributes
func (n *Node) GetTMTime() (tmTime time.Time, err error) {
nodePath := filepath.Join(n.pw.Root, "nodes", n.ID)
var b []byte
if b, err = xattr.Get(nodePath, treeMTimeAttr); err != nil {
return
}
return time.Parse(time.RFC3339Nano, string(b))
}

// SetTMTime writes the tmtime to the extended attributes
func (n *Node) SetTMTime(t time.Time) (err error) {
nodePath := filepath.Join(n.pw.Root, "nodes", n.ID)
return xattr.Set(nodePath, treeMTimeAttr, []byte(t.UTC().Format(time.RFC3339Nano)))
}

// UnsetTempEtag removes the temporary etag attribute
func (n *Node) UnsetTempEtag() (err error) {
nodePath := filepath.Join(n.pw.Root, "nodes", n.ID)
if err = xattr.Remove(nodePath, tmpEtagAttr); err != nil {
if e, ok := err.(*xattr.Error); ok && e.Err.Error() == "no data available" {
return nil
}
}
return err
}
64 changes: 23 additions & 41 deletions pkg/storage/fs/ocis/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,70 +312,52 @@ func (t *Tree) Propagate(ctx context.Context, n *Node) (err error) {
for err == nil && n.ID != root.ID {
log.Debug().Interface("node", n).Msg("propagating")

parentPath := filepath.Join(t.pw.Root, "nodes", n.ParentID)
if n, err = n.Parent(); err != nil {
break
}

// TODO none, sync and async?
var propagation string
if b, err = xattr.Get(parentPath, propagationAttr); err != nil {
if e, ok := err.(*xattr.Error); ok && e.Err.Error() == "no data available" {
log.Debug().Interface("node", n).Str("attr", propagationAttr).Msg("propagation attribute not set, not propagating")
// if the attribute is not set treat it as false / none / no propagation
return nil
}
log.Error().Interface("node", n).Msg("error reading propagation attribute")
return err
}
propagation = string(b)
if propagation != "1" {
log.Debug().Interface("node", n).Msg("propagation for the parent node disabled")
// propagation for this node disabled
if !n.HasPropagation() {
log.Debug().Interface("node", n).Str("attr", propagationAttr).Msg("propagation attribute not set or unreadable, not propagating")
// if the attribute is not set treat it as false / none / no propagation
return nil
}

if t.pw.TreeTimeAccounting {
// update the parent tree time if it is older than the nodes mtime
updateSyncTime := false
if b, err = xattr.Get(parentPath, treeMTimeAttr); err != nil {
if e, ok := err.(*xattr.Error); ok && e.Err.Error() == "no data available" {
// attribute is not set, write it
log.Debug().Interface("node", n).Str("attr", treeMTimeAttr).Msg("tmtime attribute is not set, writing it")
err = nil
updateSyncTime = true
} else {
return err
}
} else {
if tmTime, err := time.Parse(time.RFC3339Nano, string(b)); err != nil {
// invalid format, overwrite
log.Error().Err(err).Interface("node", n).Str("tmtime", string(b)).Msg("invalid format, overwriting")
updateSyncTime = true
} else if tmTime.Before(fi.ModTime()) {
log.Debug().Interface("node", n).Str("tmtime", string(b)).Str("mtime", fi.ModTime().UTC().Format(time.RFC3339Nano)).Msg("parent tmtime is older than node mtime, updating")
updateSyncTime = true
} else {
log.Debug().Interface("node", n).Str("tmtime", string(b)).Str("mtime", fi.ModTime().UTC().Format(time.RFC3339Nano)).Msg("parent tmtime is younger than node mtime, not updating")
}

var tmTime time.Time
tmTime, err = n.GetTMTime()
switch {
case err != nil:
// missing attribute, or invalid format, overwrite
log.Error().Err(err).Interface("node", n).Msg("could not read tmtime attribute, overwriting")
updateSyncTime = true
case tmTime.Before(fi.ModTime()):
log.Debug().Interface("node", n).Str("tmtime", string(b)).Str("mtime", fi.ModTime().UTC().Format(time.RFC3339Nano)).Msg("parent tmtime is older than node mtime, updating")
updateSyncTime = true
default:
log.Debug().Interface("node", n).Str("tmtime", string(b)).Str("mtime", fi.ModTime().UTC().Format(time.RFC3339Nano)).Msg("parent tmtime is younger than node mtime, not updating")
}

if updateSyncTime {
// update the tree time of the parent node
if err = xattr.Set(parentPath, treeMTimeAttr, []byte(fi.ModTime().UTC().Format(time.RFC3339Nano))); err != nil {
if err = n.SetTMTime(fi.ModTime()); err != nil {
log.Error().Err(err).Interface("node", n).Time("tmtime", fi.ModTime().UTC()).Msg("could not update tmtime of parent node")
return
}
log.Debug().Interface("node", n).Time("tmtime", fi.ModTime().UTC()).Msg("updated tmtime of parent node")
}

if err := xattr.Remove(parentPath, tmpEtagAttr); err != nil {
if e, ok := err.(*xattr.Error); ok && e.Err.Error() != "no data available" {
log.Error().Interface("node", n).Str("attr", treeMTimeAttr).Msg("could not remove temporary etag attribute")
}
if err := n.UnsetTempEtag(); err != nil {
log.Error().Err(err).Interface("node", n).Msg("could not remove temporary etag attribute")
}

}

// TODO size accounting

n, err = n.Parent()
}
if err != nil {
log.Error().Err(err).Interface("node", n).Msg("error propagating")
Expand Down

0 comments on commit bbe22ea

Please sign in to comment.