diff options
author | Fabricio Voznika <fvoznika@google.com> | 2020-09-01 19:20:37 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-09-01 19:22:12 -0700 |
commit | 37a217aca4a128d66a6dd4969375ea81bd879ac7 (patch) | |
tree | 21f60d54ca05029cd2c67d7de78cb987ee76f050 /pkg/p9/handlers.go | |
parent | 40faeaa180a30906da4822a105c43fcdb996750d (diff) |
Implement setattr+clunk in 9P
This is to cover the common pattern: open->read/write->close,
where SetAttr needs to be called to update atime/mtime before
the file is closed.
Benchmark results:
BM_OpenReadClose/10240 CPU
setattr+clunk: 63783 ns
VFS2: 68109 ns
VFS1: 72507 ns
Updates #1198
PiperOrigin-RevId: 329628461
Diffstat (limited to 'pkg/p9/handlers.go')
-rw-r--r-- | pkg/p9/handlers.go | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/pkg/p9/handlers.go b/pkg/p9/handlers.go index 1db5797dd..abd237f46 100644 --- a/pkg/p9/handlers.go +++ b/pkg/p9/handlers.go @@ -123,6 +123,37 @@ func (t *Tclunk) handle(cs *connState) message { return &Rclunk{} } +func (t *Tsetattrclunk) handle(cs *connState) message { + ref, ok := cs.LookupFID(t.FID) + if !ok { + return newErr(syscall.EBADF) + } + defer ref.DecRef() + + setAttrErr := ref.safelyWrite(func() error { + // We don't allow setattr on files that have been deleted. + // This might be technically incorrect, as it's possible that + // there were multiple links and you can still change the + // corresponding inode information. + if ref.isDeleted() { + return syscall.EINVAL + } + + // Set the attributes. + return ref.file.SetAttr(t.Valid, t.SetAttr) + }) + + // Try to delete FID even in case of failure above. Since the state of the + // file is unknown to the caller, it will not attempt to close the file again. + if !cs.DeleteFID(t.FID) { + return newErr(syscall.EBADF) + } + if setAttrErr != nil { + return newErr(setAttrErr) + } + return &Rsetattrclunk{} +} + // handle implements handler.handle. func (t *Tremove) handle(cs *connState) message { ref, ok := cs.LookupFID(t.FID) |