]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.fixes/nfsd-06-sunrpc-cache-retry-cache-lookups-that-return-ETIMEDO.patch
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / nfsd-06-sunrpc-cache-retry-cache-lookups-that-return-ETIMEDO.patch
1 Patch-mainline: submitted 04aug2009
2 References: bnc#498708
3 From: NeilBrown <neilb@suse.de>
4 Date: Tue, 4 Aug 2009 15:06:38 +1000
5 Subject: [PATCH 08/12] sunrpc/cache: retry cache lookups that return -ETIMEDOUT
6
7 If cache_check returns -ETIMEDOUT, then the cache item is not
8 up-to-date, but there is no pending upcall.
9 This could mean the data is not available, or it could mean that the
10 good data has been stored in a new cache item.
11
12 So re-do the lookup and if that returns a new item, proceed using that
13 item.
14
15 Signed-off-by: NeilBrown <neilb@suse.de>
16
17 ---
18 fs/nfsd/export.c | 18 ++++++++++++++++++
19 net/sunrpc/svcauth_unix.c | 22 ++++++++++++++++++++--
20 2 files changed, 38 insertions(+), 2 deletions(-)
21
22 --- linux-2.6.27-SLE11_BRANCH.orig/fs/nfsd/export.c
23 +++ linux-2.6.27-SLE11_BRANCH/fs/nfsd/export.c
24 @@ -796,9 +796,18 @@ exp_find_key(svc_client *clp, int fsid_t
25 memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
26
27 ek = svc_expkey_lookup(&key);
28 + again:
29 if (ek == NULL)
30 return ERR_PTR(-ENOMEM);
31 err = cache_check(&svc_expkey_cache, &ek->h, reqp);
32 + if (err == -ETIMEDOUT) {
33 + struct svc_expkey *prev_ek = ek;
34 + ek = svc_expkey_lookup(&key);
35 + if (ek != prev_ek)
36 + goto again;
37 + if (ek)
38 + cache_put(&ek->h, &svc_expkey_cache);
39 + }
40 if (err)
41 return ERR_PTR(err);
42 return ek;
43 @@ -870,9 +879,18 @@ static svc_export *exp_get_by_name(svc_c
44 key.ex_path.dentry = dentry;
45
46 exp = svc_export_lookup(&key);
47 + retry:
48 if (exp == NULL)
49 return ERR_PTR(-ENOMEM);
50 err = cache_check(&svc_export_cache, &exp->h, reqp);
51 + if (err == -ETIMEDOUT) {
52 + struct svc_export *prev_exp = exp;
53 + exp = svc_export_lookup(&key);
54 + if (exp != prev_exp)
55 + goto retry;
56 + if (exp)
57 + cache_put(&exp->h, &svc_export_cache);
58 + }
59 if (err)
60 return ERR_PTR(err);
61 return exp;
62 --- linux-2.6.27-SLE11_BRANCH.orig/net/sunrpc/svcauth_unix.c
63 +++ linux-2.6.27-SLE11_BRANCH/net/sunrpc/svcauth_unix.c
64 @@ -659,8 +659,10 @@ static int unix_gid_find(uid_t uid, stru
65 struct svc_rqst *rqstp)
66 {
67 struct unix_gid *ug = unix_gid_lookup(uid);
68 + struct unix_gid *prevug;
69 if (!ug)
70 return -EAGAIN;
71 + retry:
72 switch (cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle)) {
73 case -ENOENT:
74 *gip = NULL;
75 @@ -669,6 +671,13 @@ static int unix_gid_find(uid_t uid, stru
76 *gip = ug->gi;
77 get_group_info(*gip);
78 return 0;
79 + case -ETIMEDOUT:
80 + prevug = ug;
81 + ug = unix_gid_lookup(uid);
82 + if (ug != prevug)
83 + goto retry;
84 + if (ug)
85 + cache_put(&ug->h, &unix_gid_cache);
86 default:
87 return -EAGAIN;
88 }
89 @@ -679,7 +688,7 @@ svcauth_unix_set_client(struct svc_rqst
90 {
91 struct sockaddr_in *sin;
92 struct sockaddr_in6 *sin6, sin6_storage;
93 - struct ip_map *ipm;
94 + struct ip_map *ipm, *prev_ipm;
95
96 switch (rqstp->rq_addr.ss_family) {
97 case AF_INET:
98 @@ -704,14 +713,23 @@ svcauth_unix_set_client(struct svc_rqst
99 ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
100 &sin6->sin6_addr);
101
102 + retry:
103 if (ipm == NULL)
104 return SVC_DENIED;
105
106 switch (cache_check(&ip_map_cache, &ipm->h, &rqstp->rq_chandle)) {
107 default:
108 BUG();
109 - case -EAGAIN:
110 case -ETIMEDOUT:
111 + prev_ipm = ipm;
112 + ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
113 + &sin6->sin6_addr);
114 + if (ipm != prev_ipm)
115 + goto retry;
116 + if (ipm)
117 + cache_put(&ipm->h, &ip_map_cache);
118 +
119 + case -EAGAIN:
120 return SVC_DROP;
121 case -ENOENT:
122 return SVC_DENIED;