aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sunrpc/cache.h13
-rw-r--r--include/linux/sunrpc/rpc_pipe_fs.h8
-rw-r--r--net/sunrpc/cache.c126
-rw-r--r--net/sunrpc/rpc_pipe.c43
4 files changed, 190 insertions, 0 deletions
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 8e5bf3036652..6f52b4d7c447 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -64,6 +64,10 @@ struct cache_detail_procfs {
64 struct proc_dir_entry *flush_ent, *channel_ent, *content_ent; 64 struct proc_dir_entry *flush_ent, *channel_ent, *content_ent;
65}; 65};
66 66
67struct cache_detail_pipefs {
68 struct dentry *dir;
69};
70
67struct cache_detail { 71struct cache_detail {
68 struct module * owner; 72 struct module * owner;
69 int hash_size; 73 int hash_size;
@@ -110,6 +114,7 @@ struct cache_detail {
110 114
111 union { 115 union {
112 struct cache_detail_procfs procfs; 116 struct cache_detail_procfs procfs;
117 struct cache_detail_pipefs pipefs;
113 } u; 118 } u;
114}; 119};
115 120
@@ -135,6 +140,10 @@ struct cache_deferred_req {
135}; 140};
136 141
137 142
143extern const struct file_operations cache_file_operations_pipefs;
144extern const struct file_operations content_file_operations_pipefs;
145extern const struct file_operations cache_flush_operations_pipefs;
146
138extern struct cache_head * 147extern struct cache_head *
139sunrpc_cache_lookup(struct cache_detail *detail, 148sunrpc_cache_lookup(struct cache_detail *detail,
140 struct cache_head *key, int hash); 149 struct cache_head *key, int hash);
@@ -186,6 +195,10 @@ extern void cache_purge(struct cache_detail *detail);
186extern int cache_register(struct cache_detail *cd); 195extern int cache_register(struct cache_detail *cd);
187extern void cache_unregister(struct cache_detail *cd); 196extern void cache_unregister(struct cache_detail *cd);
188 197
198extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
199 mode_t, struct cache_detail *);
200extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
201
189extern void qword_add(char **bpp, int *lp, char *str); 202extern void qword_add(char **bpp, int *lp, char *str);
190extern void qword_addhex(char **bpp, int *lp, char *buf, int blen); 203extern void qword_addhex(char **bpp, int *lp, char *buf, int blen);
191extern int qword_get(char **bpp, char *dest, int bufsize); 204extern int qword_get(char **bpp, char *dest, int bufsize);
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index 88332ef1e959..a92571a34556 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -47,6 +47,14 @@ extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
47struct rpc_clnt; 47struct rpc_clnt;
48extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *); 48extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *);
49extern int rpc_remove_client_dir(struct dentry *); 49extern int rpc_remove_client_dir(struct dentry *);
50
51struct cache_detail;
52extern struct dentry *rpc_create_cache_dir(struct dentry *,
53 struct qstr *,
54 mode_t umode,
55 struct cache_detail *);
56extern void rpc_remove_cache_dir(struct dentry *);
57
50extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *, 58extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *,
51 const struct rpc_pipe_ops *, int flags); 59 const struct rpc_pipe_ops *, int flags);
52extern int rpc_unlink(struct dentry *); 60extern int rpc_unlink(struct dentry *);
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 1cd82eda56d0..db7720e453c3 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -32,6 +32,7 @@
32#include <linux/sunrpc/types.h> 32#include <linux/sunrpc/types.h>
33#include <linux/sunrpc/cache.h> 33#include <linux/sunrpc/cache.h>
34#include <linux/sunrpc/stats.h> 34#include <linux/sunrpc/stats.h>
35#include <linux/sunrpc/rpc_pipe_fs.h>
35 36
36#define RPCDBG_FACILITY RPCDBG_CACHE 37#define RPCDBG_FACILITY RPCDBG_CACHE
37 38
@@ -1438,3 +1439,128 @@ void cache_unregister(struct cache_detail *cd)
1438 sunrpc_destroy_cache_detail(cd); 1439 sunrpc_destroy_cache_detail(cd);
1439} 1440}
1440EXPORT_SYMBOL_GPL(cache_unregister); 1441EXPORT_SYMBOL_GPL(cache_unregister);
1442
1443static ssize_t cache_read_pipefs(struct file *filp, char __user *buf,
1444 size_t count, loff_t *ppos)
1445{
1446 struct cache_detail *cd = RPC_I(filp->f_path.dentry->d_inode)->private;
1447
1448 return cache_read(filp, buf, count, ppos, cd);
1449}
1450
1451static ssize_t cache_write_pipefs(struct file *filp, const char __user *buf,
1452 size_t count, loff_t *ppos)
1453{
1454 struct cache_detail *cd = RPC_I(filp->f_path.dentry->d_inode)->private;
1455
1456 return cache_write(filp, buf, count, ppos, cd);
1457}
1458
1459static unsigned int cache_poll_pipefs(struct file *filp, poll_table *wait)
1460{
1461 struct cache_detail *cd = RPC_I(filp->f_path.dentry->d_inode)->private;
1462
1463 return cache_poll(filp, wait, cd);
1464}
1465
1466static int cache_ioctl_pipefs(struct inode *inode, struct file *filp,
1467 unsigned int cmd, unsigned long arg)
1468{
1469 struct cache_detail *cd = RPC_I(inode)->private;
1470
1471 return cache_ioctl(inode, filp, cmd, arg, cd);
1472}
1473
1474static int cache_open_pipefs(struct inode *inode, struct file *filp)
1475{
1476 struct cache_detail *cd = RPC_I(inode)->private;
1477
1478 return cache_open(inode, filp, cd);
1479}
1480
1481static int cache_release_pipefs(struct inode *inode, struct file *filp)
1482{
1483 struct cache_detail *cd = RPC_I(inode)->private;
1484
1485 return cache_release(inode, filp, cd);
1486}
1487
1488const struct file_operations cache_file_operations_pipefs = {
1489 .owner = THIS_MODULE,
1490 .llseek = no_llseek,
1491 .read = cache_read_pipefs,
1492 .write = cache_write_pipefs,
1493 .poll = cache_poll_pipefs,
1494 .ioctl = cache_ioctl_pipefs, /* for FIONREAD */
1495 .open = cache_open_pipefs,
1496 .release = cache_release_pipefs,
1497};
1498
1499static int content_open_pipefs(struct inode *inode, struct file *filp)
1500{
1501 struct cache_detail *cd = RPC_I(inode)->private;
1502
1503 return content_open(inode, filp, cd);
1504}
1505
1506const struct file_operations content_file_operations_pipefs = {
1507 .open = content_open_pipefs,
1508 .read = seq_read,
1509 .llseek = seq_lseek,
1510 .release = seq_release_private,
1511};
1512
1513static ssize_t read_flush_pipefs(struct file *filp, char __user *buf,
1514 size_t count, loff_t *ppos)
1515{
1516 struct cache_detail *cd = RPC_I(filp->f_path.dentry->d_inode)->private;
1517
1518 return read_flush(filp, buf, count, ppos, cd);
1519}
1520
1521static ssize_t write_flush_pipefs(struct file *filp,
1522 const char __user *buf,
1523 size_t count, loff_t *ppos)
1524{
1525 struct cache_detail *cd = RPC_I(filp->f_path.dentry->d_inode)->private;
1526
1527 return write_flush(filp, buf, count, ppos, cd);
1528}
1529
1530const struct file_operations cache_flush_operations_pipefs = {
1531 .open = nonseekable_open,
1532 .read = read_flush_pipefs,
1533 .write = write_flush_pipefs,
1534};
1535
1536int sunrpc_cache_register_pipefs(struct dentry *parent,
1537 const char *name, mode_t umode,
1538 struct cache_detail *cd)
1539{
1540 struct qstr q;
1541 struct dentry *dir;
1542 int ret = 0;
1543
1544 sunrpc_init_cache_detail(cd);
1545 q.name = name;
1546 q.len = strlen(name);
1547 q.hash = full_name_hash(q.name, q.len);
1548 dir = rpc_create_cache_dir(parent, &q, umode, cd);
1549 if (!IS_ERR(dir))
1550 cd->u.pipefs.dir = dir;
1551 else {
1552 sunrpc_destroy_cache_detail(cd);
1553 ret = PTR_ERR(dir);
1554 }
1555 return ret;
1556}
1557EXPORT_SYMBOL_GPL(sunrpc_cache_register_pipefs);
1558
1559void sunrpc_cache_unregister_pipefs(struct cache_detail *cd)
1560{
1561 rpc_remove_cache_dir(cd->u.pipefs.dir);
1562 cd->u.pipefs.dir = NULL;
1563 sunrpc_destroy_cache_detail(cd);
1564}
1565EXPORT_SYMBOL_GPL(sunrpc_cache_unregister_pipefs);
1566
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 57e9cd3c49b6..8dd81535e08f 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -26,6 +26,7 @@
26#include <linux/sunrpc/clnt.h> 26#include <linux/sunrpc/clnt.h>
27#include <linux/workqueue.h> 27#include <linux/workqueue.h>
28#include <linux/sunrpc/rpc_pipe_fs.h> 28#include <linux/sunrpc/rpc_pipe_fs.h>
29#include <linux/sunrpc/cache.h>
29 30
30static struct vfsmount *rpc_mount __read_mostly; 31static struct vfsmount *rpc_mount __read_mostly;
31static int rpc_mount_count; 32static int rpc_mount_count;
@@ -882,6 +883,48 @@ int rpc_remove_client_dir(struct dentry *dentry)
882 return rpc_rmdir_depopulate(dentry, rpc_clntdir_depopulate); 883 return rpc_rmdir_depopulate(dentry, rpc_clntdir_depopulate);
883} 884}
884 885
886static const struct rpc_filelist cache_pipefs_files[3] = {
887 [0] = {
888 .name = "channel",
889 .i_fop = &cache_file_operations_pipefs,
890 .mode = S_IFIFO|S_IRUSR|S_IWUSR,
891 },
892 [1] = {
893 .name = "content",
894 .i_fop = &content_file_operations_pipefs,
895 .mode = S_IFREG|S_IRUSR,
896 },
897 [2] = {
898 .name = "flush",
899 .i_fop = &cache_flush_operations_pipefs,
900 .mode = S_IFREG|S_IRUSR|S_IWUSR,
901 },
902};
903
904static int rpc_cachedir_populate(struct dentry *dentry, void *private)
905{
906 return rpc_populate(dentry,
907 cache_pipefs_files, 0, 3,
908 private);
909}
910
911static void rpc_cachedir_depopulate(struct dentry *dentry)
912{
913 rpc_depopulate(dentry, cache_pipefs_files, 0, 3);
914}
915
916struct dentry *rpc_create_cache_dir(struct dentry *parent, struct qstr *name,
917 mode_t umode, struct cache_detail *cd)
918{
919 return rpc_mkdir_populate(parent, name, umode, NULL,
920 rpc_cachedir_populate, cd);
921}
922
923void rpc_remove_cache_dir(struct dentry *dentry)
924{
925 rpc_rmdir_depopulate(dentry, rpc_cachedir_depopulate);
926}
927
885/* 928/*
886 * populate the filesystem 929 * populate the filesystem
887 */ 930 */