func (f *rpcFsFile) GetAttr(a *fuse.Attr) fuse.Status { *a = f.attr if a.Size > 0 { a.Ino = hashIno(f.hash) } return fuse.OK }
func (gitfs *GitFs) getGitAttrByPath(repoPath string, path string) (*fuse.Attr, fuse.Status) { repo, _, _, tree, err := gitfs.getMasterTreeFromRepo(repoPath) if err != nil { return nil, fuse.EPERM } repoInfo, err := os.Stat(repoPath) if err != nil { gitfs.logger.Debugf("Failed to Stat %s due to %s", repoPath, err) return nil, fuse.ToStatus(err) } if path == "" { attr := fuse.ToAttr(repoInfo) attr.Mode &= ^uint32(0222) attr.Nlink = 2 + gitfs.treeEntryCount(tree, repoPath) return attr, fuse.OK } entry, err := tree.EntryByPath(path) if err != nil { gitfs.logger.Debugf("Cannot find path %s from tree %s of Git Repository %s due to %s", path, tree.Id().String(), repoPath, err) return nil, fuse.ENOENT } gitfs.logger.Debugf("Found path %s from tree %s of Git Repository %s", path, tree.Id().String(), repoPath) var attr fuse.Attr attr.Mode = toFileMode(entry.Filemode) if stat, ok := repoInfo.Sys().(*syscall.Stat_t); ok { attr.Uid = stat.Uid attr.Gid = stat.Gid attr.Blksize = uint32(stat.Blksize) attr.Rdev = uint32(stat.Rdev) } attr.Ino = crc64.Checksum(entry.Id[:], crc64.MakeTable(crc64.ECMA)) now := time.Now() attr.SetTimes(&now, &now, &now) switch entry.Type { case libgit2.ObjectTree: tree, err := repo.LookupTree(entry.Id) if err != nil { gitfs.logger.Errorf("Failed to find tree %s from Git Repository %s", entry.Id, repoPath) return nil, fuse.EPERM } defer tree.Free() gitfs.logger.Debugf("Found tree %s of Git Repository %s", tree.Id().String(), repoPath) attr.Size = 4096 attr.Nlink = 2 + gitfs.treeEntryCount(tree, repoPath) case libgit2.ObjectBlob: blob, err := repo.LookupBlob(entry.Id) if err != nil { gitfs.logger.Errorf("Failed to find blob %s from Git Repository %s", entry.Id, repoPath) return nil, fuse.EPERM } defer blob.Free() gitfs.logger.Debugf("Found blob %s of Git Repository %s", blob.Id().String(), repoPath) attr.Nlink = 1 attr.Size = uint64(blob.Size()) default: gitfs.logger.Debugf("GetAttr: Unsupported object type %s of %s from Git Repository %s", entry.Type.String(), entry.Id, repoPath) return nil, fuse.ENOENT } attr.Blocks = (attr.Size + 511) / 512 return &attr, fuse.OK }