Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ebed9203 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

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: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
parent 9fcfe0c8
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -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,
		struct cache_head *ckey)
{
@@ -49,8 +62,7 @@ static void nfs_dns_ent_init(struct cache_head *cnew,
	new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL);
	if (new->hostname) {
		new->namelen = key->namelen;
		memcpy(&new->addr, &key->addr, key->addrlen);
		new->addrlen = key->addrlen;
		nfs_dns_ent_update(cnew, ckey);
	} else {
		new->namelen = 0;
		new->addrlen = 0;
@@ -234,7 +246,7 @@ static struct cache_detail nfs_dns_resolve = {
	.cache_show = nfs_dns_show,
	.match = nfs_dns_match,
	.init = nfs_dns_ent_init,
	.update = nfs_dns_ent_init,
	.update = nfs_dns_ent_update,
	.alloc = nfs_dns_ent_alloc,
};