1 Patch-mainline: submitted 04aug2009
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
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.
12 So re-do the lookup and if that returns a new item, proceed using that
15 Signed-off-by: NeilBrown <neilb@suse.de>
18 fs/nfsd/export.c | 18 ++++++++++++++++++
19 net/sunrpc/svcauth_unix.c | 22 ++++++++++++++++++++--
20 2 files changed, 38 insertions(+), 2 deletions(-)
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));
27 ek = svc_expkey_lookup(&key);
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);
38 + cache_put(&ek->h, &svc_expkey_cache);
43 @@ -870,9 +879,18 @@ static svc_export *exp_get_by_name(svc_c
44 key.ex_path.dentry = dentry;
46 exp = svc_export_lookup(&key);
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)
57 + cache_put(&exp->h, &svc_export_cache);
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)
67 struct unix_gid *ug = unix_gid_lookup(uid);
68 + struct unix_gid *prevug;
72 switch (cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle)) {
75 @@ -669,6 +671,13 @@ static int unix_gid_find(uid_t uid, stru
81 + ug = unix_gid_lookup(uid);
85 + cache_put(&ug->h, &unix_gid_cache);
89 @@ -679,7 +688,7 @@ svcauth_unix_set_client(struct svc_rqst
91 struct sockaddr_in *sin;
92 struct sockaddr_in6 *sin6, sin6_storage;
94 + struct ip_map *ipm, *prev_ipm;
96 switch (rqstp->rq_addr.ss_family) {
98 @@ -704,14 +713,23 @@ svcauth_unix_set_client(struct svc_rqst
99 ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
106 switch (cache_check(&ip_map_cache, &ipm->h, &rqstp->rq_chandle)) {
112 + ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
114 + if (ipm != prev_ipm)
117 + cache_put(&ipm->h, &ip_map_cache);