From 54ad710d241f6e6d48859cfefbd7c407bad89ef6 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Wed, 22 Mar 2023 18:46:22 +0300 Subject: [PATCH] Add PollOp --- conversions.go | 20 ++++++++++++++++++++ fuseops/ops.go | 25 +++++++++++++++++++++++++ fuseutil/file_system.go | 4 ++++ fuseutil/not_implemented_file_system.go | 6 ++++++ 4 files changed, 55 insertions(+) diff --git a/conversions.go b/conversions.go index ac512c1..b0c25d5 100644 --- a/conversions.go +++ b/conversions.go @@ -688,6 +688,22 @@ func convertInMessage( Pid: inMsg.Header().Pid}, } + case fusekernel.OpPoll: + type input fusekernel.PollIn + in := (*input)(inMsg.Consume(unsafe.Sizeof(input{}))) + if in == nil { + return nil, errors.New("Corrupt OpPoll") + } + + o = &fuseops.PollOp{ + Inode: fuseops.InodeID(inMsg.Header().Nodeid), + Handle: fuseops.HandleID(in.Fh), + Kh: in.Kh, + Flags: fusekernel.PollFlags(in.Flags), + Events: fusekernel.PollEvents(in.Events), + OpContext: fuseops.OpContext{Pid: inMsg.Header().Pid}, + } + default: o = &unknownOp{ OpCode: inMsg.Header().Opcode, @@ -944,6 +960,10 @@ func (c *Connection) kernelResponseForOp( out.TimeGran = 1 out.MaxPages = o.MaxPages + case *fuseops.PollOp: + out := (*fusekernel.PollOut)(m.Grow(int(unsafe.Sizeof(fusekernel.PollOut{})))) + out.Revents = uint32(o.Revents) + default: panic(fmt.Sprintf("Unexpected op: %#v", op)) } diff --git a/fuseops/ops.go b/fuseops/ops.go index 7e1a143..9001b74 100644 --- a/fuseops/ops.go +++ b/fuseops/ops.go @@ -965,3 +965,28 @@ type FallocateOp struct { Mode uint32 OpContext OpContext } + +// Request notifications when the file system user calls poll/select or +// similar operations on a file. +type PollOp struct { + // The inode and handle the user wants to poll + Inode InodeID + Handle HandleID + + // Kh is the "kernel handle". The reason behind it is that it's allocated + // by the kernel on file allocation and guaranteed to be unique as opposed + // to regular file handles (HandleID) generated by the userland server + // (by us). Kh has to be used in NotifyPollWakeupOut replies. + Kh uint64 + + // Poll flags + Flags fusekernel.PollFlags + + // Requested events + Events fusekernel.PollEvents + + // Set by the file system: the actual events that have happened + // since the last poll + Revents fusekernel.PollEvents + OpContext OpContext +} diff --git a/fuseutil/file_system.go b/fuseutil/file_system.go index 5eab68a..bef2145 100644 --- a/fuseutil/file_system.go +++ b/fuseutil/file_system.go @@ -63,6 +63,7 @@ type FileSystem interface { ListXattr(context.Context, *fuseops.ListXattrOp) error SetXattr(context.Context, *fuseops.SetXattrOp) error Fallocate(context.Context, *fuseops.FallocateOp) error + Poll(context.Context, *fuseops.PollOp) error // Regard all inodes (including the root inode) as having their lookup counts // decremented to zero, and clean up any resources associated with the file @@ -236,6 +237,9 @@ func (s *fileSystemServer) handleOp( case *fuseops.FallocateOp: err = s.fs.Fallocate(ctx, typed) + + case *fuseops.PollOp: + err = s.fs.Poll(ctx, typed) } c.Reply(ctx, err) diff --git a/fuseutil/not_implemented_file_system.go b/fuseutil/not_implemented_file_system.go index cfb116c..356327e 100644 --- a/fuseutil/not_implemented_file_system.go +++ b/fuseutil/not_implemented_file_system.go @@ -204,5 +204,11 @@ func (fs *NotImplementedFileSystem) Fallocate( return fuse.ENOSYS } +func (fs *NotImplementedFileSystem) Poll( + ctx context.Context, + op *fuseops.PollOp) error { + return fuse.ENOSYS +} + func (fs *NotImplementedFileSystem) Destroy() { }