Handle interrupt requests.

geesefs-0-30-9
Aaron Jacobs 2015-05-05 12:21:57 +10:00
parent 0c8f9cece8
commit 98fe7cbb0d
1 changed files with 32 additions and 2 deletions

View File

@ -171,6 +171,30 @@ func (c *Connection) finishOp(bfReq bazilfuse.Request) {
c.opsInFlight.Done()
}
// LOCKS_EXCLUDED(c.mu)
func (c *Connection) handleInterrupt(req *bazilfuse.InterruptRequest) {
c.mu.Lock()
defer c.mu.Unlock()
// NOTE(jacobsa): fuse.txt in the Linux kernel documentation
// (https://goo.gl/H55Dnr) defines the kernel <-> userspace protocol for
// interrupts.
//
// In particular, my reading of it is that an interrupt request cannot be
// delivered to userspace before the original request. The part about the
// race and EAGAIN appears to be aimed at userspace programs that
// concurrently process requests.
//
// So in this method we assume that if we can't find the ID to be
// interrupted, it means that the request has already been replied to.
cancel, ok := c.cancelFuncs[req.IntrID]
if !ok {
return
}
cancel()
}
// Read the next op from the kernel process. Return io.EOF if the kernel has
// closed the connection.
//
@ -196,8 +220,8 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) {
// Log the receipt of the operation.
c.log(opID, 1, "<- %v", bfReq)
// Special case: responding to this is required to make mounting work on OS
// X. We don't currently expose the capability for the file system to
// Special case: responding to statfs is required to make mounting work on
// OS X. We don't currently expose the capability for the file system to
// intercept this.
if statfsReq, ok := bfReq.(*bazilfuse.StatfsRequest); ok {
c.log(opID, 1, "-> (Statfs) OK")
@ -205,6 +229,12 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) {
continue
}
// Special case: handle interrupt requests.
if interruptReq, ok := bfReq.(*bazilfuse.InterruptRequest); ok {
c.handleInterrupt(interruptReq)
continue
}
// Set up op dependencies.
opCtx := c.beginOp(bfReq)