LOCKD: Fix a deadlock in nlm_traverse_files()
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 <Trond.Myklebust@netapp.com> (cherry picked from e558d3cde986e04f68afe8c790ad68ef4b94587a commit)
This commit is contained in:
parent
8f8e7a50f4
commit
01df9c5e91
|
@ -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) {
|
||||
|
@ -262,7 +265,7 @@ nlm_traverse_files(struct nlm_host *host, int action)
|
|||
}
|
||||
}
|
||||
mutex_unlock(&nlm_file_mutex);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue