From d7e438be5e933c0ca5670e397f9c2bacc5f9616f Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Mon, 21 Feb 2011 16:53:08 -0800 Subject: [PATCH] pnfs: only return-on-close for last close added pnfs_layout.open_count to count open references, and only return the layout when pnfs_open_state_close() takes the open_count to 0 use InterlockedIncrement/Decrement to avoid an exclusive lock on the layout Signed-off-by: Casey Bodley --- daemon/pnfs.h | 1 + daemon/pnfs_layout.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/daemon/pnfs.h b/daemon/pnfs.h index 6e826b3..714841b 100644 --- a/daemon/pnfs.h +++ b/daemon/pnfs.h @@ -163,6 +163,7 @@ typedef struct __pnfs_layout { enum pnfs_iomode iomode; enum pnfs_layout_status status; bool_t return_on_close; + LONG open_count; /* for return on last close */ uint32_t io_count; /* number of pending io operations */ SRWLOCK lock; } pnfs_layout; diff --git a/daemon/pnfs_layout.c b/daemon/pnfs_layout.c index b3b9fb7..19bca68 100644 --- a/daemon/pnfs_layout.c +++ b/daemon/pnfs_layout.c @@ -539,10 +539,11 @@ enum pnfs_status pnfs_open_state_layout( if (status) { status = file_layout_find_or_create(layouts, &state->file.fh, &layout); if (status == PNFS_SUCCESS) { + LONG open_count = InterlockedIncrement(&layout->layout.open_count); state->layout = layout; - dprintf(FLLVL, "pnfs_open_state_layout() caching layout %p\n", - state->layout); + dprintf(FLLVL, "pnfs_open_state_layout() caching layout %p " + "(%u opens)\n", state->layout, open_count); } } @@ -576,7 +577,7 @@ void pnfs_open_state_close( IN bool_t remove) { pnfs_file_layout *layout; - bool_t return_on_close; + bool_t return_layout; enum pnfs_status status; AcquireSRWLockExclusive(&state->lock); @@ -585,12 +586,14 @@ void pnfs_open_state_close( ReleaseSRWLockExclusive(&state->lock); if (layout) { - /* check if we need to return the layout on close */ + LONG open_count = InterlockedDecrement(&layout->layout.open_count); + AcquireSRWLockShared(&layout->layout.lock); - return_on_close = layout->layout.return_on_close; + /* only return on close if it's the last close */ + return_layout = layout->layout.return_on_close && (open_count <= 0); ReleaseSRWLockShared(&layout->layout.lock); - if (return_on_close) { + if (return_layout) { status = file_layout_return(session, &state->file, layout); if (status) eprintf("file_layout_return() failed with %s\n",