diff options
author | Jakob Unterwurzacher | 2021-05-08 15:39:49 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2021-05-08 15:39:49 +0200 |
commit | a267562d291b15c192837da6f74c991892570fd6 (patch) | |
tree | 58b359dbbfa9bd7af6ad9577076bf688240f4efc /internal | |
parent | 7466f12a922a226acc65d9d3e1e9ae2810957301 (diff) |
fusefrontend: reject broken RENAME_EXCHANGE and RENAME_WHITEOUT
Discovered by xfstests generic/013: or implementation for
RENAME_EXCHANGE and RENAME_WHITEOUT is incomplete. Reject the
flags so that the caller retries with regular rename.
Diffstat (limited to 'internal')
-rw-r--r-- | internal/fusefrontend/node.go | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/internal/fusefrontend/node.go b/internal/fusefrontend/node.go index 5a7edc8..72dd69d 100644 --- a/internal/fusefrontend/node.go +++ b/internal/fusefrontend/node.go @@ -358,11 +358,36 @@ func (n *Node) Symlink(ctx context.Context, target, name string, out *fuse.Entry return inode, 0 } +// xfstests generic/013 now also exercises RENAME_EXCHANGE and RENAME_WHITEOUT, +// uncovering lots of problems with longnames +// +// Reject those flags with syscall.EINVAL. +// If we can handle the flags, this function returns 0. +func rejectRenameFlags(flags uint32) syscall.Errno { + const RENAME_NOREPLACE = 1 + switch flags { + case 0: + // Normal rename, we can handle that + return 0 + case RENAME_NOREPLACE: + // We also can handle RENAME_NOREPLACE + return 0 + default: + // We cannot handle RENAME_EXCHANGE and RENAME_WHITEOUT yet - + // needs extra code for .name files. + return syscall.EINVAL + } +} + // Rename - FUSE call. // This function is called on the PARENT DIRECTORY of `name`. // // Symlink-safe through Renameat(). func (n *Node) Rename(ctx context.Context, name string, newParent fs.InodeEmbedder, newName string, flags uint32) (errno syscall.Errno) { + if errno = rejectRenameFlags(flags); errno != 0 { + return errno + } + dirfd, cName, errno := n.prepareAtSyscall(name) if errno != 0 { return |