github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/fs/gofer/context_file.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  	"github.com/SagerNet/gvisor/pkg/context"
    19  	"github.com/SagerNet/gvisor/pkg/fd"
    20  	"github.com/SagerNet/gvisor/pkg/p9"
    21  )
    22  
    23  // contextFile is a wrapper around p9.File that notifies the context that
    24  // it's about to sleep before calling the Gofer over P9.
    25  type contextFile struct {
    26  	file p9.File
    27  }
    28  
    29  func (c *contextFile) walk(ctx context.Context, names []string) ([]p9.QID, contextFile, error) {
    30  	ctx.UninterruptibleSleepStart(false)
    31  
    32  	q, f, err := c.file.Walk(names)
    33  	if err != nil {
    34  		ctx.UninterruptibleSleepFinish(false)
    35  		return nil, contextFile{}, err
    36  	}
    37  	ctx.UninterruptibleSleepFinish(false)
    38  	return q, contextFile{file: f}, nil
    39  }
    40  
    41  func (c *contextFile) statFS(ctx context.Context) (p9.FSStat, error) {
    42  	ctx.UninterruptibleSleepStart(false)
    43  	s, err := c.file.StatFS()
    44  	ctx.UninterruptibleSleepFinish(false)
    45  	return s, err
    46  }
    47  
    48  func (c *contextFile) getAttr(ctx context.Context, req p9.AttrMask) (p9.QID, p9.AttrMask, p9.Attr, error) {
    49  	ctx.UninterruptibleSleepStart(false)
    50  	q, m, a, err := c.file.GetAttr(req)
    51  	ctx.UninterruptibleSleepFinish(false)
    52  	return q, m, a, err
    53  }
    54  
    55  func (c *contextFile) setAttr(ctx context.Context, valid p9.SetAttrMask, attr p9.SetAttr) error {
    56  	ctx.UninterruptibleSleepStart(false)
    57  	err := c.file.SetAttr(valid, attr)
    58  	ctx.UninterruptibleSleepFinish(false)
    59  	return err
    60  }
    61  
    62  func (c *contextFile) getXattr(ctx context.Context, name string, size uint64) (string, error) {
    63  	ctx.UninterruptibleSleepStart(false)
    64  	val, err := c.file.GetXattr(name, size)
    65  	ctx.UninterruptibleSleepFinish(false)
    66  	return val, err
    67  }
    68  
    69  func (c *contextFile) setXattr(ctx context.Context, name, value string, flags uint32) error {
    70  	ctx.UninterruptibleSleepStart(false)
    71  	err := c.file.SetXattr(name, value, flags)
    72  	ctx.UninterruptibleSleepFinish(false)
    73  	return err
    74  }
    75  
    76  func (c *contextFile) listXattr(ctx context.Context, size uint64) (map[string]struct{}, error) {
    77  	ctx.UninterruptibleSleepStart(false)
    78  	xattrs, err := c.file.ListXattr(size)
    79  	ctx.UninterruptibleSleepFinish(false)
    80  	return xattrs, err
    81  }
    82  
    83  func (c *contextFile) removeXattr(ctx context.Context, name string) error {
    84  	ctx.UninterruptibleSleepStart(false)
    85  	err := c.file.RemoveXattr(name)
    86  	ctx.UninterruptibleSleepFinish(false)
    87  	return err
    88  }
    89  
    90  func (c *contextFile) allocate(ctx context.Context, mode p9.AllocateMode, offset, length uint64) error {
    91  	ctx.UninterruptibleSleepStart(false)
    92  	err := c.file.Allocate(mode, offset, length)
    93  	ctx.UninterruptibleSleepFinish(false)
    94  	return err
    95  }
    96  
    97  func (c *contextFile) rename(ctx context.Context, directory contextFile, name string) error {
    98  	ctx.UninterruptibleSleepStart(false)
    99  	err := c.file.Rename(directory.file, name)
   100  	ctx.UninterruptibleSleepFinish(false)
   101  	return err
   102  }
   103  
   104  func (c *contextFile) close(ctx context.Context) error {
   105  	ctx.UninterruptibleSleepStart(false)
   106  	err := c.file.Close()
   107  	ctx.UninterruptibleSleepFinish(false)
   108  	return err
   109  }
   110  
   111  func (c *contextFile) open(ctx context.Context, mode p9.OpenFlags) (*fd.FD, p9.QID, uint32, error) {
   112  	ctx.UninterruptibleSleepStart(false)
   113  	f, q, u, err := c.file.Open(mode)
   114  	ctx.UninterruptibleSleepFinish(false)
   115  	return f, q, u, err
   116  }
   117  
   118  func (c *contextFile) readAt(ctx context.Context, p []byte, offset uint64) (int, error) {
   119  	ctx.UninterruptibleSleepStart(false)
   120  	n, err := c.file.ReadAt(p, offset)
   121  	ctx.UninterruptibleSleepFinish(false)
   122  	return n, err
   123  }
   124  
   125  func (c *contextFile) writeAt(ctx context.Context, p []byte, offset uint64) (int, error) {
   126  	ctx.UninterruptibleSleepStart(false)
   127  	n, err := c.file.WriteAt(p, offset)
   128  	ctx.UninterruptibleSleepFinish(false)
   129  	return n, err
   130  }
   131  
   132  func (c *contextFile) fsync(ctx context.Context) error {
   133  	ctx.UninterruptibleSleepStart(false)
   134  	err := c.file.FSync()
   135  	ctx.UninterruptibleSleepFinish(false)
   136  	return err
   137  }
   138  
   139  func (c *contextFile) create(ctx context.Context, name string, flags p9.OpenFlags, permissions p9.FileMode, uid p9.UID, gid p9.GID) (*fd.FD, error) {
   140  	ctx.UninterruptibleSleepStart(false)
   141  	fd, _, _, _, err := c.file.Create(name, flags, permissions, uid, gid)
   142  	ctx.UninterruptibleSleepFinish(false)
   143  	return fd, err
   144  }
   145  
   146  func (c *contextFile) mkdir(ctx context.Context, name string, permissions p9.FileMode, uid p9.UID, gid p9.GID) (p9.QID, error) {
   147  	ctx.UninterruptibleSleepStart(false)
   148  	q, err := c.file.Mkdir(name, permissions, uid, gid)
   149  	ctx.UninterruptibleSleepFinish(false)
   150  	return q, err
   151  }
   152  
   153  func (c *contextFile) symlink(ctx context.Context, oldName string, newName string, uid p9.UID, gid p9.GID) (p9.QID, error) {
   154  	ctx.UninterruptibleSleepStart(false)
   155  	q, err := c.file.Symlink(oldName, newName, uid, gid)
   156  	ctx.UninterruptibleSleepFinish(false)
   157  	return q, err
   158  }
   159  
   160  func (c *contextFile) link(ctx context.Context, target *contextFile, newName string) error {
   161  	ctx.UninterruptibleSleepStart(false)
   162  	err := c.file.Link(target.file, newName)
   163  	ctx.UninterruptibleSleepFinish(false)
   164  	return err
   165  }
   166  
   167  func (c *contextFile) mknod(ctx context.Context, name string, permissions p9.FileMode, major uint32, minor uint32, uid p9.UID, gid p9.GID) (p9.QID, error) {
   168  	ctx.UninterruptibleSleepStart(false)
   169  	q, err := c.file.Mknod(name, permissions, major, minor, uid, gid)
   170  	ctx.UninterruptibleSleepFinish(false)
   171  	return q, err
   172  }
   173  
   174  func (c *contextFile) unlinkAt(ctx context.Context, name string, flags uint32) error {
   175  	ctx.UninterruptibleSleepStart(false)
   176  	err := c.file.UnlinkAt(name, flags)
   177  	ctx.UninterruptibleSleepFinish(false)
   178  	return err
   179  }
   180  
   181  func (c *contextFile) readdir(ctx context.Context, offset uint64, count uint32) ([]p9.Dirent, error) {
   182  	ctx.UninterruptibleSleepStart(false)
   183  	d, err := c.file.Readdir(offset, count)
   184  	ctx.UninterruptibleSleepFinish(false)
   185  	return d, err
   186  }
   187  
   188  func (c *contextFile) readlink(ctx context.Context) (string, error) {
   189  	ctx.UninterruptibleSleepStart(false)
   190  	s, err := c.file.Readlink()
   191  	ctx.UninterruptibleSleepFinish(false)
   192  	return s, err
   193  }
   194  
   195  func (c *contextFile) flush(ctx context.Context) error {
   196  	ctx.UninterruptibleSleepStart(false)
   197  	err := c.file.Flush()
   198  	ctx.UninterruptibleSleepFinish(false)
   199  	return err
   200  }
   201  
   202  func (c *contextFile) walkGetAttr(ctx context.Context, names []string) ([]p9.QID, contextFile, p9.AttrMask, p9.Attr, error) {
   203  	ctx.UninterruptibleSleepStart(false)
   204  	q, f, m, a, err := c.file.WalkGetAttr(names)
   205  	if err != nil {
   206  		ctx.UninterruptibleSleepFinish(false)
   207  		return nil, contextFile{}, p9.AttrMask{}, p9.Attr{}, err
   208  	}
   209  	ctx.UninterruptibleSleepFinish(false)
   210  	return q, contextFile{file: f}, m, a, nil
   211  }
   212  
   213  func (c *contextFile) connect(ctx context.Context, flags p9.ConnectFlags) (*fd.FD, error) {
   214  	ctx.UninterruptibleSleepStart(false)
   215  	f, err := c.file.Connect(flags)
   216  	ctx.UninterruptibleSleepFinish(false)
   217  	return f, err
   218  }