fusefrontend: support RENAME_WHITEOUT, RENAME_EXCHANGE
Both new internal test and xfstests generic/013 are happy. https://github.com/rfjakob/gocryptfs/issues/641
This commit is contained in:
parent
3ca2b1983d
commit
b7cac4ffd0
@ -391,23 +391,17 @@ func (n *Node) Symlink(ctx context.Context, target, name string, out *fuse.Entry
|
|||||||
return inode, 0
|
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.
|
// If we can handle the flags, this function returns 0.
|
||||||
func rejectRenameFlags(flags uint32) syscall.Errno {
|
func rejectRenameFlags(flags uint32) syscall.Errno {
|
||||||
// Normal rename, we can handle that
|
switch flags {
|
||||||
if flags == 0 {
|
case 0, syscallcompat.RENAME_NOREPLACE, syscallcompat.RENAME_EXCHANGE, syscallcompat.RENAME_WHITEOUT:
|
||||||
return 0
|
return 0
|
||||||
}
|
case syscallcompat.RENAME_NOREPLACE | syscallcompat.RENAME_WHITEOUT:
|
||||||
// We also can handle RENAME_NOREPLACE
|
|
||||||
if flags == syscallcompat.RENAME_NOREPLACE {
|
|
||||||
return 0
|
return 0
|
||||||
}
|
default:
|
||||||
// We cannot handle RENAME_EXCHANGE and RENAME_WHITEOUT yet.
|
tlog.Warn.Printf("rejectRenameFlags: unknown flag combination 0x%x", flags)
|
||||||
// Needs extra code for .name files.
|
|
||||||
return syscall.EINVAL
|
return syscall.EINVAL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename - FUSE call.
|
// Rename - FUSE call.
|
||||||
@ -472,6 +466,11 @@ func (n *Node) Rename(ctx context.Context, name string, newParent fs.InodeEmbedd
|
|||||||
}
|
}
|
||||||
return fs.ToErrno(err)
|
return fs.ToErrno(err)
|
||||||
}
|
}
|
||||||
|
if flags&syscallcompat.RENAME_EXCHANGE != 0 || flags&syscallcompat.RENAME_WHITEOUT != 0 {
|
||||||
|
// These flags mean that there is now a new file at cName and we
|
||||||
|
// should NOT delete its longname file.
|
||||||
|
return 0
|
||||||
|
}
|
||||||
if nametransform.IsLongContent(cName) {
|
if nametransform.IsLongContent(cName) {
|
||||||
nametransform.DeleteLongNameAt(dirfd, cName)
|
nametransform.DeleteLongNameAt(dirfd, cName)
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,10 @@ const (
|
|||||||
// O_PATH is only defined on Linux
|
// O_PATH is only defined on Linux
|
||||||
O_PATH = 0
|
O_PATH = 0
|
||||||
|
|
||||||
// RENAME_NOREPLACE is only defined on Linux
|
// Only defined on Linux
|
||||||
RENAME_NOREPLACE = 0
|
RENAME_NOREPLACE = 0
|
||||||
|
RENAME_WHITEOUT = 0
|
||||||
|
RENAME_EXCHANGE = 0
|
||||||
|
|
||||||
// KAUTH_UID_NONE and KAUTH_GID_NONE are special values to
|
// KAUTH_UID_NONE and KAUTH_GID_NONE are special values to
|
||||||
// revert permissions to the process credentials.
|
// revert permissions to the process credentials.
|
||||||
|
@ -28,8 +28,10 @@ const (
|
|||||||
// O_PATH is only defined on Linux
|
// O_PATH is only defined on Linux
|
||||||
O_PATH = unix.O_PATH
|
O_PATH = unix.O_PATH
|
||||||
|
|
||||||
// RENAME_NOREPLACE is only defined on Linux
|
// Only defined on Linux
|
||||||
RENAME_NOREPLACE = unix.RENAME_NOREPLACE
|
RENAME_NOREPLACE = unix.RENAME_NOREPLACE
|
||||||
|
RENAME_WHITEOUT = unix.RENAME_WHITEOUT
|
||||||
|
RENAME_EXCHANGE = unix.RENAME_EXCHANGE
|
||||||
)
|
)
|
||||||
|
|
||||||
var preallocWarn sync.Once
|
var preallocWarn sync.Once
|
||||||
|
Loading…
Reference in New Issue
Block a user