From a85dbcab38bcad0ef713187a637a7023d016829f Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 12 Dec 2017 14:42:49 +0100 Subject: fusefrontend: Use Linkat syscall to implement Link --- internal/fusefrontend/fs.go | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'internal/fusefrontend') diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index 8c9e5e4..cabfdd2 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -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)) - if err != nil { - return fuse.ToStatus(err) - } - defer dirfd.Close() - err = fs.nameTransform.WriteLongName(dirfd, cNewName, newPath) + err = fs.nameTransform.WriteLongName(newDirFd, cNewName, newPath) if err != nil { return fuse.ToStatus(err) } - // TODO Use syscall.Linkat once it is available in Go (it is not in Go - // 1.6). - err = syscall.Link(cOldPath, cNewPath) + // Create "gocryptfs.longfile." link + err = syscallcompat.Linkat(int(oldDirFd.Fd()), cOldName, int(newDirFd.Fd()), cNewName, 0) if err != nil { - nametransform.DeleteLongName(dirfd, cNewName) + nametransform.DeleteLongName(newDirFd, cNewName) } - return fuse.ToStatus(err) + } else { + // Create regular link + err = syscallcompat.Linkat(int(oldDirFd.Fd()), cOldName, int(newDirFd.Fd()), cNewName, 0) } - return fuse.ToStatus(os.Link(cOldPath, cNewPath)) + return fuse.ToStatus(err) } // Access implements pathfs.Filesystem. -- cgit v1.2.3