diff options
-rw-r--r-- | internal/fusefrontend/xattr.go | 8 | ||||
-rw-r--r-- | tests/xattr/xattr_integration_test.go | 10 |
2 files changed, 18 insertions, 0 deletions
diff --git a/internal/fusefrontend/xattr.go b/internal/fusefrontend/xattr.go index ad1c330..2248bad 100644 --- a/internal/fusefrontend/xattr.go +++ b/internal/fusefrontend/xattr.go @@ -71,6 +71,10 @@ func (fs *FS) SetXAttr(relPath string, attr string, data []byte, flags int, cont // O_NONBLOCK to not block on FIFOs. fd, err := fs.openBackingFile(relPath, syscall.O_WRONLY|syscall.O_NONBLOCK) + // Directories cannot be opened read-write. Retry. + if err == syscall.EISDIR { + fd, err = fs.openBackingFile(relPath, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NONBLOCK) + } if err != nil { return fuse.ToStatus(err) } @@ -100,6 +104,10 @@ func (fs *FS) RemoveXAttr(relPath string, attr string, context *fuse.Context) fu // O_NONBLOCK to not block on FIFOs. fd, err := fs.openBackingFile(relPath, syscall.O_WRONLY|syscall.O_NONBLOCK) + // Directories cannot be opened read-write. Retry. + if err == syscall.EISDIR { + fd, err = fs.openBackingFile(relPath, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NONBLOCK) + } if err != nil { return fuse.ToStatus(err) } diff --git a/tests/xattr/xattr_integration_test.go b/tests/xattr/xattr_integration_test.go index b2870e8..f182fd9 100644 --- a/tests/xattr/xattr_integration_test.go +++ b/tests/xattr/xattr_integration_test.go @@ -124,6 +124,16 @@ func TestSetGetRmFifo(t *testing.T) { setGetRmList(fn) } +// Test xattr set, get, rm on a directory. This should not fail with EISDIR. +func TestSetGetRmDir(t *testing.T) { + fn := test_helpers.DefaultPlainDir + "/TestSetGetRmDir" + err := syscall.Mkdir(fn, 0700) + if err != nil { + t.Fatalf("creating fifo failed: %v", err) + } + setGetRmList(fn) +} + func TestXattrSetEmpty(t *testing.T) { attr := "user.foo" fn := test_helpers.DefaultPlainDir + "/TestXattrSetEmpty1" |