Пример #1
0
// UGH - copy & paste.
// for tests:
func StatForTest(t *testing.T, n string) *fuse.Attr {
	t.Logf("test stat %q", n)
	f, _ := os.Lstat(n)
	if f == nil {
		return nil
	}
	return fuse.ToAttr(f)
}
Пример #2
0
func getattr(filename string) (*fuse.Attr, fuse.Status) {
	stat, err := os.Stat(filename)
	if err != nil {
		// TODO report error
		return nil, fuse.EIO
	}
	return fuse.ToAttr(stat), fuse.OK
}
Пример #3
0
func GetattrForTest(t *testing.T, n string) *attr.FileAttr {
	t.Logf("test getattr %q", n)
	fi, _ := os.Lstat(n)

	var fa *fuse.Attr
	if fi != nil {
		fa = fuse.ToAttr(fi)
	}
	a := attr.FileAttr{
		Attr: fa,
	}
	if !a.Deletion() {
		a.ReadFromFs(n, crypto.MD5)
	}
	return &a
}
Пример #4
0
func (gitfs *GitFs) GetAttr(name string, _ *fuse.Context) (attr *fuse.Attr, status fuse.Status) {
	defer gitfs.showPanicError()
	user, repo, path := splitPath(name)
	gitfs.logger.Debugf("GetAttr: user = %s, repo = %s, path = %s", user, repo, path)
	if /* user == "" || */ repo == "" {
		dirInfo, err := os.Stat(gitfs.GitRepoDir + "/" + user)
		if err != nil {
			return nil, fuse.ToStatus(err)
		}
		attr = fuse.ToAttr(dirInfo)
		attr.Mode &= ^uint32(0222)
		return attr, fuse.OK
	}

	repoPath := gitfs.GitRepoDir + "/" + user + "/" + repo + ".git"
	attr, status = gitfs.getGitAttrByPath(repoPath, path)
	return
}
Пример #5
0
func (me *FileAttr) ReadFromFs(p string, hashFunc crypto.Hash) {
	var err error
	switch {
	case me.IsRegular():
		if c, e := ioutil.ReadFile(p); e == nil {
			h := hashFunc.New()
			h.Write(c)
			me.Hash = string(h.Sum(nil))
		} else {
			err = e
		}

	case me.IsDir():
		d, e := ioutil.ReadDir(p)
		if e == nil {
			me.NameModeMap = make(map[string]FileMode, len(d))
			for _, v := range d {
				a := fuse.ToAttr(v)
				if a != nil {
					// attr == nil may happen for fuse mounts that have died.
					me.NameModeMap[v.Name()] = FileMode(a.Mode &^ 07777)
				}
			}
		} else {
			err = e
		}

	case me.IsSymlink():
		if l, e := os.Readlink(p); e == nil {
			me.Link = l
		} else {
			err = e
		}
	}

	if err != nil {
		log.Println("Error reading %q (%s): %v", me.Attr.Mode, p, err)
		me.Attr = nil
	}
}
Пример #6
0
func TestMemUnionFsUpdate(t *testing.T) {
	wd, ufs, clean := setupMemUfs(t)
	defer clean()

	err := ioutil.WriteFile(wd+"/ro/file1", []byte("blablabla"), 0644)
	CheckSuccess(err)

	_, err = os.Lstat(wd + "/mnt/file1")
	CheckSuccess(err)
	if fi, _ := os.Lstat(wd + "/mnt/file2"); fi != nil {
		t.Fatal("file2 should not exist", fi)
	}
	if fi, _ := os.Lstat(wd + "/mnt/symlink"); fi != nil {
		t.Fatal("symlink should not exist", fi)
	}

	err = os.Remove(wd + "/ro/file1")
	CheckSuccess(err)
	err = ioutil.WriteFile(wd+"/ro/file2", []byte("foobar"), 0644)
	CheckSuccess(err)
	err = os.Symlink("target", wd+"/ro/symlink")
	CheckSuccess(err)

	// Still have cached attributes.
	fi, err := os.Lstat(wd + "/mnt/file1")
	CheckSuccess(err)
	if fi, _ := os.Lstat(wd + "/mnt/file2"); fi != nil {
		t.Fatal("file2 should not exist")
	}
	if fi, _ := os.Lstat(wd + "/mnt/symlink"); fi != nil {
		t.Fatal("symlink should not exist", fi)
	}

	roF2fi, err := os.Lstat(wd + "/ro/file2")
	CheckSuccess(err)
	roF2 := fuse.ToAttr(roF2fi)

	roSymlinkFi, err := os.Lstat(wd + "/ro/symlink")
	CheckSuccess(err)
	roSymlink := fuse.ToAttr(roSymlinkFi)

	updates := map[string]*Result{
		"file1": {
			nil, "", "", "",
		},
		"file2": {
			roF2, "", "", "",
		},
		"symlink": {
			roSymlink, "", "", "target",
		},
	}

	ufs.Update(updates)

	// Cached attributes flushed.
	if fi, _ := os.Lstat(wd + "/mnt/file1"); fi != nil {
		t.Fatal("file1 should have disappeared", fi)
	}

	fi, err = os.Lstat(wd + "/mnt/file2")
	CheckSuccess(err)
	if roF2.ModTime().UnixNano() != fi.ModTime().UnixNano() {
		t.Fatalf("file2 attribute mismatch: got %v want %v", fi, roF2)
	}

	val, err := os.Readlink(wd + "/mnt/symlink")
	CheckSuccess(err)
	if val != "target" {
		t.Error("symlink value got %q want %v", val, "target")
	}
}
Пример #7
0
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
}