github.com/scaleoutsean/fusego@v0.0.0-20220224074057-4a6429e46bb8/fuseops/simple_types.go (about)

     1  // Copyright 2015 Google Inc. All Rights Reserved.
     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 fuseops
    16  
    17  import (
    18  	"fmt"
    19  	"os"
    20  	"time"
    21  
    22  	"github.com/scaleoutsean/fusego/internal/fusekernel"
    23  )
    24  
    25  // InodeID is a 64-bit number used to uniquely identify a file or directory in
    26  // the file system. File systems may mint inode IDs with any value except for
    27  // RootInodeID.
    28  //
    29  // This corresponds to struct inode::i_no in the VFS layer.
    30  // (Cf. http://goo.gl/tvYyQt)
    31  type InodeID uint64
    32  
    33  // RootInodeID is a distinguished inode ID that identifies the root of the file
    34  // system, e.g. in an OpenDirOp or LookUpInodeOp. Unlike all other inode IDs,
    35  // which are minted by the file system, the FUSE VFS layer may send a request
    36  // for this ID without the file system ever having referenced it in a previous
    37  // response.
    38  const RootInodeID = 1
    39  
    40  func init() {
    41  	// Make sure the constant above is correct. We do this at runtime rather than
    42  	// defining the constant in terms of fusekernel.RootID for two reasons:
    43  	//
    44  	//  1. Users can more clearly see that the root ID is low and can therefore
    45  	//     be used as e.g. an array index, with space reserved up to the root.
    46  	//
    47  	//  2. The constant can be untyped and can therefore more easily be used as
    48  	//     an array index.
    49  	//
    50  	if RootInodeID != fusekernel.RootID {
    51  		panic(
    52  			fmt.Sprintf(
    53  				"Oops, RootInodeID is wrong: %v vs. %v",
    54  				RootInodeID,
    55  				fusekernel.RootID))
    56  	}
    57  }
    58  
    59  // InodeAttributes contains attributes for a file or directory inode. It
    60  // corresponds to struct inode (cf. http://goo.gl/tvYyQt).
    61  type InodeAttributes struct {
    62  	Size uint64
    63  
    64  	// The number of incoming hard links to this inode.
    65  	Nlink uint32
    66  
    67  	// The mode of the inode. This is exposed to the user in e.g. the result of
    68  	// fstat(2).
    69  	//
    70  	// Note that in contrast to the defaults for FUSE, this package mounts file
    71  	// systems in a manner such that the kernel checks inode permissions in the
    72  	// standard posix way. This is implemented by setting the default_permissions
    73  	// mount option (cf. http://goo.gl/1LxOop and http://goo.gl/1pTjuk).
    74  	//
    75  	// For example, in the case of mkdir:
    76  	//
    77  	//  *  (http://goo.gl/JkdxDI) sys_mkdirat calls inode_permission.
    78  	//
    79  	//  *  (...) inode_permission eventually calls do_inode_permission.
    80  	//
    81  	//  *  (http://goo.gl/aGCsmZ) calls i_op->permission, which is
    82  	//     fuse_permission (cf. http://goo.gl/VZ9beH).
    83  	//
    84  	//  *  (http://goo.gl/5kqUKO) fuse_permission doesn't do anything at all for
    85  	//     several code paths if FUSE_DEFAULT_PERMISSIONS is unset. In contrast,
    86  	//     if that flag *is* set, then it calls generic_permission.
    87  	//
    88  	Mode os.FileMode
    89  
    90  	// Time information. See `man 2 stat` for full details.
    91  	Atime  time.Time // Time of last access
    92  	Mtime  time.Time // Time of last modification
    93  	Ctime  time.Time // Time of last modification to inode
    94  	Crtime time.Time // Time of creation (OS X only)
    95  
    96  	// Ownership information
    97  	Uid uint32
    98  	Gid uint32
    99  }
   100  
   101  func (a *InodeAttributes) DebugString() string {
   102  	return fmt.Sprintf(
   103  		"%d %d %v %d %d",
   104  		a.Size,
   105  		a.Nlink,
   106  		a.Mode,
   107  		a.Uid,
   108  		a.Gid)
   109  }
   110  
   111  // GenerationNumber represents a generation of an inode. It is irrelevant for
   112  // file systems that won't be exported over NFS. For those that will and that
   113  // reuse inode IDs when they become free, the generation number must change
   114  // when an ID is reused.
   115  //
   116  // This corresponds to struct inode::i_generation in the VFS layer.
   117  // (Cf. http://goo.gl/tvYyQt)
   118  //
   119  // Some related reading:
   120  //
   121  //     http://fuse.sourceforge.net/doxygen/structfuse__entry__param.html
   122  //     http://stackoverflow.com/q/11071996/1505451
   123  //     http://goo.gl/CqvwyX
   124  //     http://julipedia.meroh.net/2005/09/nfs-file-handles.html
   125  //     http://goo.gl/wvo3MB
   126  //
   127  type GenerationNumber uint64
   128  
   129  // HandleID is an opaque 64-bit number used to identify a particular open
   130  // handle to a file or directory.
   131  //
   132  // This corresponds to fuse_file_info::fh.
   133  type HandleID uint64
   134  
   135  // DirOffset is an offset into an open directory handle. This is opaque to
   136  // FUSE, and can be used for whatever purpose the file system desires. See
   137  // notes on ReadDirOp.Offset for details.
   138  type DirOffset uint64
   139  
   140  // ChildInodeEntry contains information about a child inode within its parent
   141  // directory. It is shared by LookUpInodeOp, MkDirOp, CreateFileOp, etc, and is
   142  // consumed by the kernel in order to set up a dcache entry.
   143  type ChildInodeEntry struct {
   144  	// The ID of the child inode. The file system must ensure that the returned
   145  	// inode ID remains valid until a later ForgetInodeOp.
   146  	Child InodeID
   147  
   148  	// A generation number for this incarnation of the inode with the given ID.
   149  	// See comments on type GenerationNumber for more.
   150  	Generation GenerationNumber
   151  
   152  	// Current attributes for the child inode.
   153  	//
   154  	// When creating a new inode, the file system is responsible for initializing
   155  	// and recording (where supported) attributes like time information,
   156  	// ownership information, etc.
   157  	//
   158  	// Ownership information in particular must be set to something reasonable or
   159  	// by default root will own everything and unprivileged users won't be able
   160  	// to do anything useful. In traditional file systems in the kernel, the
   161  	// function inode_init_owner (http://goo.gl/5qavg8) contains the
   162  	// standards-compliant logic for this.
   163  	Attributes InodeAttributes
   164  
   165  	// The FUSE VFS layer in the kernel maintains a cache of file attributes,
   166  	// used whenever up to date information about size, mode, etc. is needed.
   167  	//
   168  	// For example, this is the abridged call chain for fstat(2):
   169  	//
   170  	//  *  (http://goo.gl/tKBH1p) fstat calls vfs_fstat.
   171  	//  *  (http://goo.gl/3HeITq) vfs_fstat eventuall calls vfs_getattr_nosec.
   172  	//  *  (http://goo.gl/DccFQr) vfs_getattr_nosec calls i_op->getattr.
   173  	//  *  (http://goo.gl/dpKkst) fuse_getattr calls fuse_update_attributes.
   174  	//  *  (http://goo.gl/yNlqPw) fuse_update_attributes uses the values in the
   175  	//     struct inode if allowed, otherwise calling out to the user-space code.
   176  	//
   177  	// In addition to obvious cases like fstat, this is also used in more subtle
   178  	// cases like updating size information before seeking (http://goo.gl/2nnMFa)
   179  	// or reading (http://goo.gl/FQSWs8).
   180  	//
   181  	// Most 'real' file systems do not set inode_operations::getattr, and
   182  	// therefore vfs_getattr_nosec calls generic_fillattr which simply grabs the
   183  	// information from the inode struct. This makes sense because these file
   184  	// systems cannot spontaneously change; all modifications go through the
   185  	// kernel which can update the inode struct as appropriate.
   186  	//
   187  	// In contrast, a FUSE file system may have spontaneous changes, so it calls
   188  	// out to user space to fetch attributes. However this is expensive, so the
   189  	// FUSE layer in the kernel caches the attributes if requested.
   190  	//
   191  	// This field controls when the attributes returned in this response and
   192  	// stashed in the struct inode should be re-queried. Leave at the zero value
   193  	// to disable caching.
   194  	//
   195  	// More reading:
   196  	//     http://stackoverflow.com/q/21540315/1505451
   197  	AttributesExpiration time.Time
   198  
   199  	// The time until which the kernel may maintain an entry for this name to
   200  	// inode mapping in its dentry cache. After this time, it will revalidate the
   201  	// dentry.
   202  	//
   203  	// As in the discussion of attribute caching above, unlike real file systems,
   204  	// FUSE file systems may spontaneously change their name -> inode mapping.
   205  	// Therefore the FUSE VFS layer uses dentry_operations::d_revalidate
   206  	// (http://goo.gl/dVea0h) to intercept lookups and revalidate by calling the
   207  	// user-space LookUpInode method. However the latter may be slow, so it
   208  	// caches the entries until the time defined by this field.
   209  	//
   210  	// Example code walk:
   211  	//
   212  	//     * (http://goo.gl/M2G3tO) lookup_dcache calls d_revalidate if enabled.
   213  	//     * (http://goo.gl/ef0Elu) fuse_dentry_revalidate just uses the dentry's
   214  	//     inode if fuse_dentry_time(entry) hasn't passed. Otherwise it sends a
   215  	//     lookup request.
   216  	//
   217  	// Leave at the zero value to disable caching.
   218  	//
   219  	// Beware: this value is ignored on OS X, where entry caching is disabled by
   220  	// default. See notes on MountConfig.EnableVnodeCaching for more.
   221  	EntryExpiration time.Time
   222  }