Commit a95445ae authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Protect notify writes with a separate lock.

This protects against deadlocks if the kernel calls back into
userspace in the notify handler.
parent 7c251d2f
...@@ -24,6 +24,9 @@ type Server struct { ...@@ -24,6 +24,9 @@ type Server struct {
mountPoint string mountPoint string
fileSystem RawFileSystem fileSystem RawFileSystem
// writeMu serializes close and notify writes
writeMu sync.Mutex
// I/O with kernel and daemon. // I/O with kernel and daemon.
mountFd int mountFd int
...@@ -287,9 +290,9 @@ func (ms *Server) Serve() { ...@@ -287,9 +290,9 @@ func (ms *Server) Serve() {
ms.loop(false) ms.loop(false)
ms.loops.Wait() ms.loops.Wait()
ms.reqMu.Lock() ms.writeMu.Lock()
syscall.Close(ms.mountFd) syscall.Close(ms.mountFd)
ms.reqMu.Unlock() ms.writeMu.Unlock()
} }
func (ms *Server) loop(exitIdle bool) { func (ms *Server) loop(exitIdle bool) {
...@@ -399,9 +402,9 @@ func (ms *Server) InodeNotify(node uint64, off int64, length int64) Status { ...@@ -399,9 +402,9 @@ func (ms *Server) InodeNotify(node uint64, off int64, length int64) Status {
req.outData = unsafe.Pointer(entry) req.outData = unsafe.Pointer(entry)
// Protect against concurrent close. // Protect against concurrent close.
ms.reqMu.Lock() ms.writeMu.Lock()
result := ms.write(&req) result := ms.write(&req)
ms.reqMu.Unlock() ms.writeMu.Unlock()
if ms.debug { if ms.debug {
log.Println("Response: INODE_NOTIFY", result) log.Println("Response: INODE_NOTIFY", result)
...@@ -440,9 +443,9 @@ func (ms *Server) DeleteNotify(parent uint64, child uint64, name string) Status ...@@ -440,9 +443,9 @@ func (ms *Server) DeleteNotify(parent uint64, child uint64, name string) Status
req.flatData = nameBytes req.flatData = nameBytes
// Protect against concurrent close. // Protect against concurrent close.
ms.reqMu.Lock() ms.writeMu.Lock()
result := ms.write(&req) result := ms.write(&req)
ms.reqMu.Unlock() ms.writeMu.Unlock()
if ms.debug { if ms.debug {
log.Printf("Response: DELETE_NOTIFY: %v", result) log.Printf("Response: DELETE_NOTIFY: %v", result)
...@@ -474,9 +477,9 @@ func (ms *Server) EntryNotify(parent uint64, name string) Status { ...@@ -474,9 +477,9 @@ func (ms *Server) EntryNotify(parent uint64, name string) Status {
req.flatData = nameBytes req.flatData = nameBytes
// Protect against concurrent close. // Protect against concurrent close.
ms.reqMu.Lock() ms.writeMu.Lock()
result := ms.write(&req) result := ms.write(&req)
ms.reqMu.Unlock() ms.writeMu.Unlock()
if ms.debug { if ms.debug {
log.Printf("Response: ENTRY_NOTIFY: %v", result) log.Printf("Response: ENTRY_NOTIFY: %v", result)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment