github.com/cs3org/reva/v2@v2.27.7/pkg/storage/fs/posix/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  
    19  package timemanager
    20  
    21  import (
    22  	"context"
    23  	"os"
    24  	"syscall"
    25  	"time"
    26  
    27  	"github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/metadata/prefixes"
    28  	"github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node"
    29  )
    30  
    31  // Manager is responsible for managing time-related operations on files and directories.
    32  type Manager struct {
    33  }
    34  
    35  // OverrideMtime overrides the modification time (mtime) of a node with the specified time.
    36  func (m *Manager) OverrideMtime(ctx context.Context, n *node.Node, _ *node.Attributes, mtime time.Time) error {
    37  	return os.Chtimes(n.InternalPath(), mtime, mtime)
    38  }
    39  
    40  // MTime returns the modification time (mtime) of a node.
    41  func (m *Manager) MTime(ctx context.Context, n *node.Node) (time.Time, error) {
    42  	fi, err := os.Stat(n.InternalPath())
    43  	if err != nil {
    44  		return time.Time{}, err
    45  	}
    46  	return fi.ModTime(), nil
    47  }
    48  
    49  // SetMTime sets the modification time (mtime) of a node to the specified time.
    50  func (m *Manager) SetMTime(ctx context.Context, n *node.Node, mtime *time.Time) error {
    51  	return os.Chtimes(n.InternalPath(), *mtime, *mtime)
    52  }
    53  
    54  // TMTime returns the tree modification time (tmtime) of a node.
    55  // If the tmtime is not set, it falls back to the modification time (mtime).
    56  func (m *Manager) TMTime(ctx context.Context, n *node.Node) (time.Time, error) {
    57  	b, err := n.XattrString(ctx, prefixes.TreeMTimeAttr)
    58  	if err == nil {
    59  		return time.Parse(time.RFC3339Nano, b)
    60  	}
    61  
    62  	// no tmtime, use mtime
    63  	return m.MTime(ctx, n)
    64  }
    65  
    66  // SetTMTime sets the tree modification time (tmtime) of a node to the specified time.
    67  // If tmtime is nil, the tmtime attribute is removed.
    68  func (m *Manager) SetTMTime(ctx context.Context, n *node.Node, tmtime *time.Time) error {
    69  	if tmtime == nil {
    70  		return n.RemoveXattr(ctx, prefixes.TreeMTimeAttr, true)
    71  	}
    72  	return n.SetXattrString(ctx, prefixes.TreeMTimeAttr, tmtime.UTC().Format(time.RFC3339Nano))
    73  }
    74  
    75  // CTime returns the creation time (ctime) of a node.
    76  func (m *Manager) CTime(ctx context.Context, n *node.Node) (time.Time, error) {
    77  	fi, err := os.Stat(n.InternalPath())
    78  	if err != nil {
    79  		return time.Time{}, err
    80  	}
    81  
    82  	stat := fi.Sys().(*syscall.Stat_t)
    83  	statCTime := StatCTime(stat)
    84  	//nolint:unconvert
    85  	return time.Unix(int64(statCTime.Sec), int64(statCTime.Nsec)), nil
    86  }
    87  
    88  // TCTime returns the tree creation time (tctime) of a node.
    89  // Since decomposedfs does not differentiate between ctime and mtime, it falls back to TMTime.
    90  func (m *Manager) TCTime(ctx context.Context, n *node.Node) (time.Time, error) {
    91  	// decomposedfs does not differentiate between ctime and mtime
    92  	return m.TMTime(ctx, n)
    93  }
    94  
    95  // SetTCTime sets the tree creation time (tctime) of a node to the specified time.
    96  // Since decomposedfs does not differentiate between ctime and mtime, it falls back to SetTMTime.
    97  func (m *Manager) SetTCTime(ctx context.Context, n *node.Node, tmtime *time.Time) error {
    98  	// decomposedfs does not differentiate between ctime and mtime
    99  	return m.SetTMTime(ctx, n, tmtime)
   100  }
   101  
   102  // DTime returns the deletion time (dtime) of a node.
   103  func (m *Manager) DTime(ctx context.Context, n *node.Node) (tmTime time.Time, err error) {
   104  	b, err := n.XattrString(ctx, prefixes.DTimeAttr)
   105  	if err != nil {
   106  		return time.Time{}, err
   107  	}
   108  	return time.Parse(time.RFC3339Nano, b)
   109  }
   110  
   111  // SetDTime sets the deletion time (dtime) of a node to the specified time.
   112  // If t is nil, the dtime attribute is removed.
   113  func (m *Manager) SetDTime(ctx context.Context, n *node.Node, t *time.Time) (err error) {
   114  	if t == nil {
   115  		return n.RemoveXattr(ctx, prefixes.DTimeAttr, true)
   116  	}
   117  	return n.SetXattrString(ctx, prefixes.DTimeAttr, t.UTC().Format(time.RFC3339Nano))
   118  }