Commit baab935ff3bdac20c558809da0d8e8f761840219
Committed by
Linus Torvalds
1 parent
ebd0cb1af3
Exists in
master
and in
7 other branches
[PATCH] knfsd: Convert sunrpc_cache to use krefs
.. it makes some of the code nicer. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 8 changed files with 72 additions and 84 deletions Side-by-side Diff
fs/nfsd/export.c
... | ... | @@ -57,18 +57,17 @@ |
57 | 57 | #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1) |
58 | 58 | static struct cache_head *expkey_table[EXPKEY_HASHMAX]; |
59 | 59 | |
60 | -void expkey_put(struct cache_head *item, struct cache_detail *cd) | |
60 | +void expkey_put(struct kref *ref) | |
61 | 61 | { |
62 | - if (cache_put(item, cd)) { | |
63 | - struct svc_expkey *key = container_of(item, struct svc_expkey, h); | |
64 | - if (test_bit(CACHE_VALID, &item->flags) && | |
65 | - !test_bit(CACHE_NEGATIVE, &item->flags)) { | |
66 | - dput(key->ek_dentry); | |
67 | - mntput(key->ek_mnt); | |
68 | - } | |
69 | - auth_domain_put(key->ek_client); | |
70 | - kfree(key); | |
62 | + struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref); | |
63 | + | |
64 | + if (test_bit(CACHE_VALID, &key->h.flags) && | |
65 | + !test_bit(CACHE_NEGATIVE, &key->h.flags)) { | |
66 | + dput(key->ek_dentry); | |
67 | + mntput(key->ek_mnt); | |
71 | 68 | } |
69 | + auth_domain_put(key->ek_client); | |
70 | + kfree(key); | |
72 | 71 | } |
73 | 72 | |
74 | 73 | static void expkey_request(struct cache_detail *cd, |
... | ... | @@ -158,7 +157,7 @@ |
158 | 157 | set_bit(CACHE_NEGATIVE, &key.h.flags); |
159 | 158 | ek = svc_expkey_update(&key, ek); |
160 | 159 | if (ek) |
161 | - expkey_put(&ek->h, &svc_expkey_cache); | |
160 | + cache_put(&ek->h, &svc_expkey_cache); | |
162 | 161 | else err = -ENOMEM; |
163 | 162 | } else { |
164 | 163 | struct nameidata nd; |
... | ... | @@ -172,7 +171,7 @@ |
172 | 171 | |
173 | 172 | ek = svc_expkey_update(&key, ek); |
174 | 173 | if (ek) |
175 | - expkey_put(&ek->h, &svc_expkey_cache); | |
174 | + cache_put(&ek->h, &svc_expkey_cache); | |
176 | 175 | else |
177 | 176 | err = -ENOMEM; |
178 | 177 | path_release(&nd); |
179 | 178 | |
... | ... | @@ -318,15 +317,13 @@ |
318 | 317 | |
319 | 318 | static struct cache_head *export_table[EXPORT_HASHMAX]; |
320 | 319 | |
321 | -void svc_export_put(struct cache_head *item, struct cache_detail *cd) | |
320 | +static void svc_export_put(struct kref *ref) | |
322 | 321 | { |
323 | - if (cache_put(item, cd)) { | |
324 | - struct svc_export *exp = container_of(item, struct svc_export, h); | |
325 | - dput(exp->ex_dentry); | |
326 | - mntput(exp->ex_mnt); | |
327 | - auth_domain_put(exp->ex_client); | |
328 | - kfree(exp); | |
329 | - } | |
322 | + struct svc_export *exp = container_of(ref, struct svc_export, h.ref); | |
323 | + dput(exp->ex_dentry); | |
324 | + mntput(exp->ex_mnt); | |
325 | + auth_domain_put(exp->ex_client); | |
326 | + kfree(exp); | |
330 | 327 | } |
331 | 328 | |
332 | 329 | static void svc_export_request(struct cache_detail *cd, |
... | ... | @@ -633,7 +630,7 @@ |
633 | 630 | if (ek) |
634 | 631 | ek = svc_expkey_update(&key,ek); |
635 | 632 | if (ek) { |
636 | - expkey_put(&ek->h, &svc_expkey_cache); | |
633 | + cache_put(&ek->h, &svc_expkey_cache); | |
637 | 634 | return 0; |
638 | 635 | } |
639 | 636 | return -ENOMEM; |
... | ... | @@ -762,7 +759,7 @@ |
762 | 759 | ek = exp_get_fsid_key(exp->ex_client, exp->ex_fsid); |
763 | 760 | if (ek && !IS_ERR(ek)) { |
764 | 761 | ek->h.expiry_time = get_seconds()-1; |
765 | - expkey_put(&ek->h, &svc_expkey_cache); | |
762 | + cache_put(&ek->h, &svc_expkey_cache); | |
766 | 763 | } |
767 | 764 | svc_expkey_cache.nextcheck = get_seconds(); |
768 | 765 | } |
... | ... | @@ -800,7 +797,7 @@ |
800 | 797 | ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino); |
801 | 798 | if (ek && !IS_ERR(ek)) { |
802 | 799 | ek->h.expiry_time = get_seconds()-1; |
803 | - expkey_put(&ek->h, &svc_expkey_cache); | |
800 | + cache_put(&ek->h, &svc_expkey_cache); | |
804 | 801 | } |
805 | 802 | svc_expkey_cache.nextcheck = get_seconds(); |
806 | 803 | } |
... | ... | @@ -902,7 +899,7 @@ |
902 | 899 | if (exp) |
903 | 900 | exp_put(exp); |
904 | 901 | if (fsid_key && !IS_ERR(fsid_key)) |
905 | - expkey_put(&fsid_key->h, &svc_expkey_cache); | |
902 | + cache_put(&fsid_key->h, &svc_expkey_cache); | |
906 | 903 | if (clp) |
907 | 904 | auth_domain_put(clp); |
908 | 905 | path_release(&nd); |
... | ... | @@ -1030,7 +1027,7 @@ |
1030 | 1027 | return ERR_PTR(PTR_ERR(ek)); |
1031 | 1028 | |
1032 | 1029 | exp = exp_get_by_name(clp, ek->ek_mnt, ek->ek_dentry, reqp); |
1033 | - expkey_put(&ek->h, &svc_expkey_cache); | |
1030 | + cache_put(&ek->h, &svc_expkey_cache); | |
1034 | 1031 | |
1035 | 1032 | if (!exp || IS_ERR(exp)) |
1036 | 1033 | return ERR_PTR(PTR_ERR(exp)); |
... | ... | @@ -1068,7 +1065,7 @@ |
1068 | 1065 | else |
1069 | 1066 | rv = fh_compose(fhp, exp, |
1070 | 1067 | fsid_key->ek_dentry, NULL); |
1071 | - expkey_put(&fsid_key->h, &svc_expkey_cache); | |
1068 | + cache_put(&fsid_key->h, &svc_expkey_cache); | |
1072 | 1069 | return rv; |
1073 | 1070 | } |
1074 | 1071 | |
... | ... | @@ -1187,7 +1184,7 @@ |
1187 | 1184 | cache_get(&exp->h); |
1188 | 1185 | if (cache_check(&svc_export_cache, &exp->h, NULL)) |
1189 | 1186 | return 0; |
1190 | - if (cache_put(&exp->h, &svc_export_cache)) BUG(); | |
1187 | + cache_put(&exp->h, &svc_export_cache); | |
1191 | 1188 | return svc_export_show(m, &svc_export_cache, cp); |
1192 | 1189 | } |
1193 | 1190 |
fs/nfsd/nfs4idmap.c
... | ... | @@ -96,12 +96,10 @@ |
96 | 96 | } |
97 | 97 | |
98 | 98 | static void |
99 | -ent_put(struct cache_head *ch, struct cache_detail *cd) | |
99 | +ent_put(struct kref *ref) | |
100 | 100 | { |
101 | - if (cache_put(ch, cd)) { | |
102 | - struct ent *map = container_of(ch, struct ent, h); | |
103 | - kfree(map); | |
104 | - } | |
101 | + struct ent *map = container_of(ref, struct ent, h.ref); | |
102 | + kfree(map); | |
105 | 103 | } |
106 | 104 | |
107 | 105 | static struct cache_head * |
... | ... | @@ -270,7 +268,7 @@ |
270 | 268 | if (res == NULL) |
271 | 269 | goto out; |
272 | 270 | |
273 | - ent_put(&res->h, &idtoname_cache); | |
271 | + cache_put(&res->h, &idtoname_cache); | |
274 | 272 | |
275 | 273 | error = 0; |
276 | 274 | out: |
... | ... | @@ -433,7 +431,7 @@ |
433 | 431 | if (res == NULL) |
434 | 432 | goto out; |
435 | 433 | |
436 | - ent_put(&res->h, &nametoid_cache); | |
434 | + cache_put(&res->h, &nametoid_cache); | |
437 | 435 | error = 0; |
438 | 436 | out: |
439 | 437 | kfree(buf1); |
... | ... | @@ -562,7 +560,7 @@ |
562 | 560 | goto out_put; |
563 | 561 | return 0; |
564 | 562 | out_put: |
565 | - ent_put(&(*item)->h, detail); | |
563 | + cache_put(&(*item)->h, detail); | |
566 | 564 | out_err: |
567 | 565 | *item = NULL; |
568 | 566 | return ret; |
... | ... | @@ -613,7 +611,7 @@ |
613 | 611 | if (ret) |
614 | 612 | return ret; |
615 | 613 | *id = item->id; |
616 | - ent_put(&item->h, &nametoid_cache); | |
614 | + cache_put(&item->h, &nametoid_cache); | |
617 | 615 | return 0; |
618 | 616 | } |
619 | 617 | |
... | ... | @@ -635,7 +633,7 @@ |
635 | 633 | ret = strlen(item->name); |
636 | 634 | BUG_ON(ret > IDMAP_NAMESZ); |
637 | 635 | memcpy(name, item->name, ret); |
638 | - ent_put(&item->h, &idtoname_cache); | |
636 | + cache_put(&item->h, &idtoname_cache); | |
639 | 637 | return ret; |
640 | 638 | } |
641 | 639 |
fs/nfsd/nfsfh.c
include/linux/nfsd/export.h
... | ... | @@ -102,13 +102,11 @@ |
102 | 102 | int exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp, struct cache_req *creq); |
103 | 103 | int nfserrno(int errno); |
104 | 104 | |
105 | -extern void expkey_put(struct cache_head *item, struct cache_detail *cd); | |
106 | -extern void svc_export_put(struct cache_head *item, struct cache_detail *cd); | |
107 | 105 | extern struct cache_detail svc_export_cache, svc_expkey_cache; |
108 | 106 | |
109 | 107 | static inline void exp_put(struct svc_export *exp) |
110 | 108 | { |
111 | - svc_export_put(&exp->h, &svc_export_cache); | |
109 | + cache_put(&exp->h, &svc_export_cache); | |
112 | 110 | } |
113 | 111 | |
114 | 112 | static inline void exp_get(struct svc_export *exp) |
include/linux/sunrpc/cache.h
... | ... | @@ -50,7 +50,7 @@ |
50 | 50 | time_t last_refresh; /* If CACHE_PENDING, this is when upcall |
51 | 51 | * was sent, else this is when update was received |
52 | 52 | */ |
53 | - atomic_t refcnt; | |
53 | + struct kref ref; | |
54 | 54 | unsigned long flags; |
55 | 55 | }; |
56 | 56 | #define CACHE_VALID 0 /* Entry contains valid data */ |
... | ... | @@ -68,8 +68,7 @@ |
68 | 68 | atomic_t inuse; /* active user-space update or lookup */ |
69 | 69 | |
70 | 70 | char *name; |
71 | - void (*cache_put)(struct cache_head *, | |
72 | - struct cache_detail*); | |
71 | + void (*cache_put)(struct kref *); | |
73 | 72 | |
74 | 73 | void (*cache_request)(struct cache_detail *cd, |
75 | 74 | struct cache_head *h, |
76 | 75 | |
77 | 76 | |
78 | 77 | |
... | ... | @@ -151,17 +150,17 @@ |
151 | 150 | |
152 | 151 | static inline struct cache_head *cache_get(struct cache_head *h) |
153 | 152 | { |
154 | - atomic_inc(&h->refcnt); | |
153 | + kref_get(&h->ref); | |
155 | 154 | return h; |
156 | 155 | } |
157 | 156 | |
158 | 157 | |
159 | -static inline int cache_put(struct cache_head *h, struct cache_detail *cd) | |
158 | +static inline void cache_put(struct cache_head *h, struct cache_detail *cd) | |
160 | 159 | { |
161 | - if (atomic_read(&h->refcnt) <= 2 && | |
160 | + if (atomic_read(&h->ref.refcount) <= 2 && | |
162 | 161 | h->expiry_time < cd->nextcheck) |
163 | 162 | cd->nextcheck = h->expiry_time; |
164 | - return atomic_dec_and_test(&h->refcnt); | |
163 | + kref_put(&h->ref, cd->cache_put); | |
165 | 164 | } |
166 | 165 | |
167 | 166 | extern void cache_init(struct cache_head *h); |
net/sunrpc/auth_gss/svcauth_gss.c
... | ... | @@ -89,13 +89,11 @@ |
89 | 89 | kfree(rsii->out_token.data); |
90 | 90 | } |
91 | 91 | |
92 | -static void rsi_put(struct cache_head *item, struct cache_detail *cd) | |
92 | +static void rsi_put(struct kref *ref) | |
93 | 93 | { |
94 | - struct rsi *rsii = container_of(item, struct rsi, h); | |
95 | - if (cache_put(item, cd)) { | |
96 | - rsi_free(rsii); | |
97 | - kfree(rsii); | |
98 | - } | |
94 | + struct rsi *rsii = container_of(ref, struct rsi, h.ref); | |
95 | + rsi_free(rsii); | |
96 | + kfree(rsii); | |
99 | 97 | } |
100 | 98 | |
101 | 99 | static inline int rsi_hash(struct rsi *item) |
... | ... | @@ -267,7 +265,7 @@ |
267 | 265 | out: |
268 | 266 | rsi_free(&rsii); |
269 | 267 | if (rsip) |
270 | - rsi_put(&rsip->h, &rsi_cache); | |
268 | + cache_put(&rsip->h, &rsi_cache); | |
271 | 269 | else |
272 | 270 | status = -ENOMEM; |
273 | 271 | return status; |
274 | 272 | |
275 | 273 | |
... | ... | @@ -357,14 +355,12 @@ |
357 | 355 | put_group_info(rsci->cred.cr_group_info); |
358 | 356 | } |
359 | 357 | |
360 | -static void rsc_put(struct cache_head *item, struct cache_detail *cd) | |
358 | +static void rsc_put(struct kref *ref) | |
361 | 359 | { |
362 | - struct rsc *rsci = container_of(item, struct rsc, h); | |
360 | + struct rsc *rsci = container_of(ref, struct rsc, h.ref); | |
363 | 361 | |
364 | - if (cache_put(item, cd)) { | |
365 | - rsc_free(rsci); | |
366 | - kfree(rsci); | |
367 | - } | |
362 | + rsc_free(rsci); | |
363 | + kfree(rsci); | |
368 | 364 | } |
369 | 365 | |
370 | 366 | static inline int |
... | ... | @@ -509,7 +505,7 @@ |
509 | 505 | out: |
510 | 506 | rsc_free(&rsci); |
511 | 507 | if (rscp) |
512 | - rsc_put(&rscp->h, &rsc_cache); | |
508 | + cache_put(&rscp->h, &rsc_cache); | |
513 | 509 | else |
514 | 510 | status = -ENOMEM; |
515 | 511 | return status; |
... | ... | @@ -1076,7 +1072,7 @@ |
1076 | 1072 | ret = SVC_DROP; |
1077 | 1073 | out: |
1078 | 1074 | if (rsci) |
1079 | - rsc_put(&rsci->h, &rsc_cache); | |
1075 | + cache_put(&rsci->h, &rsc_cache); | |
1080 | 1076 | return ret; |
1081 | 1077 | } |
1082 | 1078 | |
... | ... | @@ -1168,7 +1164,7 @@ |
1168 | 1164 | put_group_info(rqstp->rq_cred.cr_group_info); |
1169 | 1165 | rqstp->rq_cred.cr_group_info = NULL; |
1170 | 1166 | if (gsd->rsci) |
1171 | - rsc_put(&gsd->rsci->h, &rsc_cache); | |
1167 | + cache_put(&gsd->rsci->h, &rsc_cache); | |
1172 | 1168 | gsd->rsci = NULL; |
1173 | 1169 | |
1174 | 1170 | return stat; |
net/sunrpc/cache.c
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | time_t now = get_seconds(); |
43 | 43 | h->next = NULL; |
44 | 44 | h->flags = 0; |
45 | - atomic_set(&h->refcnt, 1); | |
45 | + kref_init(&h->ref); | |
46 | 46 | h->expiry_time = now + CACHE_NEW_EXPIRY; |
47 | 47 | h->last_refresh = now; |
48 | 48 | } |
... | ... | @@ -81,7 +81,7 @@ |
81 | 81 | if (detail->match(tmp, key)) { |
82 | 82 | cache_get(tmp); |
83 | 83 | write_unlock(&detail->hash_lock); |
84 | - detail->cache_put(new, detail); | |
84 | + cache_put(new, detail); | |
85 | 85 | return tmp; |
86 | 86 | } |
87 | 87 | } |
... | ... | @@ -145,7 +145,7 @@ |
145 | 145 | /* We need to insert a new entry */ |
146 | 146 | tmp = detail->alloc(); |
147 | 147 | if (!tmp) { |
148 | - detail->cache_put(old, detail); | |
148 | + cache_put(old, detail); | |
149 | 149 | return NULL; |
150 | 150 | } |
151 | 151 | cache_init(tmp); |
... | ... | @@ -165,7 +165,7 @@ |
165 | 165 | write_unlock(&detail->hash_lock); |
166 | 166 | cache_fresh_unlocked(tmp, detail, is_new); |
167 | 167 | cache_fresh_unlocked(old, detail, 0); |
168 | - detail->cache_put(old, detail); | |
168 | + cache_put(old, detail); | |
169 | 169 | return tmp; |
170 | 170 | } |
171 | 171 | EXPORT_SYMBOL(sunrpc_cache_update); |
... | ... | @@ -234,7 +234,7 @@ |
234 | 234 | cache_defer_req(rqstp, h); |
235 | 235 | |
236 | 236 | if (rv) |
237 | - detail->cache_put(h, detail); | |
237 | + cache_put(h, detail); | |
238 | 238 | return rv; |
239 | 239 | } |
240 | 240 | |
... | ... | @@ -431,7 +431,7 @@ |
431 | 431 | if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) |
432 | 432 | queue_loose(current_detail, ch); |
433 | 433 | |
434 | - if (atomic_read(&ch->refcnt) == 1) | |
434 | + if (atomic_read(&ch->ref.refcount) == 1) | |
435 | 435 | break; |
436 | 436 | } |
437 | 437 | if (ch) { |
... | ... | @@ -446,7 +446,7 @@ |
446 | 446 | current_index ++; |
447 | 447 | spin_unlock(&cache_list_lock); |
448 | 448 | if (ch) |
449 | - d->cache_put(ch, d); | |
449 | + cache_put(ch, d); | |
450 | 450 | } else |
451 | 451 | spin_unlock(&cache_list_lock); |
452 | 452 | |
... | ... | @@ -723,7 +723,7 @@ |
723 | 723 | !test_bit(CACHE_PENDING, &rq->item->flags)) { |
724 | 724 | list_del(&rq->q.list); |
725 | 725 | spin_unlock(&queue_lock); |
726 | - cd->cache_put(rq->item, cd); | |
726 | + cache_put(rq->item, cd); | |
727 | 727 | kfree(rq->buf); |
728 | 728 | kfree(rq); |
729 | 729 | } else |
... | ... | @@ -906,7 +906,7 @@ |
906 | 906 | continue; |
907 | 907 | list_del(&cr->q.list); |
908 | 908 | spin_unlock(&queue_lock); |
909 | - detail->cache_put(cr->item, detail); | |
909 | + cache_put(cr->item, detail); | |
910 | 910 | kfree(cr->buf); |
911 | 911 | kfree(cr); |
912 | 912 | return; |
... | ... | @@ -1192,7 +1192,7 @@ |
1192 | 1192 | |
1193 | 1193 | ifdebug(CACHE) |
1194 | 1194 | seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n", |
1195 | - cp->expiry_time, atomic_read(&cp->refcnt), cp->flags); | |
1195 | + cp->expiry_time, atomic_read(&cp->ref.refcount), cp->flags); | |
1196 | 1196 | cache_get(cp); |
1197 | 1197 | if (cache_check(cd, cp, NULL)) |
1198 | 1198 | /* cache_check does a cache_put on failure */ |
net/sunrpc/svcauth_unix.c
... | ... | @@ -84,15 +84,15 @@ |
84 | 84 | }; |
85 | 85 | static struct cache_head *ip_table[IP_HASHMAX]; |
86 | 86 | |
87 | -static void ip_map_put(struct cache_head *item, struct cache_detail *cd) | |
87 | +static void ip_map_put(struct kref *kref) | |
88 | 88 | { |
89 | + struct cache_head *item = container_of(kref, struct cache_head, ref); | |
89 | 90 | struct ip_map *im = container_of(item, struct ip_map,h); |
90 | - if (cache_put(item, cd)) { | |
91 | - if (test_bit(CACHE_VALID, &item->flags) && | |
92 | - !test_bit(CACHE_NEGATIVE, &item->flags)) | |
93 | - auth_domain_put(&im->m_client->h); | |
94 | - kfree(im); | |
95 | - } | |
91 | + | |
92 | + if (test_bit(CACHE_VALID, &item->flags) && | |
93 | + !test_bit(CACHE_NEGATIVE, &item->flags)) | |
94 | + auth_domain_put(&im->m_client->h); | |
95 | + kfree(im); | |
96 | 96 | } |
97 | 97 | |
98 | 98 | #if IP_HASHBITS == 8 |
... | ... | @@ -315,7 +315,7 @@ |
315 | 315 | hash_ip((unsigned long)ipm->m_addr.s_addr)); |
316 | 316 | if (!ch) |
317 | 317 | return -ENOMEM; |
318 | - ip_map_put(ch, &ip_map_cache); | |
318 | + cache_put(ch, &ip_map_cache); | |
319 | 319 | return 0; |
320 | 320 | } |
321 | 321 | |
... | ... | @@ -369,7 +369,7 @@ |
369 | 369 | rv = &ipm->m_client->h; |
370 | 370 | kref_get(&rv->ref); |
371 | 371 | } |
372 | - ip_map_put(&ipm->h, &ip_map_cache); | |
372 | + cache_put(&ipm->h, &ip_map_cache); | |
373 | 373 | return rv; |
374 | 374 | } |
375 | 375 | |
... | ... | @@ -403,7 +403,7 @@ |
403 | 403 | case 0: |
404 | 404 | rqstp->rq_client = &ipm->m_client->h; |
405 | 405 | kref_get(&rqstp->rq_client->ref); |
406 | - ip_map_put(&ipm->h, &ip_map_cache); | |
406 | + cache_put(&ipm->h, &ip_map_cache); | |
407 | 407 | break; |
408 | 408 | } |
409 | 409 | return SVC_OK; |