diff options
-rw-r--r-- | include/linux/sunrpc/cache.h | 13 | ||||
-rw-r--r-- | include/linux/sunrpc/rpc_pipe_fs.h | 8 | ||||
-rw-r--r-- | net/sunrpc/cache.c | 126 | ||||
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 43 |
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 | ||
67 | struct cache_detail_pipefs { | ||
68 | struct dentry *dir; | ||
69 | }; | ||
70 | |||
67 | struct cache_detail { | 71 | struct 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 | ||
143 | extern const struct file_operations cache_file_operations_pipefs; | ||
144 | extern const struct file_operations content_file_operations_pipefs; | ||
145 | extern const struct file_operations cache_flush_operations_pipefs; | ||
146 | |||
138 | extern struct cache_head * | 147 | extern struct cache_head * |
139 | sunrpc_cache_lookup(struct cache_detail *detail, | 148 | sunrpc_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); | |||
186 | extern int cache_register(struct cache_detail *cd); | 195 | extern int cache_register(struct cache_detail *cd); |
187 | extern void cache_unregister(struct cache_detail *cd); | 196 | extern void cache_unregister(struct cache_detail *cd); |
188 | 197 | ||
198 | extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *, | ||
199 | mode_t, struct cache_detail *); | ||
200 | extern void sunrpc_cache_unregister_pipefs(struct cache_detail *); | ||
201 | |||
189 | extern void qword_add(char **bpp, int *lp, char *str); | 202 | extern void qword_add(char **bpp, int *lp, char *str); |
190 | extern void qword_addhex(char **bpp, int *lp, char *buf, int blen); | 203 | extern void qword_addhex(char **bpp, int *lp, char *buf, int blen); |
191 | extern int qword_get(char **bpp, char *dest, int bufsize); | 204 | extern 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 *); | |||
47 | struct rpc_clnt; | 47 | struct rpc_clnt; |
48 | extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *); | 48 | extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *); |
49 | extern int rpc_remove_client_dir(struct dentry *); | 49 | extern int rpc_remove_client_dir(struct dentry *); |
50 | |||
51 | struct cache_detail; | ||
52 | extern struct dentry *rpc_create_cache_dir(struct dentry *, | ||
53 | struct qstr *, | ||
54 | mode_t umode, | ||
55 | struct cache_detail *); | ||
56 | extern void rpc_remove_cache_dir(struct dentry *); | ||
57 | |||
50 | extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *, | 58 | extern 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); |
52 | extern int rpc_unlink(struct dentry *); | 60 | extern 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 | } |
1440 | EXPORT_SYMBOL_GPL(cache_unregister); | 1441 | EXPORT_SYMBOL_GPL(cache_unregister); |
1442 | |||
1443 | static 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 | |||
1451 | static 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 | |||
1459 | static 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 | |||
1466 | static 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 | |||
1474 | static 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 | |||
1481 | static 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 | |||
1488 | const 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 | |||
1499 | static 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 | |||
1506 | const 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 | |||
1513 | static 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 | |||
1521 | static 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 | |||
1530 | const struct file_operations cache_flush_operations_pipefs = { | ||
1531 | .open = nonseekable_open, | ||
1532 | .read = read_flush_pipefs, | ||
1533 | .write = write_flush_pipefs, | ||
1534 | }; | ||
1535 | |||
1536 | int 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 | } | ||
1557 | EXPORT_SYMBOL_GPL(sunrpc_cache_register_pipefs); | ||
1558 | |||
1559 | void 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 | } | ||
1565 | EXPORT_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 | ||
30 | static struct vfsmount *rpc_mount __read_mostly; | 31 | static struct vfsmount *rpc_mount __read_mostly; |
31 | static int rpc_mount_count; | 32 | static 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 | ||
886 | static 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 | |||
904 | static 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 | |||
911 | static void rpc_cachedir_depopulate(struct dentry *dentry) | ||
912 | { | ||
913 | rpc_depopulate(dentry, cache_pipefs_files, 0, 3); | ||
914 | } | ||
915 | |||
916 | struct 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 | |||
923 | void 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 | */ |