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 }