NLM: Fix "kernel BUG at fs/lockd/host.c:417!" or ".../host.c:283!"
Nick Bowler <nbowler@elliptictech.com> reports: > We were just having some NFS server troubles, and my client machine > running 2.6.38-rc1+ (specifically, commit2b1caf6ed7
) crashed > hard (syslog output appended to this mail). > > I'm not sure what the exact timeline was or how to reproduce this, > but the server was rebooted during all this. Since I've never seen > this happen before, it is possibly a regression from previous kernel > releases. However, I recently updated my nfs-utils (on the client) to > version 1.2.3, so that might be related as well. [ BUG output redacted ] When done searching, the for_each_host loop in next_host_state() falls through and returns the final host on the host chain without bumping it's reference count. Since the host's ref count is only one at that point, releasing the host in nlm_host_rebooted() attempts to destroy the host prematurely, and therefore hits a BUG(). Likely, the original intent of the for_each_host behavior in next_host_state() was to handle the case when the host chain is empty. Searching the chain and finding no suitable host to return needs to be handled as well. Defensively restructure next_host_state() always to return NULL when the loop falls through. Introduced by commitb10e30f6
"lockd: reorganize nlm_host_rebooted". Cc: J. Bruce Fields <bfields@fieldses.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Родитель
f61f6da0d5
Коммит
80c30e8de4
|
@ -520,7 +520,7 @@ static struct nlm_host *next_host_state(struct hlist_head *cache,
|
|||
struct nsm_handle *nsm,
|
||||
const struct nlm_reboot *info)
|
||||
{
|
||||
struct nlm_host *host = NULL;
|
||||
struct nlm_host *host;
|
||||
struct hlist_head *chain;
|
||||
struct hlist_node *pos;
|
||||
|
||||
|
@ -532,13 +532,14 @@ static struct nlm_host *next_host_state(struct hlist_head *cache,
|
|||
host->h_state++;
|
||||
|
||||
nlm_get_host(host);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&nlm_host_mutex);
|
||||
return host;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&nlm_host_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* nlm_host_rebooted - Release all resources held by rebooted host
|
||||
|
|
Загрузка…
Ссылка в новой задаче