aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/cache.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-28 21:02:55 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-28 21:02:55 -0500
commitb6669737d3db7df79fad07180837c23dbe581db5 (patch)
tree671a9d13fe5ab00d6a3c7c5c5c466802ca96d38a /net/sunrpc/cache.c
parent1cf0209c431fa7790253c532039d53b0773193aa (diff)
parentdc107402ae06286a9ed33c32daf3f35514a7cb8d (diff)
Merge branch 'for-3.9' of git://linux-nfs.org/~bfields/linux
Pull nfsd changes from J Bruce Fields: "Miscellaneous bugfixes, plus: - An overhaul of the DRC cache by Jeff Layton. The main effect is just to make it larger. This decreases the chances of intermittent errors especially in the UDP case. But we'll need to watch for any reports of performance regressions. - Containerized nfsd: with some limitations, we now support per-container nfs-service, thanks to extensive work from Stanislav Kinsbursky over the last year." Some notes about conflicts, since there were *two* non-data semantic conflicts here: - idr_remove_all() had been added by a memory leak fix, but has since become deprecated since idr_destroy() does it for us now. - xs_local_connect() had been added by this branch to make AF_LOCAL connections be synchronous, but in the meantime Trond had changed the calling convention in order to avoid a RCU dereference. There were a couple of more obvious actual source-level conflicts due to the hlist traversal changes and one just due to code changes next to each other, but those were trivial. * 'for-3.9' of git://linux-nfs.org/~bfields/linux: (49 commits) SUNRPC: make AF_LOCAL connect synchronous nfsd: fix compiler warning about ambiguous types in nfsd_cache_csum svcrpc: fix rpc server shutdown races svcrpc: make svc_age_temp_xprts enqueue under sv_lock lockd: nlmclnt_reclaim(): avoid stack overflow nfsd: enable NFSv4 state in containers nfsd: disable usermode helper client tracker in container nfsd: use proper net while reading "exports" file nfsd: containerize NFSd filesystem nfsd: fix comments on nfsd_cache_lookup SUNRPC: move cache_detail->cache_request callback call to cache_read() SUNRPC: remove "cache_request" argument in sunrpc_cache_pipe_upcall() function SUNRPC: rework cache upcall logic SUNRPC: introduce cache_detail->cache_request callback NFS: simplify and clean cache library NFS: use SUNRPC cache creation and destruction helper for DNS cache nfsd4: free_stid can be static nfsd: keep a checksum of the first 256 bytes of request sunrpc: trim off trailing checksum before returning decrypted or integrity authenticated buffer sunrpc: fix comment in struct xdr_buf definition ...
Diffstat (limited to 'net/sunrpc/cache.c')
-rw-r--r--net/sunrpc/cache.c51
1 files changed, 29 insertions, 22 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 39a4112faf54..25d58e766014 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -196,9 +196,9 @@ EXPORT_SYMBOL_GPL(sunrpc_cache_update);
196 196
197static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h) 197static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h)
198{ 198{
199 if (!cd->cache_upcall) 199 if (cd->cache_upcall)
200 return -EINVAL; 200 return cd->cache_upcall(cd, h);
201 return cd->cache_upcall(cd, h); 201 return sunrpc_cache_pipe_upcall(cd, h);
202} 202}
203 203
204static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h) 204static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h)
@@ -750,6 +750,18 @@ struct cache_reader {
750 int offset; /* if non-0, we have a refcnt on next request */ 750 int offset; /* if non-0, we have a refcnt on next request */
751}; 751};
752 752
753static int cache_request(struct cache_detail *detail,
754 struct cache_request *crq)
755{
756 char *bp = crq->buf;
757 int len = PAGE_SIZE;
758
759 detail->cache_request(detail, crq->item, &bp, &len);
760 if (len < 0)
761 return -EAGAIN;
762 return PAGE_SIZE - len;
763}
764
753static ssize_t cache_read(struct file *filp, char __user *buf, size_t count, 765static ssize_t cache_read(struct file *filp, char __user *buf, size_t count,
754 loff_t *ppos, struct cache_detail *cd) 766 loff_t *ppos, struct cache_detail *cd)
755{ 767{
@@ -784,6 +796,13 @@ static ssize_t cache_read(struct file *filp, char __user *buf, size_t count,
784 rq->readers++; 796 rq->readers++;
785 spin_unlock(&queue_lock); 797 spin_unlock(&queue_lock);
786 798
799 if (rq->len == 0) {
800 err = cache_request(cd, rq);
801 if (err < 0)
802 goto out;
803 rq->len = err;
804 }
805
787 if (rp->offset == 0 && !test_bit(CACHE_PENDING, &rq->item->flags)) { 806 if (rp->offset == 0 && !test_bit(CACHE_PENDING, &rq->item->flags)) {
788 err = -EAGAIN; 807 err = -EAGAIN;
789 spin_lock(&queue_lock); 808 spin_lock(&queue_lock);
@@ -1140,17 +1159,14 @@ static bool cache_listeners_exist(struct cache_detail *detail)
1140 * 1159 *
1141 * Each request is at most one page long. 1160 * Each request is at most one page long.
1142 */ 1161 */
1143int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h, 1162int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h)
1144 void (*cache_request)(struct cache_detail *,
1145 struct cache_head *,
1146 char **,
1147 int *))
1148{ 1163{
1149 1164
1150 char *buf; 1165 char *buf;
1151 struct cache_request *crq; 1166 struct cache_request *crq;
1152 char *bp; 1167
1153 int len; 1168 if (!detail->cache_request)
1169 return -EINVAL;
1154 1170
1155 if (!cache_listeners_exist(detail)) { 1171 if (!cache_listeners_exist(detail)) {
1156 warn_no_listener(detail); 1172 warn_no_listener(detail);
@@ -1167,19 +1183,10 @@ int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h,
1167 return -EAGAIN; 1183 return -EAGAIN;
1168 } 1184 }
1169 1185
1170 bp = buf; len = PAGE_SIZE;
1171
1172 cache_request(detail, h, &bp, &len);
1173
1174 if (len < 0) {
1175 kfree(buf);
1176 kfree(crq);
1177 return -EAGAIN;
1178 }
1179 crq->q.reader = 0; 1186 crq->q.reader = 0;
1180 crq->item = cache_get(h); 1187 crq->item = cache_get(h);
1181 crq->buf = buf; 1188 crq->buf = buf;
1182 crq->len = PAGE_SIZE - len; 1189 crq->len = 0;
1183 crq->readers = 0; 1190 crq->readers = 0;
1184 spin_lock(&queue_lock); 1191 spin_lock(&queue_lock);
1185 list_add_tail(&crq->q.list, &detail->queue); 1192 list_add_tail(&crq->q.list, &detail->queue);
@@ -1605,7 +1612,7 @@ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
1605 if (p == NULL) 1612 if (p == NULL)
1606 goto out_nomem; 1613 goto out_nomem;
1607 1614
1608 if (cd->cache_upcall || cd->cache_parse) { 1615 if (cd->cache_request || cd->cache_parse) {
1609 p = proc_create_data("channel", S_IFREG|S_IRUSR|S_IWUSR, 1616 p = proc_create_data("channel", S_IFREG|S_IRUSR|S_IWUSR,
1610 cd->u.procfs.proc_ent, 1617 cd->u.procfs.proc_ent,
1611 &cache_file_operations_procfs, cd); 1618 &cache_file_operations_procfs, cd);
@@ -1614,7 +1621,7 @@ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
1614 goto out_nomem; 1621 goto out_nomem;
1615 } 1622 }
1616 if (cd->cache_show) { 1623 if (cd->cache_show) {
1617 p = proc_create_data("content", S_IFREG|S_IRUSR|S_IWUSR, 1624 p = proc_create_data("content", S_IFREG|S_IRUSR,
1618 cd->u.procfs.proc_ent, 1625 cd->u.procfs.proc_ent,
1619 &content_file_operations_procfs, cd); 1626 &content_file_operations_procfs, cd);
1620 cd->u.procfs.content_ent = p; 1627 cd->u.procfs.content_ent = p;