github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/fs/gofer/util.go (about)

     1  // Copyright 2018 The gVisor Authors.
     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  package gofer
    16  
    17  import (
    18  	"golang.org/x/sys/unix"
    19  	"github.com/SagerNet/gvisor/pkg/context"
    20  	"github.com/SagerNet/gvisor/pkg/p9"
    21  	"github.com/SagerNet/gvisor/pkg/sentry/fs"
    22  	ktime "github.com/SagerNet/gvisor/pkg/sentry/kernel/time"
    23  )
    24  
    25  func utimes(ctx context.Context, file contextFile, ts fs.TimeSpec) error {
    26  	if ts.ATimeOmit && ts.MTimeOmit {
    27  		return nil
    28  	}
    29  
    30  	// Replace requests to use the "system time" with the current time to
    31  	// ensure that timestamps remain consistent with the remote
    32  	// filesystem.
    33  	now := ktime.NowFromContext(ctx)
    34  	if ts.ATimeSetSystemTime {
    35  		ts.ATime = now
    36  	}
    37  	if ts.MTimeSetSystemTime {
    38  		ts.MTime = now
    39  	}
    40  	mask := p9.SetAttrMask{
    41  		ATime:              !ts.ATimeOmit,
    42  		ATimeNotSystemTime: true,
    43  		MTime:              !ts.MTimeOmit,
    44  		MTimeNotSystemTime: true,
    45  	}
    46  	as, ans := ts.ATime.Unix()
    47  	ms, mns := ts.MTime.Unix()
    48  	attr := p9.SetAttr{
    49  		ATimeSeconds:     uint64(as),
    50  		ATimeNanoSeconds: uint64(ans),
    51  		MTimeSeconds:     uint64(ms),
    52  		MTimeNanoSeconds: uint64(mns),
    53  	}
    54  	// 9p2000.L SetAttr: "If a time bit is set without the corresponding SET bit,
    55  	// the current system time on the server is used instead of the value sent
    56  	// in the request."
    57  	return file.setAttr(ctx, mask, attr)
    58  }
    59  
    60  func openFlagsFromPerms(p fs.PermMask) (p9.OpenFlags, error) {
    61  	switch {
    62  	case p.Read && p.Write:
    63  		return p9.ReadWrite, nil
    64  	case p.Write:
    65  		return p9.WriteOnly, nil
    66  	case p.Read:
    67  		return p9.ReadOnly, nil
    68  	default:
    69  		return 0, unix.EINVAL
    70  	}
    71  }