]>
Commit | Line | Data |
---|---|---|
6d43f5ef GKH |
1 | From 8d96b10639fb402357b75b055b1e82a65ff95050 Mon Sep 17 00:00:00 2001 |
2 | From: NeilBrown <neilb@suse.de> | |
3 | Date: Wed, 31 Oct 2012 12:16:01 +1100 | |
4 | Subject: NFS: fix bug in legacy DNS resolver. | |
5 | ||
6 | From: NeilBrown <neilb@suse.de> | |
7 | ||
8 | commit 8d96b10639fb402357b75b055b1e82a65ff95050 upstream. | |
9 | ||
10 | The DNS resolver's use of the sunrpc cache involves a 'ttl' number | |
11 | (relative) rather that a timeout (absolute). This confused me when | |
12 | I wrote | |
13 | commit c5b29f885afe890f953f7f23424045cdad31d3e4 | |
14 | "sunrpc: use seconds since boot in expiry cache" | |
15 | ||
16 | and I managed to break it. The effect is that any TTL is interpreted | |
17 | as 0, and nothing useful gets into the cache. | |
18 | ||
19 | This patch removes the use of get_expiry() - which really expects an | |
20 | expiry time - and uses get_uint() instead, treating the int correctly | |
21 | as a ttl. | |
22 | ||
23 | This fixes a regression that has been present since 2.6.37, causing | |
24 | certain NFS accesses in certain environments to incorrectly fail. | |
25 | ||
26 | Reported-by: Chuck Lever <chuck.lever@oracle.com> | |
27 | Tested-by: Chuck Lever <chuck.lever@oracle.com> | |
28 | Signed-off-by: NeilBrown <neilb@suse.de> | |
29 | Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> | |
30 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
31 | ||
32 | --- | |
33 | fs/nfs/dns_resolve.c | 5 +++-- | |
34 | 1 file changed, 3 insertions(+), 2 deletions(-) | |
35 | ||
36 | --- a/fs/nfs/dns_resolve.c | |
37 | +++ b/fs/nfs/dns_resolve.c | |
38 | @@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_de | |
39 | { | |
40 | char buf1[NFS_DNS_HOSTNAME_MAXLEN+1]; | |
41 | struct nfs_dns_ent key, *item; | |
42 | - unsigned long ttl; | |
43 | + unsigned int ttl; | |
44 | ssize_t len; | |
45 | int ret = -EINVAL; | |
46 | ||
47 | @@ -240,7 +240,8 @@ static int nfs_dns_parse(struct cache_de | |
48 | key.namelen = len; | |
49 | memset(&key.h, 0, sizeof(key.h)); | |
50 | ||
51 | - ttl = get_expiry(&buf); | |
52 | + if (get_uint(&buf, &ttl) < 0) | |
53 | + goto out; | |
54 | if (ttl == 0) | |
55 | goto out; | |
56 | key.h.expiry_time = ttl + seconds_since_boot(); |