summaryrefslogtreecommitdiff
path: root/internal/fusefrontend/file2_setattr.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2020-07-05 20:05:07 +0200
committerJakob Unterwurzacher2020-07-05 20:10:53 +0200
commit63f68a0fcd514b7cf96a485016c2db23c60c3405 (patch)
treeb3c7cdb39fcec34250036a1d5cdef8321c79fe6e /internal/fusefrontend/file2_setattr.go
parentc22e78ee41f4c5a91429bb83c6be3e60b4c2a20f (diff)
v2api: implement Setattr
Diffstat (limited to 'internal/fusefrontend/file2_setattr.go')
-rw-r--r--internal/fusefrontend/file2_setattr.go83
1 files changed, 83 insertions, 0 deletions
diff --git a/internal/fusefrontend/file2_setattr.go b/internal/fusefrontend/file2_setattr.go
new file mode 100644
index 0000000..c341e53
--- /dev/null
+++ b/internal/fusefrontend/file2_setattr.go
@@ -0,0 +1,83 @@
+package fusefrontend
+
+import (
+ "context"
+ "syscall"
+
+ "github.com/hanwen/go-fuse/v2/fs"
+ "github.com/hanwen/go-fuse/v2/fuse"
+
+ "github.com/rfjakob/gocryptfs/internal/syscallcompat"
+)
+
+func (f *File2) Setattr(ctx context.Context, in *fuse.SetAttrIn, out *fuse.AttrOut) (errno syscall.Errno) {
+ errno = f.setAttr(ctx, in)
+ if errno != 0 {
+ return errno
+ }
+ return f.Getattr(ctx, out)
+}
+
+func (f *File2) setAttr(ctx context.Context, in *fuse.SetAttrIn) (errno syscall.Errno) {
+ f.fdLock.RLock()
+ defer f.fdLock.RUnlock()
+ if f.released {
+ return syscall.EBADF
+ }
+ f.fileTableEntry.ContentLock.Lock()
+ defer f.fileTableEntry.ContentLock.Unlock()
+
+ // chmod(2) & fchmod(2)
+ if mode, ok := in.GetMode(); ok {
+ errno = fs.ToErrno(syscall.Fchmod(f.intFd(), mode))
+ if errno != 0 {
+ return errno
+ }
+ }
+
+ // chown(2) & fchown(2)
+ uid32, uOk := in.GetUID()
+ gid32, gOk := in.GetGID()
+ if uOk || gOk {
+ uid := -1
+ gid := -1
+
+ if uOk {
+ uid = int(uid32)
+ }
+ if gOk {
+ gid = int(gid32)
+ }
+ errno = fs.ToErrno(syscall.Fchown(f.intFd(), uid, gid))
+ if errno != 0 {
+ return errno
+ }
+ }
+
+ // utimens(2)
+ mtime, mok := in.GetMTime()
+ atime, aok := in.GetATime()
+ if mok || aok {
+ ap := &atime
+ mp := &mtime
+ if !aok {
+ ap = nil
+ }
+ if !mok {
+ mp = nil
+ }
+ errno = fs.ToErrno(syscallcompat.FutimesNano(f.intFd(), ap, mp))
+ if errno != 0 {
+ return errno
+ }
+ }
+
+ // truncate(2)
+ if sz, ok := in.GetSize(); ok {
+ errno = syscall.Errno(f.truncate(sz))
+ if errno != 0 {
+ return errno
+ }
+ }
+ return 0
+}