aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/cache.c')
-rw-r--r--net/sunrpc/cache.c305
1 files changed, 205 insertions, 100 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 2b06410e584e..e433e7580e27 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -28,21 +28,21 @@
28#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/pagemap.h> 30#include <linux/pagemap.h>
31#include <linux/smp_lock.h>
32#include <asm/ioctls.h> 31#include <asm/ioctls.h>
33#include <linux/sunrpc/types.h> 32#include <linux/sunrpc/types.h>
34#include <linux/sunrpc/cache.h> 33#include <linux/sunrpc/cache.h>
35#include <linux/sunrpc/stats.h> 34#include <linux/sunrpc/stats.h>
36#include <linux/sunrpc/rpc_pipe_fs.h> 35#include <linux/sunrpc/rpc_pipe_fs.h>
36#include "netns.h"
37 37
38#define RPCDBG_FACILITY RPCDBG_CACHE 38#define RPCDBG_FACILITY RPCDBG_CACHE
39 39
40static int cache_defer_req(struct cache_req *req, struct cache_head *item); 40static void cache_defer_req(struct cache_req *req, struct cache_head *item);
41static void cache_revisit_request(struct cache_head *item); 41static void cache_revisit_request(struct cache_head *item);
42 42
43static void cache_init(struct cache_head *h) 43static void cache_init(struct cache_head *h)
44{ 44{
45 time_t now = get_seconds(); 45 time_t now = seconds_since_boot();
46 h->next = NULL; 46 h->next = NULL;
47 h->flags = 0; 47 h->flags = 0;
48 kref_init(&h->ref); 48 kref_init(&h->ref);
@@ -52,7 +52,7 @@ static void cache_init(struct cache_head *h)
52 52
53static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h) 53static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h)
54{ 54{
55 return (h->expiry_time < get_seconds()) || 55 return (h->expiry_time < seconds_since_boot()) ||
56 (detail->flush_time > h->last_refresh); 56 (detail->flush_time > h->last_refresh);
57} 57}
58 58
@@ -127,7 +127,7 @@ static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch);
127static void cache_fresh_locked(struct cache_head *head, time_t expiry) 127static void cache_fresh_locked(struct cache_head *head, time_t expiry)
128{ 128{
129 head->expiry_time = expiry; 129 head->expiry_time = expiry;
130 head->last_refresh = get_seconds(); 130 head->last_refresh = seconds_since_boot();
131 set_bit(CACHE_VALID, &head->flags); 131 set_bit(CACHE_VALID, &head->flags);
132} 132}
133 133
@@ -238,7 +238,7 @@ int cache_check(struct cache_detail *detail,
238 238
239 /* now see if we want to start an upcall */ 239 /* now see if we want to start an upcall */
240 refresh_age = (h->expiry_time - h->last_refresh); 240 refresh_age = (h->expiry_time - h->last_refresh);
241 age = get_seconds() - h->last_refresh; 241 age = seconds_since_boot() - h->last_refresh;
242 242
243 if (rqstp == NULL) { 243 if (rqstp == NULL) {
244 if (rv == -EAGAIN) 244 if (rv == -EAGAIN)
@@ -253,7 +253,7 @@ int cache_check(struct cache_detail *detail,
253 cache_revisit_request(h); 253 cache_revisit_request(h);
254 if (rv == -EAGAIN) { 254 if (rv == -EAGAIN) {
255 set_bit(CACHE_NEGATIVE, &h->flags); 255 set_bit(CACHE_NEGATIVE, &h->flags);
256 cache_fresh_locked(h, get_seconds()+CACHE_NEW_EXPIRY); 256 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
257 cache_fresh_unlocked(h, detail); 257 cache_fresh_unlocked(h, detail);
258 rv = -ENOENT; 258 rv = -ENOENT;
259 } 259 }
@@ -268,7 +268,8 @@ int cache_check(struct cache_detail *detail,
268 } 268 }
269 269
270 if (rv == -EAGAIN) { 270 if (rv == -EAGAIN) {
271 if (cache_defer_req(rqstp, h) < 0) { 271 cache_defer_req(rqstp, h);
272 if (!test_bit(CACHE_PENDING, &h->flags)) {
272 /* Request is not deferred */ 273 /* Request is not deferred */
273 rv = cache_is_valid(detail, h); 274 rv = cache_is_valid(detail, h);
274 if (rv == -EAGAIN) 275 if (rv == -EAGAIN)
@@ -388,11 +389,11 @@ static int cache_clean(void)
388 return -1; 389 return -1;
389 } 390 }
390 current_detail = list_entry(next, struct cache_detail, others); 391 current_detail = list_entry(next, struct cache_detail, others);
391 if (current_detail->nextcheck > get_seconds()) 392 if (current_detail->nextcheck > seconds_since_boot())
392 current_index = current_detail->hash_size; 393 current_index = current_detail->hash_size;
393 else { 394 else {
394 current_index = 0; 395 current_index = 0;
395 current_detail->nextcheck = get_seconds()+30*60; 396 current_detail->nextcheck = seconds_since_boot()+30*60;
396 } 397 }
397 } 398 }
398 399
@@ -477,7 +478,7 @@ EXPORT_SYMBOL_GPL(cache_flush);
477void cache_purge(struct cache_detail *detail) 478void cache_purge(struct cache_detail *detail)
478{ 479{
479 detail->flush_time = LONG_MAX; 480 detail->flush_time = LONG_MAX;
480 detail->nextcheck = get_seconds(); 481 detail->nextcheck = seconds_since_boot();
481 cache_flush(); 482 cache_flush();
482 detail->flush_time = 1; 483 detail->flush_time = 1;
483} 484}
@@ -506,81 +507,155 @@ EXPORT_SYMBOL_GPL(cache_purge);
506 507
507static DEFINE_SPINLOCK(cache_defer_lock); 508static DEFINE_SPINLOCK(cache_defer_lock);
508static LIST_HEAD(cache_defer_list); 509static LIST_HEAD(cache_defer_list);
509static struct list_head cache_defer_hash[DFR_HASHSIZE]; 510static struct hlist_head cache_defer_hash[DFR_HASHSIZE];
510static int cache_defer_cnt; 511static int cache_defer_cnt;
511 512
512static int cache_defer_req(struct cache_req *req, struct cache_head *item) 513static void __unhash_deferred_req(struct cache_deferred_req *dreq)
514{
515 hlist_del_init(&dreq->hash);
516 if (!list_empty(&dreq->recent)) {
517 list_del_init(&dreq->recent);
518 cache_defer_cnt--;
519 }
520}
521
522static void __hash_deferred_req(struct cache_deferred_req *dreq, struct cache_head *item)
513{ 523{
514 struct cache_deferred_req *dreq, *discard;
515 int hash = DFR_HASH(item); 524 int hash = DFR_HASH(item);
516 525
517 if (cache_defer_cnt >= DFR_MAX) { 526 INIT_LIST_HEAD(&dreq->recent);
518 /* too much in the cache, randomly drop this one, 527 hlist_add_head(&dreq->hash, &cache_defer_hash[hash]);
519 * or continue and drop the oldest below 528}
520 */ 529
521 if (net_random()&1) 530static void setup_deferral(struct cache_deferred_req *dreq,
522 return -ENOMEM; 531 struct cache_head *item,
523 } 532 int count_me)
524 dreq = req->defer(req); 533{
525 if (dreq == NULL)
526 return -ENOMEM;
527 534
528 dreq->item = item; 535 dreq->item = item;
529 536
530 spin_lock(&cache_defer_lock); 537 spin_lock(&cache_defer_lock);
531 538
532 list_add(&dreq->recent, &cache_defer_list); 539 __hash_deferred_req(dreq, item);
533 540
534 if (cache_defer_hash[hash].next == NULL) 541 if (count_me) {
535 INIT_LIST_HEAD(&cache_defer_hash[hash]); 542 cache_defer_cnt++;
536 list_add(&dreq->hash, &cache_defer_hash[hash]); 543 list_add(&dreq->recent, &cache_defer_list);
537
538 /* it is in, now maybe clean up */
539 discard = NULL;
540 if (++cache_defer_cnt > DFR_MAX) {
541 discard = list_entry(cache_defer_list.prev,
542 struct cache_deferred_req, recent);
543 list_del_init(&discard->recent);
544 list_del_init(&discard->hash);
545 cache_defer_cnt--;
546 } 544 }
545
547 spin_unlock(&cache_defer_lock); 546 spin_unlock(&cache_defer_lock);
548 547
548}
549
550struct thread_deferred_req {
551 struct cache_deferred_req handle;
552 struct completion completion;
553};
554
555static void cache_restart_thread(struct cache_deferred_req *dreq, int too_many)
556{
557 struct thread_deferred_req *dr =
558 container_of(dreq, struct thread_deferred_req, handle);
559 complete(&dr->completion);
560}
561
562static void cache_wait_req(struct cache_req *req, struct cache_head *item)
563{
564 struct thread_deferred_req sleeper;
565 struct cache_deferred_req *dreq = &sleeper.handle;
566
567 sleeper.completion = COMPLETION_INITIALIZER_ONSTACK(sleeper.completion);
568 dreq->revisit = cache_restart_thread;
569
570 setup_deferral(dreq, item, 0);
571
572 if (!test_bit(CACHE_PENDING, &item->flags) ||
573 wait_for_completion_interruptible_timeout(
574 &sleeper.completion, req->thread_wait) <= 0) {
575 /* The completion wasn't completed, so we need
576 * to clean up
577 */
578 spin_lock(&cache_defer_lock);
579 if (!hlist_unhashed(&sleeper.handle.hash)) {
580 __unhash_deferred_req(&sleeper.handle);
581 spin_unlock(&cache_defer_lock);
582 } else {
583 /* cache_revisit_request already removed
584 * this from the hash table, but hasn't
585 * called ->revisit yet. It will very soon
586 * and we need to wait for it.
587 */
588 spin_unlock(&cache_defer_lock);
589 wait_for_completion(&sleeper.completion);
590 }
591 }
592}
593
594static void cache_limit_defers(void)
595{
596 /* Make sure we haven't exceed the limit of allowed deferred
597 * requests.
598 */
599 struct cache_deferred_req *discard = NULL;
600
601 if (cache_defer_cnt <= DFR_MAX)
602 return;
603
604 spin_lock(&cache_defer_lock);
605
606 /* Consider removing either the first or the last */
607 if (cache_defer_cnt > DFR_MAX) {
608 if (net_random() & 1)
609 discard = list_entry(cache_defer_list.next,
610 struct cache_deferred_req, recent);
611 else
612 discard = list_entry(cache_defer_list.prev,
613 struct cache_deferred_req, recent);
614 __unhash_deferred_req(discard);
615 }
616 spin_unlock(&cache_defer_lock);
549 if (discard) 617 if (discard)
550 /* there was one too many */
551 discard->revisit(discard, 1); 618 discard->revisit(discard, 1);
619}
552 620
553 if (!test_bit(CACHE_PENDING, &item->flags)) { 621static void cache_defer_req(struct cache_req *req, struct cache_head *item)
554 /* must have just been validated... */ 622{
555 cache_revisit_request(item); 623 struct cache_deferred_req *dreq;
556 return -EAGAIN; 624
625 if (req->thread_wait) {
626 cache_wait_req(req, item);
627 if (!test_bit(CACHE_PENDING, &item->flags))
628 return;
557 } 629 }
558 return 0; 630 dreq = req->defer(req);
631 if (dreq == NULL)
632 return;
633 setup_deferral(dreq, item, 1);
634 if (!test_bit(CACHE_PENDING, &item->flags))
635 /* Bit could have been cleared before we managed to
636 * set up the deferral, so need to revisit just in case
637 */
638 cache_revisit_request(item);
639
640 cache_limit_defers();
559} 641}
560 642
561static void cache_revisit_request(struct cache_head *item) 643static void cache_revisit_request(struct cache_head *item)
562{ 644{
563 struct cache_deferred_req *dreq; 645 struct cache_deferred_req *dreq;
564 struct list_head pending; 646 struct list_head pending;
565 647 struct hlist_node *lp, *tmp;
566 struct list_head *lp;
567 int hash = DFR_HASH(item); 648 int hash = DFR_HASH(item);
568 649
569 INIT_LIST_HEAD(&pending); 650 INIT_LIST_HEAD(&pending);
570 spin_lock(&cache_defer_lock); 651 spin_lock(&cache_defer_lock);
571 652
572 lp = cache_defer_hash[hash].next; 653 hlist_for_each_entry_safe(dreq, lp, tmp, &cache_defer_hash[hash], hash)
573 if (lp) { 654 if (dreq->item == item) {
574 while (lp != &cache_defer_hash[hash]) { 655 __unhash_deferred_req(dreq);
575 dreq = list_entry(lp, struct cache_deferred_req, hash); 656 list_add(&dreq->recent, &pending);
576 lp = lp->next;
577 if (dreq->item == item) {
578 list_del_init(&dreq->hash);
579 list_move(&dreq->recent, &pending);
580 cache_defer_cnt--;
581 }
582 } 657 }
583 } 658
584 spin_unlock(&cache_defer_lock); 659 spin_unlock(&cache_defer_lock);
585 660
586 while (!list_empty(&pending)) { 661 while (!list_empty(&pending)) {
@@ -601,9 +676,8 @@ void cache_clean_deferred(void *owner)
601 676
602 list_for_each_entry_safe(dreq, tmp, &cache_defer_list, recent) { 677 list_for_each_entry_safe(dreq, tmp, &cache_defer_list, recent) {
603 if (dreq->owner == owner) { 678 if (dreq->owner == owner) {
604 list_del_init(&dreq->hash); 679 __unhash_deferred_req(dreq);
605 list_move(&dreq->recent, &pending); 680 list_add(&dreq->recent, &pending);
606 cache_defer_cnt--;
607 } 681 }
608 } 682 }
609 spin_unlock(&cache_defer_lock); 683 spin_unlock(&cache_defer_lock);
@@ -902,7 +976,7 @@ static int cache_release(struct inode *inode, struct file *filp,
902 filp->private_data = NULL; 976 filp->private_data = NULL;
903 kfree(rp); 977 kfree(rp);
904 978
905 cd->last_close = get_seconds(); 979 cd->last_close = seconds_since_boot();
906 atomic_dec(&cd->readers); 980 atomic_dec(&cd->readers);
907 } 981 }
908 module_put(cd->owner); 982 module_put(cd->owner);
@@ -1015,6 +1089,23 @@ static void warn_no_listener(struct cache_detail *detail)
1015 } 1089 }
1016} 1090}
1017 1091
1092static bool cache_listeners_exist(struct cache_detail *detail)
1093{
1094 if (atomic_read(&detail->readers))
1095 return true;
1096 if (detail->last_close == 0)
1097 /* This cache was never opened */
1098 return false;
1099 if (detail->last_close < seconds_since_boot() - 30)
1100 /*
1101 * We allow for the possibility that someone might
1102 * restart a userspace daemon without restarting the
1103 * server; but after 30 seconds, we give up.
1104 */
1105 return false;
1106 return true;
1107}
1108
1018/* 1109/*
1019 * register an upcall request to user-space and queue it up for read() by the 1110 * register an upcall request to user-space and queue it up for read() by the
1020 * upcall daemon. 1111 * upcall daemon.
@@ -1033,10 +1124,9 @@ int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h,
1033 char *bp; 1124 char *bp;
1034 int len; 1125 int len;
1035 1126
1036 if (atomic_read(&detail->readers) == 0 && 1127 if (!cache_listeners_exist(detail)) {
1037 detail->last_close < get_seconds() - 30) { 1128 warn_no_listener(detail);
1038 warn_no_listener(detail); 1129 return -EINVAL;
1039 return -EINVAL;
1040 } 1130 }
1041 1131
1042 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 1132 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
@@ -1095,13 +1185,19 @@ int qword_get(char **bpp, char *dest, int bufsize)
1095 if (bp[0] == '\\' && bp[1] == 'x') { 1185 if (bp[0] == '\\' && bp[1] == 'x') {
1096 /* HEX STRING */ 1186 /* HEX STRING */
1097 bp += 2; 1187 bp += 2;
1098 while (isxdigit(bp[0]) && isxdigit(bp[1]) && len < bufsize) { 1188 while (len < bufsize) {
1099 int byte = isdigit(*bp) ? *bp-'0' : toupper(*bp)-'A'+10; 1189 int h, l;
1100 bp++; 1190
1101 byte <<= 4; 1191 h = hex_to_bin(bp[0]);
1102 byte |= isdigit(*bp) ? *bp-'0' : toupper(*bp)-'A'+10; 1192 if (h < 0)
1103 *dest++ = byte; 1193 break;
1104 bp++; 1194
1195 l = hex_to_bin(bp[1]);
1196 if (l < 0)
1197 break;
1198
1199 *dest++ = (h << 4) | l;
1200 bp += 2;
1105 len++; 1201 len++;
1106 } 1202 }
1107 } else { 1203 } else {
@@ -1219,7 +1315,8 @@ static int c_show(struct seq_file *m, void *p)
1219 1315
1220 ifdebug(CACHE) 1316 ifdebug(CACHE)
1221 seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n", 1317 seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n",
1222 cp->expiry_time, atomic_read(&cp->ref.refcount), cp->flags); 1318 convert_to_wallclock(cp->expiry_time),
1319 atomic_read(&cp->ref.refcount), cp->flags);
1223 cache_get(cp); 1320 cache_get(cp);
1224 if (cache_check(cd, cp, NULL)) 1321 if (cache_check(cd, cp, NULL))
1225 /* cache_check does a cache_put on failure */ 1322 /* cache_check does a cache_put on failure */
@@ -1285,7 +1382,7 @@ static ssize_t read_flush(struct file *file, char __user *buf,
1285 unsigned long p = *ppos; 1382 unsigned long p = *ppos;
1286 size_t len; 1383 size_t len;
1287 1384
1288 sprintf(tbuf, "%lu\n", cd->flush_time); 1385 sprintf(tbuf, "%lu\n", convert_to_wallclock(cd->flush_time));
1289 len = strlen(tbuf); 1386 len = strlen(tbuf);
1290 if (p >= len) 1387 if (p >= len)
1291 return 0; 1388 return 0;
@@ -1303,19 +1400,20 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
1303 struct cache_detail *cd) 1400 struct cache_detail *cd)
1304{ 1401{
1305 char tbuf[20]; 1402 char tbuf[20];
1306 char *ep; 1403 char *bp, *ep;
1307 long flushtime; 1404
1308 if (*ppos || count > sizeof(tbuf)-1) 1405 if (*ppos || count > sizeof(tbuf)-1)
1309 return -EINVAL; 1406 return -EINVAL;
1310 if (copy_from_user(tbuf, buf, count)) 1407 if (copy_from_user(tbuf, buf, count))
1311 return -EFAULT; 1408 return -EFAULT;
1312 tbuf[count] = 0; 1409 tbuf[count] = 0;
1313 flushtime = simple_strtoul(tbuf, &ep, 0); 1410 simple_strtoul(tbuf, &ep, 0);
1314 if (*ep && *ep != '\n') 1411 if (*ep && *ep != '\n')
1315 return -EINVAL; 1412 return -EINVAL;
1316 1413
1317 cd->flush_time = flushtime; 1414 bp = tbuf;
1318 cd->nextcheck = get_seconds(); 1415 cd->flush_time = get_expiry(&bp);
1416 cd->nextcheck = seconds_since_boot();
1319 cache_flush(); 1417 cache_flush();
1320 1418
1321 *ppos += count; 1419 *ppos += count;
@@ -1348,15 +1446,10 @@ static unsigned int cache_poll_procfs(struct file *filp, poll_table *wait)
1348static long cache_ioctl_procfs(struct file *filp, 1446static long cache_ioctl_procfs(struct file *filp,
1349 unsigned int cmd, unsigned long arg) 1447 unsigned int cmd, unsigned long arg)
1350{ 1448{
1351 long ret;
1352 struct inode *inode = filp->f_path.dentry->d_inode; 1449 struct inode *inode = filp->f_path.dentry->d_inode;
1353 struct cache_detail *cd = PDE(inode)->data; 1450 struct cache_detail *cd = PDE(inode)->data;
1354 1451
1355 lock_kernel(); 1452 return cache_ioctl(inode, filp, cmd, arg, cd);
1356 ret = cache_ioctl(inode, filp, cmd, arg, cd);
1357 unlock_kernel();
1358
1359 return ret;
1360} 1453}
1361 1454
1362static int cache_open_procfs(struct inode *inode, struct file *filp) 1455static int cache_open_procfs(struct inode *inode, struct file *filp)
@@ -1441,10 +1534,13 @@ static const struct file_operations cache_flush_operations_procfs = {
1441 .read = read_flush_procfs, 1534 .read = read_flush_procfs,
1442 .write = write_flush_procfs, 1535 .write = write_flush_procfs,
1443 .release = release_flush_procfs, 1536 .release = release_flush_procfs,
1537 .llseek = no_llseek,
1444}; 1538};
1445 1539
1446static void remove_cache_proc_entries(struct cache_detail *cd) 1540static void remove_cache_proc_entries(struct cache_detail *cd, struct net *net)
1447{ 1541{
1542 struct sunrpc_net *sn;
1543
1448 if (cd->u.procfs.proc_ent == NULL) 1544 if (cd->u.procfs.proc_ent == NULL)
1449 return; 1545 return;
1450 if (cd->u.procfs.flush_ent) 1546 if (cd->u.procfs.flush_ent)
@@ -1454,15 +1550,18 @@ static void remove_cache_proc_entries(struct cache_detail *cd)
1454 if (cd->u.procfs.content_ent) 1550 if (cd->u.procfs.content_ent)
1455 remove_proc_entry("content", cd->u.procfs.proc_ent); 1551 remove_proc_entry("content", cd->u.procfs.proc_ent);
1456 cd->u.procfs.proc_ent = NULL; 1552 cd->u.procfs.proc_ent = NULL;
1457 remove_proc_entry(cd->name, proc_net_rpc); 1553 sn = net_generic(net, sunrpc_net_id);
1554 remove_proc_entry(cd->name, sn->proc_net_rpc);
1458} 1555}
1459 1556
1460#ifdef CONFIG_PROC_FS 1557#ifdef CONFIG_PROC_FS
1461static int create_cache_proc_entries(struct cache_detail *cd) 1558static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
1462{ 1559{
1463 struct proc_dir_entry *p; 1560 struct proc_dir_entry *p;
1561 struct sunrpc_net *sn;
1464 1562
1465 cd->u.procfs.proc_ent = proc_mkdir(cd->name, proc_net_rpc); 1563 sn = net_generic(net, sunrpc_net_id);
1564 cd->u.procfs.proc_ent = proc_mkdir(cd->name, sn->proc_net_rpc);
1466 if (cd->u.procfs.proc_ent == NULL) 1565 if (cd->u.procfs.proc_ent == NULL)
1467 goto out_nomem; 1566 goto out_nomem;
1468 cd->u.procfs.channel_ent = NULL; 1567 cd->u.procfs.channel_ent = NULL;
@@ -1493,11 +1592,11 @@ static int create_cache_proc_entries(struct cache_detail *cd)
1493 } 1592 }
1494 return 0; 1593 return 0;
1495out_nomem: 1594out_nomem:
1496 remove_cache_proc_entries(cd); 1595 remove_cache_proc_entries(cd, net);
1497 return -ENOMEM; 1596 return -ENOMEM;
1498} 1597}
1499#else /* CONFIG_PROC_FS */ 1598#else /* CONFIG_PROC_FS */
1500static int create_cache_proc_entries(struct cache_detail *cd) 1599static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
1501{ 1600{
1502 return 0; 1601 return 0;
1503} 1602}
@@ -1508,23 +1607,33 @@ void __init cache_initialize(void)
1508 INIT_DELAYED_WORK_DEFERRABLE(&cache_cleaner, do_cache_clean); 1607 INIT_DELAYED_WORK_DEFERRABLE(&cache_cleaner, do_cache_clean);
1509} 1608}
1510 1609
1511int cache_register(struct cache_detail *cd) 1610int cache_register_net(struct cache_detail *cd, struct net *net)
1512{ 1611{
1513 int ret; 1612 int ret;
1514 1613
1515 sunrpc_init_cache_detail(cd); 1614 sunrpc_init_cache_detail(cd);
1516 ret = create_cache_proc_entries(cd); 1615 ret = create_cache_proc_entries(cd, net);
1517 if (ret) 1616 if (ret)
1518 sunrpc_destroy_cache_detail(cd); 1617 sunrpc_destroy_cache_detail(cd);
1519 return ret; 1618 return ret;
1520} 1619}
1620
1621int cache_register(struct cache_detail *cd)
1622{
1623 return cache_register_net(cd, &init_net);
1624}
1521EXPORT_SYMBOL_GPL(cache_register); 1625EXPORT_SYMBOL_GPL(cache_register);
1522 1626
1523void cache_unregister(struct cache_detail *cd) 1627void cache_unregister_net(struct cache_detail *cd, struct net *net)
1524{ 1628{
1525 remove_cache_proc_entries(cd); 1629 remove_cache_proc_entries(cd, net);
1526 sunrpc_destroy_cache_detail(cd); 1630 sunrpc_destroy_cache_detail(cd);
1527} 1631}
1632
1633void cache_unregister(struct cache_detail *cd)
1634{
1635 cache_unregister_net(cd, &init_net);
1636}
1528EXPORT_SYMBOL_GPL(cache_unregister); 1637EXPORT_SYMBOL_GPL(cache_unregister);
1529 1638
1530static ssize_t cache_read_pipefs(struct file *filp, char __user *buf, 1639static ssize_t cache_read_pipefs(struct file *filp, char __user *buf,
@@ -1555,13 +1664,8 @@ static long cache_ioctl_pipefs(struct file *filp,
1555{ 1664{
1556 struct inode *inode = filp->f_dentry->d_inode; 1665 struct inode *inode = filp->f_dentry->d_inode;
1557 struct cache_detail *cd = RPC_I(inode)->private; 1666 struct cache_detail *cd = RPC_I(inode)->private;
1558 long ret;
1559
1560 lock_kernel();
1561 ret = cache_ioctl(inode, filp, cmd, arg, cd);
1562 unlock_kernel();
1563 1667
1564 return ret; 1668 return cache_ioctl(inode, filp, cmd, arg, cd);
1565} 1669}
1566 1670
1567static int cache_open_pipefs(struct inode *inode, struct file *filp) 1671static int cache_open_pipefs(struct inode *inode, struct file *filp)
@@ -1646,6 +1750,7 @@ const struct file_operations cache_flush_operations_pipefs = {
1646 .read = read_flush_pipefs, 1750 .read = read_flush_pipefs,
1647 .write = write_flush_pipefs, 1751 .write = write_flush_pipefs,
1648 .release = release_flush_pipefs, 1752 .release = release_flush_pipefs,
1753 .llseek = no_llseek,
1649}; 1754};
1650 1755
1651int sunrpc_cache_register_pipefs(struct dentry *parent, 1756int sunrpc_cache_register_pipefs(struct dentry *parent,