Пример #1
0
func (n *Node) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
	defer trace(NewGetxattrOp(req, n.path))
	size, err := syscallx.Getxattr(n.path, req.Name, []byte{})
	if err != nil || size <= 0 {
		return fuse.ErrNoXattr
	}
	buffer := make([]byte, size)
	size, err = syscallx.Getxattr(n.path, req.Name, buffer)
	if err != nil {
		return osErrorToFuseError(err)
	}
	resp.Xattr = buffer
	return nil
}
Пример #2
0
func Get(path string, name string) (bytes []byte) {
	buf := make([]byte, GetBufsize)
	read, err := syscallx.Getxattr(path, name, buf)
	if err == nil && read > 0 {
		bytes = buf[:read]
	}
	return
}
Пример #3
0
func (n *Node) Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error {
	defer trace(NewRemovexattrOp(req, n.path))
	// TODO: this needs to be improved, since the behavior of Removexattr depends
	// on the previous existance of the attribute. The return code of the operation
	// is governed by the flags. See bazil.org/fuse/syscallx.Removexattr comments.
	_, err := syscallx.Getxattr(n.path, req.Name, []byte{})
	if err == nil {
		// TODO: There is already an attribute with that name. Should return
		// the expected error code according to the request's flags
		err = syscallx.Removexattr(n.path, req.Name)
		return osErrorToFuseError(err)
	}
	return nil
}
Пример #4
0
func (file *File) Getxattr(req *fuse.GetxattrRequest, res *fuse.GetxattrResponse, intr fs.Intr) fuse.Error {
	// return fuse.EPERM
	// fmt.Printf("Get attr: %s\n", req.Name)

	buf := make([]byte, 8192)
	size, err := syscallx.Getxattr(file.Path, req.Name, buf)

	if err != nil {
		// fmt.Printf("Get xattr error: %s - %s: \n", file.Path, req.Name, err)
		// return err
		// On osx, we need to return NOATTR, but this isn't built into go or bazil.org/fuse, so we need to do this:
		return fuse.Errno(93)
	}

	res.Xattr = buf[:size]

	return nil
}
Пример #5
0
func TestGetxattrSize(t *testing.T) {
	t.Parallel()
	f := &getxattrSize{}
	mnt, err := fstestutil.MountedT(t, childMapFS{"child": f})
	if err != nil {
		t.Fatal(err)
	}
	defer mnt.Close()

	n, err := syscallx.Getxattr(mnt.Dir+"/child", "whatever", nil)
	if err != nil {
		t.Errorf("Getxattr unexpected error: %v", err)
		return
	}
	if g, e := n, len("hello, world"); g != e {
		t.Errorf("Getxattr incorrect size: %d != %d", g, e)
	}
}
Пример #6
0
func TestGetxattrTooSmall(t *testing.T) {
	t.Parallel()
	f := &getxattrTooSmall{}
	mnt, err := fstestutil.MountedT(t, childMapFS{"child": f})
	if err != nil {
		t.Fatal(err)
	}
	defer mnt.Close()

	buf := make([]byte, 3)
	_, err = syscallx.Getxattr(mnt.Dir+"/child", "whatever", buf)
	if err == nil {
		t.Error("Getxattr = nil; want some error")
	}
	if err != syscall.ERANGE {
		t.Errorf("unexpected error: %v", err)
		return
	}
}
Пример #7
0
func TestGetxattr(t *testing.T) {
	t.Parallel()
	f := &getxattr{}
	mnt, err := fstestutil.MountedT(t, childMapFS{"child": f})
	if err != nil {
		t.Fatal(err)
	}
	defer mnt.Close()

	buf := make([]byte, 8192)
	n, err := syscallx.Getxattr(mnt.Dir+"/child", "not-there", buf)
	if err != nil {
		t.Errorf("unexpected error: %v", err)
		return
	}
	buf = buf[:n]
	if g, e := string(buf), "hello, world"; g != e {
		t.Errorf("wrong getxattr content: %#v != %#v", g, e)
	}
	seen := f.RecordedGetxattr()
	if g, e := seen.Name, "not-there"; g != e {
		t.Errorf("wrong getxattr name: %#v != %#v", g, e)
	}
}
Пример #8
0
func TestXattr(t *testing.T) {
	condSkip(t)
	inEmptyMutDir(t, func(env *mountEnv, rootDir string) {
		name1 := filepath.Join(rootDir, "1")
		attr1 := "attr1"
		attr2 := "attr2"

		contents := []byte("Some file contents")

		if err := ioutil.WriteFile(name1, contents, 0644); err != nil {
			t.Fatal(err)
		}

		buf := make([]byte, 8192)
		// list empty
		n, err := syscallx.Listxattr(name1, buf)
		if err != nil {
			t.Errorf("Error in initial listxattr: %v", err)
		}
		if n != 0 {
			t.Errorf("Expected zero-length xattr list, got %q", buf[:n])
		}

		// get missing
		n, err = syscallx.Getxattr(name1, attr1, buf)
		if err == nil {
			t.Errorf("Expected error getting non-existent xattr, got %q", buf[:n])
		}

		// Set (two different attributes)
		err = syscallx.Setxattr(name1, attr1, []byte("hello1"), 0)
		if err != nil {
			t.Fatalf("Error setting xattr: %v", err)
		}
		err = syscallx.Setxattr(name1, attr2, []byte("hello2"), 0)
		if err != nil {
			t.Fatalf("Error setting xattr: %v", err)
		}
		// Alternate value for first attribute
		err = syscallx.Setxattr(name1, attr1, []byte("hello1a"), 0)
		if err != nil {
			t.Fatalf("Error setting xattr: %v", err)
		}

		// list attrs
		n, err = syscallx.Listxattr(name1, buf)
		if err != nil {
			t.Errorf("Error in initial listxattr: %v", err)
		}
		m := parseXattrList(buf[:n])
		if !(len(m) == 2 && m[attr1] && m[attr2]) {
			t.Errorf("Missing an attribute: %q", buf[:n])
		}

		// Remove attr
		err = syscallx.Removexattr(name1, attr2)
		if err != nil {
			t.Errorf("Failed to remove attr: %v", err)
		}

		// List attrs
		n, err = syscallx.Listxattr(name1, buf)
		if err != nil {
			t.Errorf("Error in initial listxattr: %v", err)
		}
		m = parseXattrList(buf[:n])
		if !(len(m) == 1 && m[attr1]) {
			t.Errorf("Missing an attribute: %q", buf[:n])
		}

		// Get remaining attr
		n, err = syscallx.Getxattr(name1, attr1, buf)
		if err != nil {
			t.Errorf("Error getting attr1: %v", err)
		}
		if string(buf[:n]) != "hello1a" {
			t.Logf("Expected hello1a, got %q", buf[:n])
		}
	})
}