Skip to content

Commit

Permalink
LOCKD: Fix a deadlock in nlm_traverse_files()
Browse files Browse the repository at this point in the history
nlm_traverse_files() is not allowed to hold the nlm_file_mutex while calling
nlm_inspect file, since it may end up calling nlm_release_file() when
releaseing the blocks.

Signed-off-by: Trond Myklebust <[email protected]>
(cherry picked from e558d3cde986e04f68afe8c790ad68ef4b94587a commit)
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Aug 24, 2006
1 parent 8f8e7a5 commit 01df9c5
Showing 1 changed file with 9 additions and 6 deletions.
15 changes: 9 additions & 6 deletions fs/lockd/svcsubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,19 +237,22 @@ static int
nlm_traverse_files(struct nlm_host *host, int action)
{
struct nlm_file *file, **fp;
int i;
int i, ret = 0;

mutex_lock(&nlm_file_mutex);
for (i = 0; i < FILE_NRHASH; i++) {
fp = nlm_files + i;
while ((file = *fp) != NULL) {
file->f_count++;
mutex_unlock(&nlm_file_mutex);

/* Traverse locks, blocks and shares of this file
* and update file->f_locks count */
if (nlm_inspect_file(host, file, action)) {
mutex_unlock(&nlm_file_mutex);
return 1;
}
if (nlm_inspect_file(host, file, action))
ret = 1;

mutex_lock(&nlm_file_mutex);
file->f_count--;
/* No more references to this file. Let go of it. */
if (!file->f_blocks && !file->f_locks
&& !file->f_shares && !file->f_count) {
Expand All @@ -262,7 +265,7 @@ nlm_traverse_files(struct nlm_host *host, int action)
}
}
mutex_unlock(&nlm_file_mutex);
return 0;
return ret;
}

/*
Expand Down

0 comments on commit 01df9c5

Please sign in to comment.