in internal/fs/fs.go [135:224]
func NewFileSystem(ctx context.Context, serverCfg *ServerConfig) (fuseutil.FileSystem, error) {
// Check permissions bits.
if serverCfg.FilePerms&^os.ModePerm != 0 {
return nil, fmt.Errorf("illegal file perms: %v", serverCfg.FilePerms)
}
if serverCfg.DirPerms&^os.ModePerm != 0 {
return nil, fmt.Errorf("illegal dir perms: %v", serverCfg.FilePerms)
}
mtimeClock := timeutil.RealClock()
contentCache := contentcache.New(serverCfg.TempDir, mtimeClock)
if serverCfg.LocalFileCache {
err := contentCache.RecoverCache()
if err != nil {
fmt.Printf("Encountered error retrieving files from cache directory, disabling local file cache: %v", err)
serverCfg.LocalFileCache = false
}
}
// Create file cache handler if cache is enabled by user. Cache is considered
// enabled only if cache-dir is not empty and file-cache:max-size-mb is non 0.
var fileCacheHandler *file.CacheHandler
if cfg.IsFileCacheEnabled(serverCfg.NewConfig) {
var err error
fileCacheHandler, err = createFileCacheHandler(serverCfg)
if err != nil {
return nil, err
}
}
// Set up the basic struct.
fs := &fileSystem{
mtimeClock: mtimeClock,
cacheClock: serverCfg.CacheClock,
bucketManager: serverCfg.BucketManager,
localFileCache: serverCfg.LocalFileCache,
contentCache: contentCache,
implicitDirs: serverCfg.ImplicitDirectories,
enableNonexistentTypeCache: serverCfg.EnableNonexistentTypeCache,
inodeAttributeCacheTTL: serverCfg.InodeAttributeCacheTTL,
dirTypeCacheTTL: serverCfg.DirTypeCacheTTL,
kernelListCacheTTL: cfg.ListCacheTTLSecsToDuration(serverCfg.NewConfig.FileSystem.KernelListCacheTtlSecs),
renameDirLimit: serverCfg.RenameDirLimit,
sequentialReadSizeMb: serverCfg.SequentialReadSizeMb,
uid: serverCfg.Uid,
gid: serverCfg.Gid,
fileMode: serverCfg.FilePerms,
dirMode: serverCfg.DirPerms | os.ModeDir,
inodes: make(map[fuseops.InodeID]inode.Inode),
nextInodeID: fuseops.RootInodeID + 1,
generationBackedInodes: make(map[inode.Name]inode.GenerationBackedInode),
implicitDirInodes: make(map[inode.Name]inode.DirInode),
folderInodes: make(map[inode.Name]inode.DirInode),
localFileInodes: make(map[inode.Name]inode.Inode),
handles: make(map[fuseops.HandleID]interface{}),
newConfig: serverCfg.NewConfig,
fileCacheHandler: fileCacheHandler,
cacheFileForRangeRead: serverCfg.NewConfig.FileCache.CacheFileForRangeRead,
metricHandle: serverCfg.MetricHandle,
enableAtomicRenameObject: serverCfg.NewConfig.EnableAtomicRenameObject,
globalMaxWriteBlocksSem: semaphore.NewWeighted(serverCfg.NewConfig.Write.GlobalMaxBlocks),
}
// Set up root bucket
var root inode.DirInode
if serverCfg.BucketName == "" || serverCfg.BucketName == "_" {
logger.Info("Set up root directory for all accessible buckets")
root = makeRootForAllBuckets(fs)
} else {
logger.Info("Set up root directory for bucket " + serverCfg.BucketName)
syncerBucket, err := fs.bucketManager.SetUpBucket(ctx, serverCfg.BucketName, false, fs.metricHandle)
if err != nil {
return nil, fmt.Errorf("SetUpBucket: %w", err)
}
root = makeRootForBucket(ctx, fs, syncerBucket)
}
root.Lock()
root.IncrementLookupCount()
fs.inodes[fuseops.RootInodeID] = root
fs.implicitDirInodes[root.Name()] = root
fs.folderInodes[root.Name()] = root
root.Unlock()
// Set up invariant checking.
fs.mu = locker.New("FS", fs.checkInvariants)
return fs, nil
}