diff options
author | Tom Zanussi <zanussi@us.ibm.com> | 2006-01-08 04:02:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-08 23:13:49 -0500 |
commit | 6625b861f8f0e429902b8671b3e70792cd99074e (patch) | |
tree | 0a141b0c15d8ed012d971553acde9f7029adcfe6 | |
parent | b33291c0bcecfa44baa905964eec4b8815dcbcdf (diff) |
[PATCH] relayfs: decouple buffer creation from inode creation
The patch series implementa or fixes 3 things that were specifically requested
or suggested by relayfs users:
- support for non-relay files (patches 1-6)
Currently, the relayfs API only supports the creation of directories
(relayfs_create_dir()) and relay files (relay_open()). These patches adds
support for non-relay files (relayfs_create_file()). This is so relayfs
applications can create 'control files' in relayfs itself rather than in /proc
or via a netlink channel, as is currently done in the relay-app examples.
Basically what this amounts to is exporting relayfs_create_file() with an
additional file_ops param that clients can use to supply file operations for
their own special-purpose files in relayfs.
- make exported relay file ops useful (patches 7-8)
The relayfs relay_file_operations have always been exported, the intent being
to make it possible to create relay files in other filesystems such as
debugfs. The problem, though, is that currently the file operations are too
tightly coupled to relayfs to actually be used for this purpose. This patch
fixes that by adding a couple of callback functions that allow a client to
hook into relay_open()/close() and supply the files that will be used to
represent the channel buffers; the default implementation if no callbacks are
defined is to create the files in relayfs.
- add an option to create global relay buffer (patches 9-10) The file creation
callback also supplies an optional param, is_global, that can be used by
clients to create a single global relayfs buffer instead of the default
per-cpu buffers. This was suggested as being useful for certain debugging
applications where it's more convenient to be able to get all the data from a
single channel without having to go to the bother of dealing with per-cpu
files.
- cleanup, some renaming and Documentation updates (patches 11-12)
There were several comments that the use of netlink in the example code was
non-intuitive and in fact the whole relay-app business was needlessly
confusing. Based on that feedback, the example code has been completely
converted over to relayfs control files as supported by this patch, and have
also been made completely self-contained.
The converted examples along with a couple of new examples that demonstrate
using exported relay files can be found in relay-apps tarball:
http://prdownloads.sourceforge.net/relayfs/relay-apps-0.9.tar.gz?download
This patch:
Separate buffer create/destroy from inode create/destroy. We want to be able
to associate other data and not just relay buffers with inodes. Buffer
create/destroy is moved out of inode.c and into relayfs core code.
Signed-off-by: Tom Zanussi <zanussi@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/relayfs/buffers.c | 1 | ||||
-rw-r--r-- | fs/relayfs/inode.c | 31 | ||||
-rw-r--r-- | fs/relayfs/relay.c | 11 | ||||
-rw-r--r-- | fs/relayfs/relay.h | 2 |
4 files changed, 19 insertions, 26 deletions
diff --git a/fs/relayfs/buffers.c b/fs/relayfs/buffers.c index 84e21ffa5ca8..667b529944c5 100644 --- a/fs/relayfs/buffers.c +++ b/fs/relayfs/buffers.c | |||
@@ -186,4 +186,5 @@ void relay_remove_buf(struct kref *kref) | |||
186 | { | 186 | { |
187 | struct rchan_buf *buf = container_of(kref, struct rchan_buf, kref); | 187 | struct rchan_buf *buf = container_of(kref, struct rchan_buf, kref); |
188 | relayfs_remove(buf->dentry); | 188 | relayfs_remove(buf->dentry); |
189 | relay_destroy_buf(buf); | ||
189 | } | 190 | } |
diff --git a/fs/relayfs/inode.c b/fs/relayfs/inode.c index 0f7f88d067ad..379e07cd2b34 100644 --- a/fs/relayfs/inode.c +++ b/fs/relayfs/inode.c | |||
@@ -34,23 +34,13 @@ static struct backing_dev_info relayfs_backing_dev_info = { | |||
34 | }; | 34 | }; |
35 | 35 | ||
36 | static struct inode *relayfs_get_inode(struct super_block *sb, int mode, | 36 | static struct inode *relayfs_get_inode(struct super_block *sb, int mode, |
37 | struct rchan *chan) | 37 | void *data) |
38 | { | 38 | { |
39 | struct rchan_buf *buf = NULL; | ||
40 | struct inode *inode; | 39 | struct inode *inode; |
41 | 40 | ||
42 | if (S_ISREG(mode)) { | ||
43 | BUG_ON(!chan); | ||
44 | buf = relay_create_buf(chan); | ||
45 | if (!buf) | ||
46 | return NULL; | ||
47 | } | ||
48 | |||
49 | inode = new_inode(sb); | 41 | inode = new_inode(sb); |
50 | if (!inode) { | 42 | if (!inode) |
51 | relay_destroy_buf(buf); | ||
52 | return NULL; | 43 | return NULL; |
53 | } | ||
54 | 44 | ||
55 | inode->i_mode = mode; | 45 | inode->i_mode = mode; |
56 | inode->i_uid = 0; | 46 | inode->i_uid = 0; |
@@ -62,7 +52,7 @@ static struct inode *relayfs_get_inode(struct super_block *sb, int mode, | |||
62 | switch (mode & S_IFMT) { | 52 | switch (mode & S_IFMT) { |
63 | case S_IFREG: | 53 | case S_IFREG: |
64 | inode->i_fop = &relayfs_file_operations; | 54 | inode->i_fop = &relayfs_file_operations; |
65 | RELAYFS_I(inode)->buf = buf; | 55 | RELAYFS_I(inode)->buf = data; |
66 | break; | 56 | break; |
67 | case S_IFDIR: | 57 | case S_IFDIR: |
68 | inode->i_op = &simple_dir_inode_operations; | 58 | inode->i_op = &simple_dir_inode_operations; |
@@ -83,7 +73,7 @@ static struct inode *relayfs_get_inode(struct super_block *sb, int mode, | |||
83 | * @name: the name of the file to create | 73 | * @name: the name of the file to create |
84 | * @parent: parent directory | 74 | * @parent: parent directory |
85 | * @mode: mode | 75 | * @mode: mode |
86 | * @chan: relay channel associated with the file | 76 | * @data: user-associated data for this file |
87 | * | 77 | * |
88 | * Returns the new dentry, NULL on failure | 78 | * Returns the new dentry, NULL on failure |
89 | * | 79 | * |
@@ -92,7 +82,7 @@ static struct inode *relayfs_get_inode(struct super_block *sb, int mode, | |||
92 | static struct dentry *relayfs_create_entry(const char *name, | 82 | static struct dentry *relayfs_create_entry(const char *name, |
93 | struct dentry *parent, | 83 | struct dentry *parent, |
94 | int mode, | 84 | int mode, |
95 | struct rchan *chan) | 85 | void *data) |
96 | { | 86 | { |
97 | struct dentry *d; | 87 | struct dentry *d; |
98 | struct inode *inode; | 88 | struct inode *inode; |
@@ -127,7 +117,7 @@ static struct dentry *relayfs_create_entry(const char *name, | |||
127 | goto release_mount; | 117 | goto release_mount; |
128 | } | 118 | } |
129 | 119 | ||
130 | inode = relayfs_get_inode(parent->d_inode->i_sb, mode, chan); | 120 | inode = relayfs_get_inode(parent->d_inode->i_sb, mode, data); |
131 | if (!inode) { | 121 | if (!inode) { |
132 | d = NULL; | 122 | d = NULL; |
133 | goto release_mount; | 123 | goto release_mount; |
@@ -155,20 +145,20 @@ exit: | |||
155 | * @name: the name of the file to create | 145 | * @name: the name of the file to create |
156 | * @parent: parent directory | 146 | * @parent: parent directory |
157 | * @mode: mode, if not specied the default perms are used | 147 | * @mode: mode, if not specied the default perms are used |
158 | * @chan: channel associated with the file | 148 | * @data: user-associated data for this file |
159 | * | 149 | * |
160 | * Returns file dentry if successful, NULL otherwise. | 150 | * Returns file dentry if successful, NULL otherwise. |
161 | * | 151 | * |
162 | * The file will be created user r on behalf of current user. | 152 | * The file will be created user r on behalf of current user. |
163 | */ | 153 | */ |
164 | struct dentry *relayfs_create_file(const char *name, struct dentry *parent, | 154 | struct dentry *relayfs_create_file(const char *name, struct dentry *parent, |
165 | int mode, struct rchan *chan) | 155 | int mode, void *data) |
166 | { | 156 | { |
167 | if (!mode) | 157 | if (!mode) |
168 | mode = S_IRUSR; | 158 | mode = S_IRUSR; |
169 | mode = (mode & S_IALLUGO) | S_IFREG; | 159 | mode = (mode & S_IALLUGO) | S_IFREG; |
170 | 160 | ||
171 | return relayfs_create_entry(name, parent, mode, chan); | 161 | return relayfs_create_entry(name, parent, mode, data); |
172 | } | 162 | } |
173 | 163 | ||
174 | /** | 164 | /** |
@@ -505,9 +495,6 @@ static struct inode *relayfs_alloc_inode(struct super_block *sb) | |||
505 | */ | 495 | */ |
506 | static void relayfs_destroy_inode(struct inode *inode) | 496 | static void relayfs_destroy_inode(struct inode *inode) |
507 | { | 497 | { |
508 | if (RELAYFS_I(inode)->buf) | ||
509 | relay_destroy_buf(RELAYFS_I(inode)->buf); | ||
510 | |||
511 | kmem_cache_free(relayfs_inode_cachep, RELAYFS_I(inode)); | 498 | kmem_cache_free(relayfs_inode_cachep, RELAYFS_I(inode)); |
512 | } | 499 | } |
513 | 500 | ||
diff --git a/fs/relayfs/relay.c b/fs/relayfs/relay.c index 2a6f7f12b7f9..7fbda177ad8f 100644 --- a/fs/relayfs/relay.c +++ b/fs/relayfs/relay.c | |||
@@ -171,12 +171,17 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan, | |||
171 | struct rchan_buf *buf; | 171 | struct rchan_buf *buf; |
172 | struct dentry *dentry; | 172 | struct dentry *dentry; |
173 | 173 | ||
174 | buf = relay_create_buf(chan); | ||
175 | if (!buf) | ||
176 | return NULL; | ||
177 | |||
174 | /* Create file in fs */ | 178 | /* Create file in fs */ |
175 | dentry = relayfs_create_file(filename, parent, S_IRUSR, chan); | 179 | dentry = relayfs_create_file(filename, parent, S_IRUSR, buf); |
176 | if (!dentry) | 180 | if (!dentry) { |
181 | relay_destroy_buf(buf); | ||
177 | return NULL; | 182 | return NULL; |
183 | } | ||
178 | 184 | ||
179 | buf = RELAYFS_I(dentry->d_inode)->buf; | ||
180 | buf->dentry = dentry; | 185 | buf->dentry = dentry; |
181 | __relay_reset(buf, 1); | 186 | __relay_reset(buf, 1); |
182 | 187 | ||
diff --git a/fs/relayfs/relay.h b/fs/relayfs/relay.h index 703503fa22b6..c325bb243549 100644 --- a/fs/relayfs/relay.h +++ b/fs/relayfs/relay.h | |||
@@ -4,7 +4,7 @@ | |||
4 | struct dentry *relayfs_create_file(const char *name, | 4 | struct dentry *relayfs_create_file(const char *name, |
5 | struct dentry *parent, | 5 | struct dentry *parent, |
6 | int mode, | 6 | int mode, |
7 | struct rchan *chan); | 7 | void *data); |
8 | extern int relayfs_remove(struct dentry *dentry); | 8 | extern int relayfs_remove(struct dentry *dentry); |
9 | extern int relay_buf_empty(struct rchan_buf *buf); | 9 | extern int relay_buf_empty(struct rchan_buf *buf); |
10 | extern void relay_destroy_channel(struct kref *kref); | 10 | extern void relay_destroy_channel(struct kref *kref); |