func (t *DirTest) resetInode(implicitDirs bool) { if t.in != nil { t.in.Unlock() } t.in = inode.NewDirInode( dirInodeID, dirInodeName, fuseops.InodeAttributes{ Uid: uid, Gid: gid, Mode: dirMode, }, implicitDirs, typeCacheTTL, t.bucket, &t.clock, &t.clock) t.in.Lock() }
// Implementation detail of lookUpOrCreateInodeIfNotStale; do not use outside // of that function. // // LOCKS_REQUIRED(fs.mu) func (fs *fileSystem) mintInode(name string, o *gcs.Object) (in inode.Inode) { // Choose an ID. id := fs.nextInodeID fs.nextInodeID++ // Create the inode. switch { // Explicit directories case o != nil && inode.IsDirName(o.Name): in = inode.NewExplicitDirInode( id, o, fuseops.InodeAttributes{ Uid: fs.uid, Gid: fs.gid, Mode: fs.dirMode, }, fs.implicitDirs, fs.dirTypeCacheTTL, fs.bucket, fs.mtimeClock, fs.cacheClock) // Implicit directories case inode.IsDirName(name): in = inode.NewDirInode( id, name, fuseops.InodeAttributes{ Uid: fs.uid, Gid: fs.gid, Mode: fs.dirMode, }, fs.implicitDirs, fs.dirTypeCacheTTL, fs.bucket, fs.mtimeClock, fs.cacheClock) case inode.IsSymlink(o): in = inode.NewSymlinkInode( id, o, fuseops.InodeAttributes{ Uid: fs.uid, Gid: fs.gid, Mode: fs.fileMode | os.ModeSymlink, }) default: in = inode.NewFileInode( id, o, fuseops.InodeAttributes{ Uid: fs.uid, Gid: fs.gid, Mode: fs.fileMode, }, fs.bucket, fs.syncer, fs.tempDir, fs.mtimeClock) } // Place it in our map of IDs to inodes. fs.inodes[in.ID()] = in return }
// Create a fuse file system server according to the supplied configuration. func NewServer(cfg *ServerConfig) (server fuse.Server, err error) { // Check permissions bits. if cfg.FilePerms&^os.ModePerm != 0 { err = fmt.Errorf("Illegal file perms: %v", cfg.FilePerms) return } if cfg.DirPerms&^os.ModePerm != 0 { err = fmt.Errorf("Illegal dir perms: %v", cfg.FilePerms) return } // Create the object syncer. if cfg.TmpObjectPrefix == "" { err = errors.New("You must set TmpObjectPrefix.") return } syncer := gcsx.NewSyncer( cfg.AppendThreshold, cfg.TmpObjectPrefix, cfg.Bucket) // Set up the basic struct. fs := &fileSystem{ mtimeClock: timeutil.RealClock(), cacheClock: cfg.CacheClock, bucket: cfg.Bucket, syncer: syncer, tempDir: cfg.TempDir, implicitDirs: cfg.ImplicitDirectories, inodeAttributeCacheTTL: cfg.InodeAttributeCacheTTL, dirTypeCacheTTL: cfg.DirTypeCacheTTL, uid: cfg.Uid, gid: cfg.Gid, fileMode: cfg.FilePerms, dirMode: cfg.DirPerms | os.ModeDir, inodes: make(map[fuseops.InodeID]inode.Inode), nextInodeID: fuseops.RootInodeID + 1, generationBackedInodes: make(map[string]inode.GenerationBackedInode), implicitDirInodes: make(map[string]inode.DirInode), handles: make(map[fuseops.HandleID]interface{}), } // Set up the root inode. root := inode.NewDirInode( fuseops.RootInodeID, "", // name fuseops.InodeAttributes{ Uid: fs.uid, Gid: fs.gid, Mode: fs.dirMode, }, fs.implicitDirs, fs.dirTypeCacheTTL, cfg.Bucket, fs.mtimeClock, fs.cacheClock) root.Lock() root.IncrementLookupCount() fs.inodes[fuseops.RootInodeID] = root fs.implicitDirInodes[root.Name()] = root root.Unlock() // Set up invariant checking. fs.mu = syncutil.NewInvariantMutex(fs.checkInvariants) // Periodically garbage collect temporary objects. var gcCtx context.Context gcCtx, fs.stopGarbageCollecting = context.WithCancel(context.Background()) go garbageCollect(gcCtx, cfg.TmpObjectPrefix, fs.bucket) server = fuseutil.NewFileSystemServer(fs) return }