aboutsummaryrefslogtreecommitdiff
path: root/internal/fusefrontend
diff options
context:
space:
mode:
authorJakob Unterwurzacher2021-05-08 15:39:49 +0200
committerJakob Unterwurzacher2021-05-08 15:39:49 +0200
commita267562d291b15c192837da6f74c991892570fd6 (patch)
tree58b359dbbfa9bd7af6ad9577076bf688240f4efc /internal/fusefrontend
parent7466f12a922a226acc65d9d3e1e9ae2810957301 (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/fusefrontend')
-rw-r--r--internal/fusefrontend/node.go25
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