diff options
Diffstat (limited to 'internal/fusefrontend')
| -rw-r--r-- | internal/fusefrontend/fs.go | 29 | 
1 files changed, 13 insertions, 16 deletions
| 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. | 
