xattr: return EOPNOTSUPP for unsupported attributes

mv is unhappy when we return EPERM when it tries to set
system.posix_acl_access:

   mv: preserving permissions for ‘b/x’: Operation not permitted

Now we return EOPNOTSUPP like tmpfs does and mv seems happy.
This commit is contained in:
Jakob Unterwurzacher 2018-05-15 23:00:47 +02:00
parent f7a6f4d468
commit 7b00681807
2 changed files with 43 additions and 2 deletions

View File

@ -48,13 +48,15 @@ func (fs *FS) GetXAttr(path string, attr string, context *fuse.Context) ([]byte,
return data, fuse.OK return data, fuse.OK
} }
const _EOPNOTSUPP = fuse.Status(syscall.EOPNOTSUPP)
// SetXAttr implements pathfs.Filesystem. // SetXAttr implements pathfs.Filesystem.
func (fs *FS) SetXAttr(path string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status { func (fs *FS) SetXAttr(path string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status {
if fs.isFiltered(path) { if fs.isFiltered(path) {
return fuse.EPERM return fuse.EPERM
} }
if disallowedXAttrName(attr) { if disallowedXAttrName(attr) {
return fuse.EPERM return _EOPNOTSUPP
} }
flags = filterXattrSetFlags(flags) flags = filterXattrSetFlags(flags)
@ -74,7 +76,7 @@ func (fs *FS) RemoveXAttr(path string, attr string, context *fuse.Context) fuse.
return fuse.EPERM return fuse.EPERM
} }
if disallowedXAttrName(attr) { if disallowedXAttrName(attr) {
return fuse.EPERM return _EOPNOTSUPP
} }
cPath, err := fs.getBackingPath(path) cPath, err := fs.getBackingPath(path)
if err != nil { if err != nil {

View File

@ -193,3 +193,42 @@ func TestWrite0200File(t *testing.T) {
t.Fatal("wrong restored permissions") t.Fatal("wrong restored permissions")
} }
} }
// When xattr support was introduced, mv threw warnings like these:
// mv: preserving permissions for b/x: Operation not permitted
// because we returned EPERM when it tried to set system.posix_acl_access.
// Now we return EOPNOTSUPP and mv is happy.
func TestMvWarnings(t *testing.T) {
fn := test_helpers.TmpDir + "/TestMvWarnings"
err := ioutil.WriteFile(fn, nil, 0600)
if err != nil {
t.Fatalf("creating file failed: %v", err)
}
cmd := exec.Command("mv", fn, test_helpers.DefaultPlainDir)
out, err := cmd.CombinedOutput()
if err != nil {
t.Log(string(out))
t.Fatal(err)
}
if len(out) != 0 {
t.Fatalf("Got warnings from mv:\n%s", string(out))
}
}
// See TestCpWarnings.
func TestCpWarnings(t *testing.T) {
fn := test_helpers.TmpDir + "/TestCpWarnings"
err := ioutil.WriteFile(fn, []byte("foo"), 0600)
if err != nil {
t.Fatalf("creating file failed: %v", err)
}
cmd := exec.Command("cp", "-a", fn, test_helpers.DefaultPlainDir)
out, err := cmd.CombinedOutput()
if err != nil {
t.Log(string(out))
t.Fatal(err)
}
if len(out) != 0 {
t.Fatalf("Got warnings from cp -a:\n%s", string(out))
}
}