fusefrontend: Use Linkat syscall to implement Link
This commit is contained in:
parent
a24342f656
commit
a85dbcab38
@ -540,35 +540,32 @@ func (fs *FS) Link(oldPath string, newPath string, context *fuse.Context) (code
|
||||
if fs.isFiltered(newPath) {
|
||||
return fuse.EPERM
|
||||
}
|
||||
cOldPath, err := fs.getBackingPath(oldPath)
|
||||
oldDirFd, cOldName, err := fs.openBackingPath(oldPath)
|
||||
if err != nil {
|
||||
return fuse.ToStatus(err)
|
||||
}
|
||||
cNewPath, err := fs.getBackingPath(newPath)
|
||||
defer oldDirFd.Close()
|
||||
newDirFd, cNewName, err := fs.openBackingPath(newPath)
|
||||
if err != nil {
|
||||
return fuse.ToStatus(err)
|
||||
}
|
||||
// Handle long file name
|
||||
cNewName := filepath.Base(cNewPath)
|
||||
defer newDirFd.Close()
|
||||
// Handle long file name (except in PlaintextNames mode)
|
||||
if !fs.args.PlaintextNames && nametransform.IsLongContent(cNewName) {
|
||||
dirfd, err := os.Open(filepath.Dir(cNewPath))
|
||||
err = fs.nameTransform.WriteLongName(newDirFd, cNewName, newPath)
|
||||
if err != nil {
|
||||
return fuse.ToStatus(err)
|
||||
}
|
||||
defer dirfd.Close()
|
||||
err = fs.nameTransform.WriteLongName(dirfd, cNewName, newPath)
|
||||
// Create "gocryptfs.longfile." link
|
||||
err = syscallcompat.Linkat(int(oldDirFd.Fd()), cOldName, int(newDirFd.Fd()), cNewName, 0)
|
||||
if err != nil {
|
||||
return fuse.ToStatus(err)
|
||||
nametransform.DeleteLongName(newDirFd, cNewName)
|
||||
}
|
||||
// TODO Use syscall.Linkat once it is available in Go (it is not in Go
|
||||
// 1.6).
|
||||
err = syscall.Link(cOldPath, cNewPath)
|
||||
if err != nil {
|
||||
nametransform.DeleteLongName(dirfd, cNewName)
|
||||
} else {
|
||||
// Create regular link
|
||||
err = syscallcompat.Linkat(int(oldDirFd.Fd()), cOldName, int(newDirFd.Fd()), cNewName, 0)
|
||||
}
|
||||
return fuse.ToStatus(err)
|
||||
}
|
||||
return fuse.ToStatus(os.Link(cOldPath, cNewPath))
|
||||
}
|
||||
|
||||
// Access implements pathfs.Filesystem.
|
||||
|
@ -38,3 +38,8 @@ func Faccessat(dirfd int, path string, mode uint32) error {
|
||||
}
|
||||
return unix.Faccessat(dirfd, path, mode, 0)
|
||||
}
|
||||
|
||||
// Linkat exists both in Linux and in MacOS 10.10+.
|
||||
func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
|
||||
return unix.Linkat(olddirfd, oldpath, newdirfd, newpath, flags)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user