提交 ebed9203 编写于 作者: T Trond Myklebust

NFS: Fix an allocation-under-spinlock bug

sunrpc_cache_update() will always call detail->update() from inside the
detail->hash_lock, so it cannot allocate memory.
Signed-off-by: NTrond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
上级 9fcfe0c8
...@@ -36,6 +36,19 @@ struct nfs_dns_ent { ...@@ -36,6 +36,19 @@ struct nfs_dns_ent {
}; };
static void nfs_dns_ent_update(struct cache_head *cnew,
struct cache_head *ckey)
{
struct nfs_dns_ent *new;
struct nfs_dns_ent *key;
new = container_of(cnew, struct nfs_dns_ent, h);
key = container_of(ckey, struct nfs_dns_ent, h);
memcpy(&new->addr, &key->addr, key->addrlen);
new->addrlen = key->addrlen;
}
static void nfs_dns_ent_init(struct cache_head *cnew, static void nfs_dns_ent_init(struct cache_head *cnew,
struct cache_head *ckey) struct cache_head *ckey)
{ {
...@@ -49,8 +62,7 @@ static void nfs_dns_ent_init(struct cache_head *cnew, ...@@ -49,8 +62,7 @@ static void nfs_dns_ent_init(struct cache_head *cnew,
new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL); new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL);
if (new->hostname) { if (new->hostname) {
new->namelen = key->namelen; new->namelen = key->namelen;
memcpy(&new->addr, &key->addr, key->addrlen); nfs_dns_ent_update(cnew, ckey);
new->addrlen = key->addrlen;
} else { } else {
new->namelen = 0; new->namelen = 0;
new->addrlen = 0; new->addrlen = 0;
...@@ -234,7 +246,7 @@ static struct cache_detail nfs_dns_resolve = { ...@@ -234,7 +246,7 @@ static struct cache_detail nfs_dns_resolve = {
.cache_show = nfs_dns_show, .cache_show = nfs_dns_show,
.match = nfs_dns_match, .match = nfs_dns_match,
.init = nfs_dns_ent_init, .init = nfs_dns_ent_init,
.update = nfs_dns_ent_init, .update = nfs_dns_ent_update,
.alloc = nfs_dns_ent_alloc, .alloc = nfs_dns_ent_alloc,
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册