github.com/cs3org/reva/v2@v2.27.7/pkg/storage/utils/decomposedfs/timemanager/timemanager.go (about)

     1  // Copyright 2018-2024 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //	http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  package timemanager
    19  
    20  import (
    21  	"context"
    22  	"os"
    23  	"time"
    24  
    25  	"github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/metadata/prefixes"
    26  	"github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node"
    27  )
    28  
    29  // Manager is responsible for managing time-related attributes of nodes in a decomposed file system.
    30  type Manager struct {
    31  }
    32  
    33  // OverrideMtime overrides the modification time (mtime) attribute of a node with the given time.
    34  func (m *Manager) OverrideMtime(ctx context.Context, _ *node.Node, attrs *node.Attributes, mtime time.Time) error {
    35  	attrs.SetString(prefixes.MTimeAttr, mtime.UTC().Format(time.RFC3339Nano))
    36  	return nil
    37  }
    38  
    39  // MTime retrieves the modification time (mtime) attribute of a node.
    40  // If the attribute is not set, it falls back to the file's last modification time.
    41  func (dtm *Manager) MTime(ctx context.Context, n *node.Node) (time.Time, error) {
    42  	b, err := n.XattrString(ctx, prefixes.MTimeAttr)
    43  	if err != nil {
    44  		fi, err := os.Lstat(n.InternalPath())
    45  		if err != nil {
    46  			return time.Time{}, err
    47  		}
    48  		return fi.ModTime(), nil
    49  	}
    50  	return time.Parse(time.RFC3339Nano, b)
    51  }
    52  
    53  // SetMTime sets the modification time (mtime) attribute of a node to the given time.
    54  // If the time is nil, the attribute is removed.
    55  func (dtm *Manager) SetMTime(ctx context.Context, n *node.Node, mtime *time.Time) error {
    56  	if mtime == nil {
    57  		return n.RemoveXattr(ctx, prefixes.MTimeAttr, true)
    58  	}
    59  	return n.SetXattrString(ctx, prefixes.MTimeAttr, mtime.UTC().Format(time.RFC3339Nano))
    60  }
    61  
    62  // TMTime retrieves the tree modification time (tmtime) attribute of a node.
    63  // If the attribute is not set, it falls back to the node's modification time (mtime).
    64  func (dtm *Manager) TMTime(ctx context.Context, n *node.Node) (time.Time, error) {
    65  	b, err := n.XattrString(ctx, prefixes.TreeMTimeAttr)
    66  	if err == nil {
    67  		return time.Parse(time.RFC3339Nano, b)
    68  	}
    69  
    70  	// no tmtime, use mtime
    71  	return dtm.MTime(ctx, n)
    72  }
    73  
    74  // SetTMTime sets the tree modification time (tmtime) attribute of a node to the given time.
    75  // If the time is nil, the attribute is removed.
    76  func (dtm *Manager) SetTMTime(ctx context.Context, n *node.Node, tmtime *time.Time) error {
    77  	if tmtime == nil {
    78  		return n.RemoveXattr(ctx, prefixes.TreeMTimeAttr, true)
    79  	}
    80  	return n.SetXattrString(ctx, prefixes.TreeMTimeAttr, tmtime.UTC().Format(time.RFC3339Nano))
    81  }
    82  
    83  // CTime retrieves the creation time (ctime) attribute of a node.
    84  // Since decomposedfs does not differentiate between ctime and mtime, it falls back to the node's modification time (mtime).
    85  func (dtm *Manager) CTime(ctx context.Context, n *node.Node) (time.Time, error) {
    86  	// decomposedfs does not differentiate between ctime and mtime
    87  	return dtm.MTime(ctx, n)
    88  }
    89  
    90  // SetCTime sets the creation time (ctime) attribute of a node to the given time.
    91  // Since decomposedfs does not differentiate between ctime and mtime, it sets the modification time (mtime) instead.
    92  func (dtm *Manager) SetCTime(ctx context.Context, n *node.Node, mtime *time.Time) error {
    93  	// decomposedfs does not differentiate between ctime and mtime
    94  	return dtm.SetMTime(ctx, n, mtime)
    95  }
    96  
    97  // TCTime retrieves the tree creation time (tctime) attribute of a node.
    98  // Since decomposedfs does not differentiate between ctime and mtime, it falls back to the tree modification time (tmtime).
    99  func (dtm *Manager) TCTime(ctx context.Context, n *node.Node) (time.Time, error) {
   100  	// decomposedfs does not differentiate between ctime and mtime
   101  	return dtm.TMTime(ctx, n)
   102  }
   103  
   104  // SetTCTime sets the tree creation time (tctime) attribute of a node to the given time.
   105  // Since decomposedfs does not differentiate between ctime and mtime, it sets the tree modification time (tmtime) instead.
   106  func (dtm *Manager) SetTCTime(ctx context.Context, n *node.Node, tmtime *time.Time) error {
   107  	// decomposedfs does not differentiate between ctime and mtime
   108  	return dtm.SetTMTime(ctx, n, tmtime)
   109  }
   110  
   111  // DTime retrieves the deletion time (dtime) attribute of a node.
   112  func (dtm *Manager) DTime(ctx context.Context, n *node.Node) (tmTime time.Time, err error) {
   113  	b, err := n.XattrString(ctx, prefixes.DTimeAttr)
   114  	if err != nil {
   115  		return time.Time{}, err
   116  	}
   117  	return time.Parse(time.RFC3339Nano, b)
   118  }
   119  
   120  // SetDTime sets the deletion time (dtime) attribute of a node to the given time.
   121  // If the time is nil, the attribute is removed.
   122  func (dtm *Manager) SetDTime(ctx context.Context, n *node.Node, t *time.Time) (err error) {
   123  	if t == nil {
   124  		return n.RemoveXattr(ctx, prefixes.DTimeAttr, true)
   125  	}
   126  	return n.SetXattrString(ctx, prefixes.DTimeAttr, t.UTC().Format(time.RFC3339Nano))
   127  }