From 30913f26b675803940d8cca424f1f49b93822930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Wed, 21 Oct 2020 13:33:27 +0200 Subject: [PATCH] fix etag propagation in ocis driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- .../unreleased/ocis-fix-etag-propagation.md | 5 +++ pkg/storage/fs/ocis/tree.go | 35 +++++++++++-------- 2 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 changelog/unreleased/ocis-fix-etag-propagation.md diff --git a/changelog/unreleased/ocis-fix-etag-propagation.md b/changelog/unreleased/ocis-fix-etag-propagation.md new file mode 100644 index 00000000000..e95f886d1fc --- /dev/null +++ b/changelog/unreleased/ocis-fix-etag-propagation.md @@ -0,0 +1,5 @@ +Bugfix: Fix etag propagation in ocis driver + +We now use a new synctime timestamp instead of trying to read the mtime to avoid race conditions when the stat request happens too quickly. + +https://github.com/cs3org/reva/pull/1264 \ No newline at end of file diff --git a/pkg/storage/fs/ocis/tree.go b/pkg/storage/fs/ocis/tree.go index dd49c044cb4..1d1e56a7845 100644 --- a/pkg/storage/fs/ocis/tree.go +++ b/pkg/storage/fs/ocis/tree.go @@ -316,8 +316,6 @@ func (t *Tree) Propagate(ctx context.Context, n *Node) (err error) { } log := appctx.GetLogger(ctx) - nodePath := t.lu.toInternalPath(n.ID) - // is propagation enabled for the parent node? var root *Node @@ -325,12 +323,8 @@ func (t *Tree) Propagate(ctx context.Context, n *Node) (err error) { return } - var fi os.FileInfo - if fi, err = os.Stat(nodePath); err != nil { - return err - } - - var b []byte + // use a sync time and don't rely on the mtime of the current node, as the stat might not change when a rename happened too quickly + sTime := time.Now().UTC() for err == nil && n.ID != root.ID { log.Debug().Interface("node", n).Msg("propagating") @@ -355,22 +349,33 @@ func (t *Tree) Propagate(ctx context.Context, n *Node) (err error) { switch { case err != nil: // missing attribute, or invalid format, overwrite - log.Error().Err(err).Interface("node", n).Msg("could not read tmtime attribute, overwriting") + 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") + case tmTime.Before(sTime): + log.Debug(). + Interface("node", n). + Time("tmtime", tmTime). + Time("stime", sTime). + 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") + log.Debug(). + Interface("node", n). + Time("tmtime", tmTime). + Time("stime", sTime). + Dur("delta", sTime.Sub(tmTime)). + Msg("parent tmtime is younger than node mtime, not updating") } if updateSyncTime { // update the tree time of the parent node - 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") + if err = n.SetTMTime(sTime); err != nil { + log.Error().Err(err).Interface("node", n).Time("tmtime", sTime).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") + log.Debug().Interface("node", n).Time("tmtime", sTime).Msg("updated tmtime of parent node") } if err := n.UnsetTempEtag(); err != nil {