From: Yang Erkun <yangerkun@xxxxxxxxxx> Only do check in cache_check, this is a prepare patch. Signed-off-by: Yang Erkun <yangerkun@xxxxxxxxxx> --- fs/nfs/dns_resolve.c | 4 +++- fs/nfsd/export.c | 6 +++++- fs/nfsd/nfs4idmap.c | 2 ++ net/sunrpc/auth_gss/svcauth_gss.c | 9 +++++++-- net/sunrpc/cache.c | 7 +++---- net/sunrpc/svcauth_unix.c | 12 +++++++++++- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c index 714975e5c0db..733163b01795 100644 --- a/fs/nfs/dns_resolve.c +++ b/fs/nfs/dns_resolve.c @@ -287,8 +287,10 @@ static int do_cache_lookup(struct cache_detail *cd, *item = nfs_dns_lookup(cd, key); if (*item) { ret = cache_check(cd, &(*item)->h, &dreq->req); - if (ret) + if (ret) { + cache_put(&(*item)->h, cd); *item = NULL; + } } return ret; } diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index aa4712362b3b..56002d9ef66b 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -953,6 +953,7 @@ exp_find_key(struct cache_detail *cd, struct auth_domain *clp, int fsid_type, return ERR_PTR(-ENOMEM); err = cache_check(cd, &ek->h, reqp); if (err) { + cache_put(&ek->h, cd); trace_nfsd_exp_find_key(&key, err); return ERR_PTR(err); } @@ -978,6 +979,7 @@ exp_get_by_name(struct cache_detail *cd, struct auth_domain *clp, return ERR_PTR(-ENOMEM); err = cache_check(cd, &exp->h, reqp); if (err) { + cache_put(&exp->h, cd); trace_nfsd_exp_get_by_name(&key, err); return ERR_PTR(err); } @@ -1428,8 +1430,10 @@ static int e_show(struct seq_file *m, void *p) if (!cache_get_rcu(&exp->h)) return 0; - if (cache_check(cd, &exp->h, NULL)) + if (cache_check(cd, &exp->h, NULL)) { + cache_put(&exp->h, cd); return 0; + } exp_put(exp); return svc_export_show(m, cd, cp); diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 8cca1329f348..8861e34b5126 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c @@ -515,6 +515,8 @@ idmap_lookup(struct svc_rqst *rqstp, return -ENOMEM; retry: ret = cache_check(detail, &(*item)->h, &rqstp->rq_chandle); + if (ret) + cache_put(&(*item)->h, detail); if (ret == -ETIMEDOUT) { struct ent *prev_item = *item; diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 73a90ad873fb..c0846adcb65e 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -634,8 +634,11 @@ gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle) rsc_free(&rsci); if (!found) return NULL; - if (cache_check(cd, &found->h, NULL)) + if (cache_check(cd, &found->h, NULL)) { + cache_put(&found->h, cd); return NULL; + } + return found; } @@ -1194,9 +1197,11 @@ svcauth_gss_legacy_init(struct svc_rqst *rqstp, rsi_free(&rsikey); if (!rsip) return SVC_CLOSE; - if (cache_check(sn->rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0) + if (cache_check(sn->rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0) { /* No upcall result: */ + cache_put(&rsip->h, sn->rsi_cache); return SVC_CLOSE; + } ret = SVC_CLOSE; if (!svcauth_gss_proc_init_verf(sn->rsc_cache, rqstp, &rsip->out_handle, diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 059f6ef1ad18..eaf4defd1fcf 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -336,8 +336,6 @@ int cache_check(struct cache_detail *detail, rv = -ETIMEDOUT; } } - if (rv) - cache_put(h, detail); return rv; } EXPORT_SYMBOL_GPL(cache_check); @@ -1430,10 +1428,11 @@ static int c_show(struct seq_file *m, void *p) if (!cache_get_rcu(cp)) return 0; - if (cache_check(cd, cp, NULL)) + if (cache_check(cd, cp, NULL)) { + cache_put(cp, cd); /* cache_check does a cache_put on failure */ seq_puts(m, "# "); - else { + } else { if (cache_is_expired(cd, cp)) seq_puts(m, "# "); cache_put(cp, cd); diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 8ca98b146ec8..df014463c054 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -651,6 +651,10 @@ static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp) if (!ug) return ERR_PTR(-EAGAIN); ret = cache_check(sn->unix_gid_cache, &ug->h, &rqstp->rq_chandle); + + if (ret) + cache_put(&ug->h, sn->unix_gid_cache); + switch (ret) { case -ENOENT: return ERR_PTR(-ENOENT); @@ -676,6 +680,7 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) struct svc_xprt *xprt = rqstp->rq_xprt; struct net *net = xprt->xpt_net; struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); + int check_res; switch (rqstp->rq_addr.ss_family) { case AF_INET: @@ -704,7 +709,12 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) if (ipm == NULL) return SVC_DENIED; - switch (cache_check(sn->ip_map_cache, &ipm->h, &rqstp->rq_chandle)) { + check_res = cache_check(sn->ip_map_cache, &ipm->h, &rqstp->rq_chandle); + + if (check_res) + cache_put(&ipm->h, sn->ip_map_cache); + + switch (check_res) { default: BUG(); case -ETIMEDOUT: -- 2.39.2