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) {
|
if fs.isFiltered(newPath) {
|
||||||
return fuse.EPERM
|
return fuse.EPERM
|
||||||
}
|
}
|
||||||
cOldPath, err := fs.getBackingPath(oldPath)
|
oldDirFd, cOldName, err := fs.openBackingPath(oldPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
cNewPath, err := fs.getBackingPath(newPath)
|
defer oldDirFd.Close()
|
||||||
|
newDirFd, cNewName, err := fs.openBackingPath(newPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
// Handle long file name
|
defer newDirFd.Close()
|
||||||
cNewName := filepath.Base(cNewPath)
|
// Handle long file name (except in PlaintextNames mode)
|
||||||
if !fs.args.PlaintextNames && nametransform.IsLongContent(cNewName) {
|
if !fs.args.PlaintextNames && nametransform.IsLongContent(cNewName) {
|
||||||
dirfd, err := os.Open(filepath.Dir(cNewPath))
|
err = fs.nameTransform.WriteLongName(newDirFd, cNewName, newPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
defer dirfd.Close()
|
// Create "gocryptfs.longfile." link
|
||||||
err = fs.nameTransform.WriteLongName(dirfd, cNewName, newPath)
|
err = syscallcompat.Linkat(int(oldDirFd.Fd()), cOldName, int(newDirFd.Fd()), cNewName, 0)
|
||||||
if err != nil {
|
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
|
} else {
|
||||||
// 1.6).
|
// Create regular link
|
||||||
err = syscall.Link(cOldPath, cNewPath)
|
err = syscallcompat.Linkat(int(oldDirFd.Fd()), cOldName, int(newDirFd.Fd()), cNewName, 0)
|
||||||
if err != nil {
|
|
||||||
nametransform.DeleteLongName(dirfd, cNewName)
|
|
||||||
}
|
}
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
|
||||||
return fuse.ToStatus(os.Link(cOldPath, cNewPath))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access implements pathfs.Filesystem.
|
// Access implements pathfs.Filesystem.
|
||||||
|
@ -38,3 +38,8 @@ func Faccessat(dirfd int, path string, mode uint32) error {
|
|||||||
}
|
}
|
||||||
return unix.Faccessat(dirfd, path, mode, 0)
|
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…
x
Reference in New Issue
Block a user