diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-03-02 13:06:22 -0500 | 
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-03-02 13:06:22 -0500 | 
| commit | ebed9203b68a4f333ce5d17e874b26c3afcfeff1 (patch) | |
| tree | ec0c24396061eb662594a3b879acc760e41532b7 /fs/nfs | |
| parent | 9fcfe0c83c3b04a759cde6b8c5f961237f17808b (diff) | |
| download | olio-linux-3.10-ebed9203b68a4f333ce5d17e874b26c3afcfeff1.tar.xz olio-linux-3.10-ebed9203b68a4f333ce5d17e874b26c3afcfeff1.zip  | |
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: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
Diffstat (limited to 'fs/nfs')
| -rw-r--r-- | fs/nfs/dns_resolve.c | 18 | 
1 files changed, 15 insertions, 3 deletions
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c index 95e1ca765d4..3f0cd4dfdda 100644 --- a/fs/nfs/dns_resolve.c +++ b/fs/nfs/dns_resolve.c @@ -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,  };  |