Documentation ¶
Index ¶
- Constants
- func IsDirName(name string) bool
- func IsSymlink(o *gcs.Object) bool
- type DirInode
- type ExplicitDirInode
- type FileInode
- func (f *FileInode) Attributes(ctx context.Context) (attrs fuseops.InodeAttributes, err error)
- func (f *FileInode) DecrementLookupCount(n uint64) (destroy bool)
- func (f *FileInode) Destroy() (err error)
- func (f *FileInode) ID() fuseops.InodeID
- func (f *FileInode) IncrementLookupCount()
- func (f *FileInode) Lock()
- func (f *FileInode) Name() string
- func (f *FileInode) Read(ctx context.Context, offset int64, size int) (data []byte, err error)
- func (f *FileInode) SourceGeneration() int64
- func (f *FileInode) Sync(ctx context.Context) (err error)
- func (f *FileInode) Truncate(ctx context.Context, size int64) (err error)
- func (f *FileInode) Unlock()
- func (f *FileInode) Write(ctx context.Context, data []byte, offset int64) (err error)
- type Inode
- type LookUpResult
- type SymlinkInode
- func (s *SymlinkInode) Attributes(ctx context.Context) (attrs fuseops.InodeAttributes, err error)
- func (s *SymlinkInode) DecrementLookupCount(n uint64) (destroy bool)
- func (s *SymlinkInode) Destroy() (err error)
- func (s *SymlinkInode) ID() fuseops.InodeID
- func (s *SymlinkInode) IncrementLookupCount()
- func (s *SymlinkInode) Lock()
- func (s *SymlinkInode) Name() string
- func (s *SymlinkInode) SourceGeneration() int64
- func (s *SymlinkInode) Target() (target string)
- func (s *SymlinkInode) Unlock()
Constants ¶
const ConflictingFileNameSuffix = "\n"
A suffix that can be used to unambiguously tag a file system name. (Unambiguous because U+000A is not allowed in GCS object names.) This is used to refer to the file/symlink in a (file/symlink, directory) pair with conflicting object names.
See also the notes on DirInode.LookUpChild.
const SymlinkMetadataKey = "gcsfuse_symlink_target"
When this custom metadata key is present in an object record, it is to be treated as a symlink. For use in testing only; other users should detect this with IsSymlink.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type DirInode ¶
type DirInode interface { Inode // Look up the direct child with the given relative name, returning // information about the object backing the child or whether it exists as an // implicit directory. If a file/symlink and a directory with the given name // both exist, the directory is preferred. Return a result with // !result.Exists() and a nil error if neither is found. // // Special case: if the name ends in ConflictingFileNameSuffix, we strip the // suffix, confirm that a conflicting directory exists, then return a result // for the file/symlink. // // If this inode was created with implicitDirs is set, this method will use // ListObjects to find child directories that are "implicitly" defined by the // existence of their own descendents. For example, if there is an object // named "foo/bar/baz" and this is the directory "foo", a child directory // named "bar" will be implied. In this case, result.ImplicitDir will be // true. LookUpChild( ctx context.Context, name string) (result LookUpResult, err error) // Read some number of entries from the directory, returning a continuation // token that can be used to pick up the read operation where it left off. // Supply the empty token on the first call. // // At the end of the directory, the returned continuation token will be // empty. Otherwise it will be non-empty. There is no guarantee about the // number of entries returned; it may be zero even with a non-empty // continuation token. // // The contents of the Offset and Inode fields for returned entries is // undefined. ReadEntries( ctx context.Context, tok string) (entries []fuseutil.Dirent, newTok string, err error) // Create an empty child file with the supplied (relative) name, failing with // *gcs.PreconditionError if a backing object already exists in GCS. CreateChildFile( ctx context.Context, name string) (o *gcs.Object, err error) // Like CreateChildFile, except clone the supplied source object instead of // creating an empty object. CloneToChildFile( ctx context.Context, name string, src *gcs.Object) (o *gcs.Object, err error) // Create a symlink object with the supplied (relative) name and the supplied // target, failing with *gcs.PreconditionError if a backing object already // exists in GCS. CreateChildSymlink( ctx context.Context, name string, target string) (o *gcs.Object, err error) // Create a backing object for a child directory with the supplied (relative) // name, failing with *gcs.PreconditionError if a backing object already // exists in GCS. CreateChildDir( ctx context.Context, name string) (o *gcs.Object, err error) // Delete the backing object for the child file or symlink with the given // (relative) name and generation, where zero means the latest generation. If // the object/generation doesn't exist, no error is returned. DeleteChildFile( ctx context.Context, name string, generation int64) (err error) // Delete the backing object for the child directory with the given // (relative) name. DeleteChildDir( ctx context.Context, name string) (err error) }
An inode representing a directory, with facilities for listing entries, looking up children, and creating and deleting children. Must be locked for any method additional to the Inode interface.
func NewDirInode ¶
func NewDirInode( id fuseops.InodeID, name string, attrs fuseops.InodeAttributes, implicitDirs bool, typeCacheTTL time.Duration, bucket gcs.Bucket, clock timeutil.Clock) (d DirInode)
Create a directory inode for the name, representing the directory containing the objects for which it is an immediate prefix. For the root directory, this is the empty string.
If implicitDirs is set, LookUpChild will use ListObjects to find child directories that are "implicitly" defined by the existence of their own descendents. For example, if there is an object named "foo/bar/baz" and this is the directory "foo", a child directory named "bar" will be implied.
If typeCacheTTL is non-zero, a cache from child name to information about whether that name exists as a file/symlink and/or directory will be maintained. This may speed up calls to LookUpChild, especially when combined with a stat-caching GCS bucket, but comes at the cost of consistency: if the child is removed and recreated with a different type before the expiration, we may fail to find it.
The initial lookup count is zero.
REQUIRES: IsDirName(name)
type ExplicitDirInode ¶
type ExplicitDirInode interface { DirInode // Return the object generation number from which this inode was branched. SourceGeneration() int64 }
An inode representing a directory backed by an object in GCS with a specific generation.
func NewExplicitDirInode ¶
func NewExplicitDirInode( id fuseops.InodeID, o *gcs.Object, attrs fuseops.InodeAttributes, implicitDirs bool, typeCacheTTL time.Duration, bucket gcs.Bucket, clock timeutil.Clock) (d ExplicitDirInode)
Create an explicit dir inode backed by the supplied object. See notes on NewDirInode for more.
type FileInode ¶
type FileInode struct {
// contains filtered or unexported fields
}
func NewFileInode ¶
func NewFileInode( id fuseops.InodeID, o *gcs.Object, attrs fuseops.InodeAttributes, gcsChunkSize uint64, bucket gcs.Bucket, leaser lease.FileLeaser, objectSyncer gcsproxy.ObjectSyncer, clock timeutil.Clock) (f *FileInode)
Create a file inode for the given object in GCS. The initial lookup count is zero.
gcsChunkSize controls the maximum size of each individual read request made to GCS.
REQUIRES: o != nil REQUIRES: o.Generation > 0 REQUIRES: len(o.Name) > 0 REQUIRES: o.Name[len(o.Name)-1] != '/'
func (*FileInode) Attributes ¶
LOCKS_REQUIRED(f.mu)
func (*FileInode) DecrementLookupCount ¶
LOCKS_REQUIRED(f.mu)
func (*FileInode) IncrementLookupCount ¶
func (f *FileInode) IncrementLookupCount()
LOCKS_REQUIRED(f.mu)
func (*FileInode) Read ¶
Serve a read for this file with semantics matching fuseops.ReadFileOp.
LOCKS_REQUIRED(f.mu)
func (*FileInode) SourceGeneration ¶
Return the object generation number from which this inode was branched.
LOCKS_REQUIRED(f)
func (*FileInode) Sync ¶
Write out contents to GCS. If this fails due to the generation having been clobbered, treat it as a non-error (simulating the inode having been unlinked).
After this method succeeds, SourceGeneration will return the new generation by which this inode should be known (which may be the same as before). If it fails, the generation will not change.
LOCKS_REQUIRED(f.mu)
type Inode ¶
type Inode interface { // All methods below require the lock to be held unless otherwise documented. sync.Locker // Return the ID assigned to the inode. // // Does not require the lock to be held. ID() fuseops.InodeID // Return the name of the GCS object backing the inode. This may be "foo/bar" // for a file, or "foo/bar/" for a directory. // // Does not require the lock to be held. Name() string // Increment the lookup count for the inode. For use in fuse operations where // the kernel expects us to remember the inode. IncrementLookupCount() // Return up to date attributes for this inode. Attributes(ctx context.Context) (fuseops.InodeAttributes, error) // Decrement the lookup count for the inode by the given amount. // // If this method returns true, the lookup count has hit zero and the // Destroy() method should be called to release any local resources, perhaps // after releasing locks that should not be held while blocking. DecrementLookupCount(n uint64) (destroy bool) // Clean up any local resources used by the inode, putting it into an // indeterminate state where no method should be called except Unlock. // // This method may block. Errors are for logging purposes only. Destroy() (err error) }
type LookUpResult ¶
type LookUpResult struct { // For both object-backed children and implicit directories, the full // canonical name of the child. For example, if the parent inode is "foo/" // and the child is a directory, then this is "foo/bar/". // // Guaranteed to be present only if Exists(). FullName string // The backing object for the child, if any. If the child is not found or // exists only as an implicit directory, this is nil. Object *gcs.Object // Does the child exist as a directory implicitly defined by its own // descendents? Meaningful only if Object is nil and implicit directories are // enabled for the parent inode. ImplicitDir bool }
The result of looking up a child within a directory inode. See notes on DirInode.LookUpChild for more info.
func (*LookUpResult) Exists ¶
func (lr *LookUpResult) Exists() bool
Return true iff the result indicates that the child exists, explicitly or implicitly.
type SymlinkInode ¶
type SymlinkInode struct {
// contains filtered or unexported fields
}
func NewSymlinkInode ¶
func NewSymlinkInode( id fuseops.InodeID, o *gcs.Object, attrs fuseops.InodeAttributes) (s *SymlinkInode)
Create a symlink inode for the supplied object record.
REQUIRES: IsSymlink(o)
func (*SymlinkInode) Attributes ¶
func (s *SymlinkInode) Attributes( ctx context.Context) (attrs fuseops.InodeAttributes, err error)
func (*SymlinkInode) DecrementLookupCount ¶
func (s *SymlinkInode) DecrementLookupCount(n uint64) (destroy bool)
LOCKS_REQUIRED(s.mu)
func (*SymlinkInode) ID ¶
func (s *SymlinkInode) ID() fuseops.InodeID
func (*SymlinkInode) IncrementLookupCount ¶
func (s *SymlinkInode) IncrementLookupCount()
LOCKS_REQUIRED(s.mu)
func (*SymlinkInode) Lock ¶
func (s *SymlinkInode) Lock()
func (*SymlinkInode) Name ¶
func (s *SymlinkInode) Name() string
func (*SymlinkInode) SourceGeneration ¶
func (s *SymlinkInode) SourceGeneration() int64
Return the object generation number from which this inode was branched.
LOCKS_REQUIRED(s)
func (*SymlinkInode) Target ¶
func (s *SymlinkInode) Target() (target string)
Return the target of the symlink.
func (*SymlinkInode) Unlock ¶
func (s *SymlinkInode) Unlock()