syscallcompat: Introduce unlinkat syscall with flags argument
This commit is contained in:
parent
5d44a31b41
commit
0f44c617d0
@ -388,7 +388,7 @@ func (fs *FS) Unlink(path string, context *fuse.Context) (code fuse.Status) {
|
|||||||
}
|
}
|
||||||
defer dirfd.Close()
|
defer dirfd.Close()
|
||||||
// Delete content
|
// Delete content
|
||||||
err = syscallcompat.Unlinkat(int(dirfd.Fd()), cName)
|
err = syscallcompat.Unlinkat(int(dirfd.Fd()), cName, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/hanwen/go-fuse/fuse"
|
"github.com/hanwen/go-fuse/fuse"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/configfile"
|
"github.com/rfjakob/gocryptfs/internal/configfile"
|
||||||
@ -231,9 +233,7 @@ retry:
|
|||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
// Actual Rmdir
|
// Actual Rmdir
|
||||||
// TODO Use syscall.Unlinkat with the AT_REMOVEDIR flag once it is available
|
err = syscallcompat.Unlinkat(int(parentDirFd.Fd()), cName, unix.AT_REMOVEDIR)
|
||||||
// in Go
|
|
||||||
err = syscall.Rmdir(cPath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This can happen if another file in the directory was created in the
|
// This can happen if another file in the directory was created in the
|
||||||
// meantime, undo the rename
|
// meantime, undo the rename
|
||||||
@ -245,7 +245,7 @@ retry:
|
|||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
// Delete "gocryptfs.diriv.rmdir.XYZ"
|
// Delete "gocryptfs.diriv.rmdir.XYZ"
|
||||||
err = syscallcompat.Unlinkat(int(parentDirFd.Fd()), tmpName)
|
err = syscallcompat.Unlinkat(int(parentDirFd.Fd()), tmpName, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
|
tlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ func ReadLongName(path string) (string, error) {
|
|||||||
|
|
||||||
// DeleteLongName deletes "hashName.name".
|
// DeleteLongName deletes "hashName.name".
|
||||||
func DeleteLongName(dirfd *os.File, hashName string) error {
|
func DeleteLongName(dirfd *os.File, hashName string) error {
|
||||||
err := syscallcompat.Unlinkat(int(dirfd.Fd()), hashName+LongNameSuffix)
|
err := syscallcompat.Unlinkat(int(dirfd.Fd()), hashName+LongNameSuffix, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Warn.Printf("DeleteLongName: %v", err)
|
tlog.Warn.Printf("DeleteLongName: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Sorry, fallocate is not available on OSX at all and
|
// Sorry, fallocate is not available on OSX at all and
|
||||||
@ -71,21 +73,24 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Poor man's Unlinkat
|
// Poor man's Unlinkat
|
||||||
func Unlinkat(dirfd int, path string) error {
|
func Unlinkat(dirfd int, path string, flags int) (err error) {
|
||||||
chdirMutex.Lock()
|
chdirMutex.Lock()
|
||||||
defer chdirMutex.Unlock()
|
defer chdirMutex.Unlock()
|
||||||
if !filepath.IsAbs(path) {
|
cwd, err := syscall.Open(".", syscall.O_RDONLY, 0)
|
||||||
oldWd, err := os.Getwd()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer os.Chdir(oldWd)
|
defer syscall.Close(cwd)
|
||||||
}
|
err = syscall.Fchdir(dirfd)
|
||||||
path, err := dirfdAbs(dirfd, path)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer syscall.Fchdir(cwd)
|
||||||
|
if (flags & unix.AT_REMOVEDIR) != 0 {
|
||||||
|
return syscall.Rmdir(path)
|
||||||
|
} else {
|
||||||
return syscall.Unlink(path)
|
return syscall.Unlink(path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poor man's Mknodat
|
// Poor man's Mknodat
|
||||||
|
@ -54,9 +54,19 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e
|
|||||||
return syscall.Renameat(olddirfd, oldpath, newdirfd, newpath)
|
return syscall.Renameat(olddirfd, oldpath, newdirfd, newpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlinkat wraps the Unlinkat syscall.
|
// Unlinkat syscall. In old versions the 'flags' argument was missing, so
|
||||||
func Unlinkat(dirfd int, path string) error {
|
// manually call it by using the corresponding syscall number.
|
||||||
return syscall.Unlinkat(dirfd, path)
|
func Unlinkat(dirfd int, path string, flags int) (err error) {
|
||||||
|
var _p0 *byte
|
||||||
|
_p0, err = syscall.BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, _, e1 := syscall.Syscall(syscall.SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mknodat wraps the Mknodat syscall.
|
// Mknodat wraps the Mknodat syscall.
|
||||||
|
Loading…
Reference in New Issue
Block a user