func NewFileSystem()

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
}