Skip to content

Commit bbe22ea

Browse files
committed
refactoring and changelog
Signed-off-by: Jörn Friedrich Dreyer <[email protected]>
1 parent 1e60927 commit bbe22ea

File tree

3 files changed

+67
-49
lines changed

3 files changed

+67
-49
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Enhancement: introduce ocis driver treetime accounting
2+
3+
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).
4+
It can be enabled using the new `treetime_accounting` option, which defaults to `false`
5+
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.
6+
7+
https://github.com/cs3org/reva/pull/1180

pkg/storage/fs/ocis/node.go

+37-8
Original file line numberDiff line numberDiff line change
@@ -265,15 +265,8 @@ func (n *Node) AsResourceInfo(ctx context.Context) (ri *provider.ResourceInfo, e
265265
if _, err := io.WriteString(h, n.ID); err != nil {
266266
return nil, err
267267
}
268-
var b []byte
269268
var tmTime time.Time
270-
if b, err = xattr.Get(nodePath, treeMTimeAttr); err == nil {
271-
if tmTime, err = time.Parse(time.RFC3339Nano, string(b)); err != nil {
272-
// invalid format, overwrite
273-
log.Error().Err(err).Interface("node", n).Str("tmtime", string(b)).Msg("invalid format, ignoring")
274-
tmTime = fi.ModTime()
275-
}
276-
} else {
269+
if tmTime, err = n.GetTMTime(); err != nil {
277270
// no tmtime, use mtime
278271
tmTime = fi.ModTime()
279272
}
@@ -325,3 +318,39 @@ func (n *Node) AsResourceInfo(ctx context.Context) (ri *provider.ResourceInfo, e
325318

326319
return ri, nil
327320
}
321+
322+
// HasPropagation checks if the propagation attribute exists and is set to "1"
323+
func (n *Node) HasPropagation() (propagation bool) {
324+
nodePath := filepath.Join(n.pw.Root, "nodes", n.ID)
325+
if b, err := xattr.Get(nodePath, propagationAttr); err == nil {
326+
return string(b) == "1"
327+
}
328+
return false
329+
}
330+
331+
// GetTMTime reads the tmtime from the extended attributes
332+
func (n *Node) GetTMTime() (tmTime time.Time, err error) {
333+
nodePath := filepath.Join(n.pw.Root, "nodes", n.ID)
334+
var b []byte
335+
if b, err = xattr.Get(nodePath, treeMTimeAttr); err != nil {
336+
return
337+
}
338+
return time.Parse(time.RFC3339Nano, string(b))
339+
}
340+
341+
// SetTMTime writes the tmtime to the extended attributes
342+
func (n *Node) SetTMTime(t time.Time) (err error) {
343+
nodePath := filepath.Join(n.pw.Root, "nodes", n.ID)
344+
return xattr.Set(nodePath, treeMTimeAttr, []byte(t.UTC().Format(time.RFC3339Nano)))
345+
}
346+
347+
// UnsetTempEtag removes the temporary etag attribute
348+
func (n *Node) UnsetTempEtag() (err error) {
349+
nodePath := filepath.Join(n.pw.Root, "nodes", n.ID)
350+
if err = xattr.Remove(nodePath, tmpEtagAttr); err != nil {
351+
if e, ok := err.(*xattr.Error); ok && e.Err.Error() == "no data available" {
352+
return nil
353+
}
354+
}
355+
return err
356+
}

pkg/storage/fs/ocis/tree.go

+23-41
Original file line numberDiff line numberDiff line change
@@ -312,70 +312,52 @@ func (t *Tree) Propagate(ctx context.Context, n *Node) (err error) {
312312
for err == nil && n.ID != root.ID {
313313
log.Debug().Interface("node", n).Msg("propagating")
314314

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

317319
// TODO none, sync and async?
318-
var propagation string
319-
if b, err = xattr.Get(parentPath, propagationAttr); err != nil {
320-
if e, ok := err.(*xattr.Error); ok && e.Err.Error() == "no data available" {
321-
log.Debug().Interface("node", n).Str("attr", propagationAttr).Msg("propagation attribute not set, not propagating")
322-
// if the attribute is not set treat it as false / none / no propagation
323-
return nil
324-
}
325-
log.Error().Interface("node", n).Msg("error reading propagation attribute")
326-
return err
327-
}
328-
propagation = string(b)
329-
if propagation != "1" {
330-
log.Debug().Interface("node", n).Msg("propagation for the parent node disabled")
331-
// propagation for this node disabled
320+
if !n.HasPropagation() {
321+
log.Debug().Interface("node", n).Str("attr", propagationAttr).Msg("propagation attribute not set or unreadable, not propagating")
322+
// if the attribute is not set treat it as false / none / no propagation
332323
return nil
333324
}
334325

335326
if t.pw.TreeTimeAccounting {
336327
// update the parent tree time if it is older than the nodes mtime
337328
updateSyncTime := false
338-
if b, err = xattr.Get(parentPath, treeMTimeAttr); err != nil {
339-
if e, ok := err.(*xattr.Error); ok && e.Err.Error() == "no data available" {
340-
// attribute is not set, write it
341-
log.Debug().Interface("node", n).Str("attr", treeMTimeAttr).Msg("tmtime attribute is not set, writing it")
342-
err = nil
343-
updateSyncTime = true
344-
} else {
345-
return err
346-
}
347-
} else {
348-
if tmTime, err := time.Parse(time.RFC3339Nano, string(b)); err != nil {
349-
// invalid format, overwrite
350-
log.Error().Err(err).Interface("node", n).Str("tmtime", string(b)).Msg("invalid format, overwriting")
351-
updateSyncTime = true
352-
} else if tmTime.Before(fi.ModTime()) {
353-
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")
354-
updateSyncTime = true
355-
} else {
356-
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")
357-
}
329+
330+
var tmTime time.Time
331+
tmTime, err = n.GetTMTime()
332+
switch {
333+
case err != nil:
334+
// missing attribute, or invalid format, overwrite
335+
log.Error().Err(err).Interface("node", n).Msg("could not read tmtime attribute, overwriting")
336+
updateSyncTime = true
337+
case tmTime.Before(fi.ModTime()):
338+
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")
339+
updateSyncTime = true
340+
default:
341+
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")
358342
}
343+
359344
if updateSyncTime {
360345
// update the tree time of the parent node
361-
if err = xattr.Set(parentPath, treeMTimeAttr, []byte(fi.ModTime().UTC().Format(time.RFC3339Nano))); err != nil {
346+
if err = n.SetTMTime(fi.ModTime()); err != nil {
362347
log.Error().Err(err).Interface("node", n).Time("tmtime", fi.ModTime().UTC()).Msg("could not update tmtime of parent node")
363348
return
364349
}
365350
log.Debug().Interface("node", n).Time("tmtime", fi.ModTime().UTC()).Msg("updated tmtime of parent node")
366351
}
367352

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

374357
}
375358

376359
// TODO size accounting
377360

378-
n, err = n.Parent()
379361
}
380362
if err != nil {
381363
log.Error().Err(err).Interface("node", n).Msg("error propagating")

0 commit comments

Comments
 (0)