Handle interrupt requests.
parent
0c8f9cece8
commit
98fe7cbb0d
|
@ -171,6 +171,30 @@ func (c *Connection) finishOp(bfReq bazilfuse.Request) {
|
||||||
c.opsInFlight.Done()
|
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
|
// Read the next op from the kernel process. Return io.EOF if the kernel has
|
||||||
// closed the connection.
|
// closed the connection.
|
||||||
//
|
//
|
||||||
|
@ -196,8 +220,8 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) {
|
||||||
// Log the receipt of the operation.
|
// Log the receipt of the operation.
|
||||||
c.log(opID, 1, "<- %v", bfReq)
|
c.log(opID, 1, "<- %v", bfReq)
|
||||||
|
|
||||||
// Special case: responding to this is required to make mounting work on OS
|
// Special case: responding to statfs is required to make mounting work on
|
||||||
// X. We don't currently expose the capability for the file system to
|
// OS X. We don't currently expose the capability for the file system to
|
||||||
// intercept this.
|
// intercept this.
|
||||||
if statfsReq, ok := bfReq.(*bazilfuse.StatfsRequest); ok {
|
if statfsReq, ok := bfReq.(*bazilfuse.StatfsRequest); ok {
|
||||||
c.log(opID, 1, "-> (Statfs) OK")
|
c.log(opID, 1, "-> (Statfs) OK")
|
||||||
|
@ -205,6 +229,12 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Special case: handle interrupt requests.
|
||||||
|
if interruptReq, ok := bfReq.(*bazilfuse.InterruptRequest); ok {
|
||||||
|
c.handleInterrupt(interruptReq)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Set up op dependencies.
|
// Set up op dependencies.
|
||||||
opCtx := c.beginOp(bfReq)
|
opCtx := c.beginOp(bfReq)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue