From 19168d41f0ee9eace4a412c47e3e9b412746c064 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 25 Jan 2009 13:11:14 -0800 Subject: [PATCH] HAMMER VFS - clean out cached data_buffer on unlock cursor to avoid deadlock Clean out any cached cursor->data_buffer when unlocking a cursor. The underlying buffer cache buffer could become stale and if we do not release our hammer_buffer reference on it other threads may deadlock trying to getblk() the buffer cache buffer in order to invalidate it. --- sys/vfs/hammer/hammer_cursor.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sys/vfs/hammer/hammer_cursor.c b/sys/vfs/hammer/hammer_cursor.c index 7def58895a..dc048dcbbc 100644 --- a/sys/vfs/hammer/hammer_cursor.c +++ b/sys/vfs/hammer/hammer_cursor.c @@ -489,11 +489,24 @@ hammer_cursor_down(hammer_cursor_t cursor) void hammer_unlock_cursor(hammer_cursor_t cursor) { + hammer_buffer_t data_buffer; hammer_node_t node; - hammer_inode_t ip; KKASSERT((cursor->flags & HAMMER_CURSOR_TRACKED) == 0); KKASSERT(cursor->node); + + /* + * We must release any cached data buffer held by the cursor, + * otherwise we can deadlock against other threads attempting + * to invalidate the underlying buffer cache buffers which + * become stale due to a pruning or reblocking operation. + */ + if ((data_buffer = cursor->data_buffer) != NULL) { + cursor->data_buffer = NULL; + cursor->data = NULL; + hammer_rel_buffer(data_buffer, 0); + } + /* * Release the cursor's locks and track B-Tree operations on node. * While being tracked our cursor can be modified by other threads @@ -521,7 +534,6 @@ hammer_unlock_cursor(hammer_cursor_t cursor) int hammer_lock_cursor(hammer_cursor_t cursor) { - hammer_inode_t ip; hammer_node_t node; int error; -- 2.41.0