summaryrefslogtreecommitdiff
path: root/pathfs_frontend/fs_dir.go
diff options
context:
space:
mode:
Diffstat (limited to 'pathfs_frontend/fs_dir.go')
-rw-r--r--pathfs_frontend/fs_dir.go157
1 files changed, 0 insertions, 157 deletions
diff --git a/pathfs_frontend/fs_dir.go b/pathfs_frontend/fs_dir.go
deleted file mode 100644
index d378d28..0000000
--- a/pathfs_frontend/fs_dir.go
+++ /dev/null
@@ -1,157 +0,0 @@
-package pathfs_frontend
-
-// Mkdir and Rmdir
-
-import (
- "fmt"
- "os"
- "path/filepath"
- "syscall"
-
- "github.com/hanwen/go-fuse/fuse"
-
- "github.com/rfjakob/gocryptfs/internal/toggledlog"
- "github.com/rfjakob/gocryptfs/internal/cryptocore"
- "github.com/rfjakob/gocryptfs/internal/nametransform"
-)
-
-func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fuse.Status) {
- if fs.isFiltered(relPath) {
- return fuse.EPERM
- }
- encPath, err := fs.getBackingPath(relPath)
- if err != nil {
- return fuse.ToStatus(err)
- }
- if !fs.args.DirIV {
- return fuse.ToStatus(os.Mkdir(encPath, os.FileMode(mode)))
- }
-
- // We need write and execute permissions to create gocryptfs.diriv
- origMode := mode
- mode = mode | 0300
-
- // The new directory may take the place of an older one that is still in the cache
- fs.nameTransform.DirIVCache.Clear()
- // Create directory
- fs.dirIVLock.Lock()
- defer fs.dirIVLock.Unlock()
- err = os.Mkdir(encPath, os.FileMode(mode))
- if err != nil {
- return fuse.ToStatus(err)
- }
- // Create gocryptfs.diriv inside
- err = nametransform.WriteDirIV(encPath)
- if err != nil {
- // This should not happen
- toggledlog.Warn.Printf("Mkdir: WriteDirIV failed: %v", err)
- err2 := syscall.Rmdir(encPath)
- if err2 != nil {
- toggledlog.Warn.Printf("Mkdir: Rmdir rollback failed: %v", err2)
- }
- return fuse.ToStatus(err)
- }
-
- // Set permissions back to what the user wanted
- if origMode != mode {
- err = os.Chmod(encPath, os.FileMode(origMode))
- if err != nil {
- toggledlog.Warn.Printf("Mkdir: Chmod failed: %v", err)
- }
- }
-
- return fuse.OK
-}
-
-func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
- encPath, err := fs.getBackingPath(name)
- if err != nil {
- return fuse.ToStatus(err)
- }
- if !fs.args.DirIV {
- return fuse.ToStatus(syscall.Rmdir(encPath))
- }
-
- // If the directory is not empty besides gocryptfs.diriv, do not even
- // attempt the dance around gocryptfs.diriv.
- fd, err := os.Open(encPath)
- if perr, ok := err.(*os.PathError); ok && perr.Err == syscall.EACCES {
- // We need permission to read and modify the directory
- toggledlog.Debug.Printf("Rmdir: handling EACCESS")
- fi, err2 := os.Stat(encPath)
- if err2 != nil {
- toggledlog.Debug.Printf("Rmdir: Stat: %v", err2)
- return fuse.ToStatus(err2)
- }
- origMode := fi.Mode()
- newMode := origMode | 0700
- err2 = os.Chmod(encPath, newMode)
- if err2 != nil {
- toggledlog.Debug.Printf("Rmdir: Chmod failed: %v", err2)
- return fuse.ToStatus(err)
- }
- defer func() {
- if code != fuse.OK {
- // Undo the chmod if removing the directory failed
- err3 := os.Chmod(encPath, origMode)
- if err3 != nil {
- toggledlog.Warn.Printf("Rmdir: Chmod rollback failed: %v", err2)
- }
- }
- }()
- // Retry open
- fd, err = os.Open(encPath)
- }
- if err != nil {
- toggledlog.Debug.Printf("Rmdir: Open: %v", err)
- return fuse.ToStatus(err)
- }
- list, err := fd.Readdirnames(10)
- fd.Close()
- if err != nil {
- toggledlog.Debug.Printf("Rmdir: Readdirnames: %v", err)
- return fuse.ToStatus(err)
- }
- if len(list) > 1 {
- return fuse.ToStatus(syscall.ENOTEMPTY)
- } else if len(list) == 0 {
- toggledlog.Warn.Printf("Rmdir: gocryptfs.diriv missing, allowing deletion")
- return fuse.ToStatus(syscall.Rmdir(encPath))
- }
-
- // Move "gocryptfs.diriv" to the parent dir as "gocryptfs.diriv.rmdir.XYZ"
- dirivPath := filepath.Join(encPath, nametransform.DirIVFilename)
- parentDir := filepath.Dir(encPath)
- tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", cryptocore.RandUint64())
- tmpDirivPath := filepath.Join(parentDir, tmpName)
- toggledlog.Debug.Printf("Rmdir: Renaming %s to %s", nametransform.DirIVFilename, tmpDirivPath)
- // The directory is in an inconsistent state between rename and rmdir. Protect against
- // concurrent readers.
- fs.dirIVLock.Lock()
- defer fs.dirIVLock.Unlock()
- err = os.Rename(dirivPath, tmpDirivPath)
- if err != nil {
- toggledlog.Warn.Printf("Rmdir: Renaming %s to %s failed: %v",
- nametransform.DirIVFilename, tmpDirivPath, err)
- return fuse.ToStatus(err)
- }
- // Actual Rmdir
- err = syscall.Rmdir(encPath)
- if err != nil {
- // This can happen if another file in the directory was created in the
- // meantime, undo the rename
- err2 := os.Rename(tmpDirivPath, dirivPath)
- if err2 != nil {
- toggledlog.Warn.Printf("Rmdir: Rename rollback failed: %v", err2)
- }
- return fuse.ToStatus(err)
- }
- // Delete "gocryptfs.diriv.rmdir.INODENUMBER"
- err = syscall.Unlink(tmpDirivPath)
- if err != nil {
- toggledlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
- }
- // The now-deleted directory may have been in the DirIV cache. Clear it.
- fs.nameTransform.DirIVCache.Clear()
- return fuse.OK
-}