aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Zanussi <zanussi@us.ibm.com>2006-01-08 04:02:24 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-08 23:13:49 -0500
commit907f2c77d1653ce235e8e1fd6ce5c46005814e78 (patch)
treedddb1fb14c4be54b066585235c97a36460e8faff
parent6625b861f8f0e429902b8671b3e70792cd99074e (diff)
[PATCH] relayfs: export relayfs_create_file() with fileops param
This patch adds a mandatory fileops param to relayfs_create_file() and exports that function so that clients can use it to create files defined by their own set of file operations, in relayfs. The purpose is to allow relayfs applications to create their own set of 'control' files alongside their relay files in relayfs rather than having to create them in /proc or debugfs for instance. relayfs_create_file() is also used by relay_open_buf() to create the relay files for a channel. In this case, a pointer to relayfs_file_operations is passed in, along with a pointer to the buffer associated with the file. 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/inode.c41
-rw-r--r--fs/relayfs/relay.c3
-rw-r--r--fs/relayfs/relay.h4
-rw-r--r--include/linux/relayfs_fs.h7
4 files changed, 34 insertions, 21 deletions
diff --git a/fs/relayfs/inode.c b/fs/relayfs/inode.c
index 379e07cd2b34..a5e6d4f2efb9 100644
--- a/fs/relayfs/inode.c
+++ b/fs/relayfs/inode.c
@@ -33,7 +33,9 @@ static struct backing_dev_info relayfs_backing_dev_info = {
33 .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, 33 .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
34}; 34};
35 35
36static struct inode *relayfs_get_inode(struct super_block *sb, int mode, 36static struct inode *relayfs_get_inode(struct super_block *sb,
37 int mode,
38 struct file_operations *fops,
37 void *data) 39 void *data)
38{ 40{
39 struct inode *inode; 41 struct inode *inode;
@@ -51,8 +53,8 @@ static struct inode *relayfs_get_inode(struct super_block *sb, int mode,
51 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 53 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
52 switch (mode & S_IFMT) { 54 switch (mode & S_IFMT) {
53 case S_IFREG: 55 case S_IFREG:
54 inode->i_fop = &relayfs_file_operations; 56 inode->i_fop = fops;
55 RELAYFS_I(inode)->buf = data; 57 RELAYFS_I(inode)->data = data;
56 break; 58 break;
57 case S_IFDIR: 59 case S_IFDIR:
58 inode->i_op = &simple_dir_inode_operations; 60 inode->i_op = &simple_dir_inode_operations;
@@ -73,6 +75,7 @@ static struct inode *relayfs_get_inode(struct super_block *sb, int mode,
73 * @name: the name of the file to create 75 * @name: the name of the file to create
74 * @parent: parent directory 76 * @parent: parent directory
75 * @mode: mode 77 * @mode: mode
78 * @fops: file operations to use for the file
76 * @data: user-associated data for this file 79 * @data: user-associated data for this file
77 * 80 *
78 * Returns the new dentry, NULL on failure 81 * Returns the new dentry, NULL on failure
@@ -82,6 +85,7 @@ static struct inode *relayfs_get_inode(struct super_block *sb, int mode,
82static struct dentry *relayfs_create_entry(const char *name, 85static struct dentry *relayfs_create_entry(const char *name,
83 struct dentry *parent, 86 struct dentry *parent,
84 int mode, 87 int mode,
88 struct file_operations *fops,
85 void *data) 89 void *data)
86{ 90{
87 struct dentry *d; 91 struct dentry *d;
@@ -117,7 +121,7 @@ static struct dentry *relayfs_create_entry(const char *name,
117 goto release_mount; 121 goto release_mount;
118 } 122 }
119 123
120 inode = relayfs_get_inode(parent->d_inode->i_sb, mode, data); 124 inode = relayfs_get_inode(parent->d_inode->i_sb, mode, fops, data);
121 if (!inode) { 125 if (!inode) {
122 d = NULL; 126 d = NULL;
123 goto release_mount; 127 goto release_mount;
@@ -145,20 +149,26 @@ exit:
145 * @name: the name of the file to create 149 * @name: the name of the file to create
146 * @parent: parent directory 150 * @parent: parent directory
147 * @mode: mode, if not specied the default perms are used 151 * @mode: mode, if not specied the default perms are used
152 * @fops: file operations to use for the file
148 * @data: user-associated data for this file 153 * @data: user-associated data for this file
149 * 154 *
150 * Returns file dentry if successful, NULL otherwise. 155 * Returns file dentry if successful, NULL otherwise.
151 * 156 *
152 * The file will be created user r on behalf of current user. 157 * The file will be created user r on behalf of current user.
153 */ 158 */
154struct dentry *relayfs_create_file(const char *name, struct dentry *parent, 159struct dentry *relayfs_create_file(const char *name,
155 int mode, void *data) 160 struct dentry *parent,
161 int mode,
162 struct file_operations *fops,
163 void *data)
156{ 164{
165 BUG_ON(!fops);
166
157 if (!mode) 167 if (!mode)
158 mode = S_IRUSR; 168 mode = S_IRUSR;
159 mode = (mode & S_IALLUGO) | S_IFREG; 169 mode = (mode & S_IALLUGO) | S_IFREG;
160 170
161 return relayfs_create_entry(name, parent, mode, data); 171 return relayfs_create_entry(name, parent, mode, fops, data);
162} 172}
163 173
164/** 174/**
@@ -173,7 +183,7 @@ struct dentry *relayfs_create_file(const char *name, struct dentry *parent,
173struct dentry *relayfs_create_dir(const char *name, struct dentry *parent) 183struct dentry *relayfs_create_dir(const char *name, struct dentry *parent)
174{ 184{
175 int mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; 185 int mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
176 return relayfs_create_entry(name, parent, mode, NULL); 186 return relayfs_create_entry(name, parent, mode, NULL, NULL);
177} 187}
178 188
179/** 189/**
@@ -234,7 +244,7 @@ int relayfs_remove_dir(struct dentry *dentry)
234 */ 244 */
235static int relayfs_open(struct inode *inode, struct file *filp) 245static int relayfs_open(struct inode *inode, struct file *filp)
236{ 246{
237 struct rchan_buf *buf = RELAYFS_I(inode)->buf; 247 struct rchan_buf *buf = RELAYFS_I(inode)->data;
238 kref_get(&buf->kref); 248 kref_get(&buf->kref);
239 249
240 return 0; 250 return 0;
@@ -250,7 +260,7 @@ static int relayfs_open(struct inode *inode, struct file *filp)
250static int relayfs_mmap(struct file *filp, struct vm_area_struct *vma) 260static int relayfs_mmap(struct file *filp, struct vm_area_struct *vma)
251{ 261{
252 struct inode *inode = filp->f_dentry->d_inode; 262 struct inode *inode = filp->f_dentry->d_inode;
253 return relay_mmap_buf(RELAYFS_I(inode)->buf, vma); 263 return relay_mmap_buf(RELAYFS_I(inode)->data, vma);
254} 264}
255 265
256/** 266/**
@@ -264,7 +274,7 @@ static unsigned int relayfs_poll(struct file *filp, poll_table *wait)
264{ 274{
265 unsigned int mask = 0; 275 unsigned int mask = 0;
266 struct inode *inode = filp->f_dentry->d_inode; 276 struct inode *inode = filp->f_dentry->d_inode;
267 struct rchan_buf *buf = RELAYFS_I(inode)->buf; 277 struct rchan_buf *buf = RELAYFS_I(inode)->data;
268 278
269 if (buf->finalized) 279 if (buf->finalized)
270 return POLLERR; 280 return POLLERR;
@@ -288,7 +298,7 @@ static unsigned int relayfs_poll(struct file *filp, poll_table *wait)
288 */ 298 */
289static int relayfs_release(struct inode *inode, struct file *filp) 299static int relayfs_release(struct inode *inode, struct file *filp)
290{ 300{
291 struct rchan_buf *buf = RELAYFS_I(inode)->buf; 301 struct rchan_buf *buf = RELAYFS_I(inode)->data;
292 kref_put(&buf->kref, relay_remove_buf); 302 kref_put(&buf->kref, relay_remove_buf);
293 303
294 return 0; 304 return 0;
@@ -450,7 +460,7 @@ static ssize_t relayfs_read(struct file *filp,
450 loff_t *ppos) 460 loff_t *ppos)
451{ 461{
452 struct inode *inode = filp->f_dentry->d_inode; 462 struct inode *inode = filp->f_dentry->d_inode;
453 struct rchan_buf *buf = RELAYFS_I(inode)->buf; 463 struct rchan_buf *buf = RELAYFS_I(inode)->data;
454 size_t read_start, avail; 464 size_t read_start, avail;
455 ssize_t ret = 0; 465 ssize_t ret = 0;
456 void *from; 466 void *from;
@@ -485,7 +495,7 @@ static struct inode *relayfs_alloc_inode(struct super_block *sb)
485 struct relayfs_inode_info *p = kmem_cache_alloc(relayfs_inode_cachep, SLAB_KERNEL); 495 struct relayfs_inode_info *p = kmem_cache_alloc(relayfs_inode_cachep, SLAB_KERNEL);
486 if (!p) 496 if (!p)
487 return NULL; 497 return NULL;
488 p->buf = NULL; 498 p->data = NULL;
489 499
490 return &p->vfs_inode; 500 return &p->vfs_inode;
491} 501}
@@ -531,7 +541,7 @@ static int relayfs_fill_super(struct super_block * sb, void * data, int silent)
531 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 541 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
532 sb->s_magic = RELAYFS_MAGIC; 542 sb->s_magic = RELAYFS_MAGIC;
533 sb->s_op = &relayfs_ops; 543 sb->s_op = &relayfs_ops;
534 inode = relayfs_get_inode(sb, mode, NULL); 544 inode = relayfs_get_inode(sb, mode, NULL, NULL);
535 545
536 if (!inode) 546 if (!inode)
537 return -ENOMEM; 547 return -ENOMEM;
@@ -589,6 +599,7 @@ module_exit(exit_relayfs_fs)
589EXPORT_SYMBOL_GPL(relayfs_file_operations); 599EXPORT_SYMBOL_GPL(relayfs_file_operations);
590EXPORT_SYMBOL_GPL(relayfs_create_dir); 600EXPORT_SYMBOL_GPL(relayfs_create_dir);
591EXPORT_SYMBOL_GPL(relayfs_remove_dir); 601EXPORT_SYMBOL_GPL(relayfs_remove_dir);
602EXPORT_SYMBOL_GPL(relayfs_create_file);
592 603
593MODULE_AUTHOR("Tom Zanussi <zanussi@us.ibm.com> and Karim Yaghmour <karim@opersys.com>"); 604MODULE_AUTHOR("Tom Zanussi <zanussi@us.ibm.com> and Karim Yaghmour <karim@opersys.com>");
594MODULE_DESCRIPTION("Relay Filesystem"); 605MODULE_DESCRIPTION("Relay Filesystem");
diff --git a/fs/relayfs/relay.c b/fs/relayfs/relay.c
index 7fbda177ad8f..a9cd5585c45c 100644
--- a/fs/relayfs/relay.c
+++ b/fs/relayfs/relay.c
@@ -176,7 +176,8 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan,
176 return NULL; 176 return NULL;
177 177
178 /* Create file in fs */ 178 /* Create file in fs */
179 dentry = relayfs_create_file(filename, parent, S_IRUSR, buf); 179 dentry = relayfs_create_file(filename, parent, S_IRUSR,
180 &relayfs_file_operations, buf);
180 if (!dentry) { 181 if (!dentry) {
181 relay_destroy_buf(buf); 182 relay_destroy_buf(buf);
182 return NULL; 183 return NULL;
diff --git a/fs/relayfs/relay.h b/fs/relayfs/relay.h
index c325bb243549..0993d3e5753b 100644
--- a/fs/relayfs/relay.h
+++ b/fs/relayfs/relay.h
@@ -1,10 +1,6 @@
1#ifndef _RELAY_H 1#ifndef _RELAY_H
2#define _RELAY_H 2#define _RELAY_H
3 3
4struct dentry *relayfs_create_file(const char *name,
5 struct dentry *parent,
6 int mode,
7 void *data);
8extern int relayfs_remove(struct dentry *dentry); 4extern int relayfs_remove(struct dentry *dentry);
9extern int relay_buf_empty(struct rchan_buf *buf); 5extern int relay_buf_empty(struct rchan_buf *buf);
10extern void relay_destroy_channel(struct kref *kref); 6extern void relay_destroy_channel(struct kref *kref);
diff --git a/include/linux/relayfs_fs.h b/include/linux/relayfs_fs.h
index fb7e80737325..a122df2d9880 100644
--- a/include/linux/relayfs_fs.h
+++ b/include/linux/relayfs_fs.h
@@ -70,7 +70,7 @@ struct rchan
70struct relayfs_inode_info 70struct relayfs_inode_info
71{ 71{
72 struct inode vfs_inode; 72 struct inode vfs_inode;
73 struct rchan_buf *buf; 73 void *data;
74}; 74};
75 75
76static inline struct relayfs_inode_info *RELAYFS_I(struct inode *inode) 76static inline struct relayfs_inode_info *RELAYFS_I(struct inode *inode)
@@ -148,6 +148,11 @@ extern size_t relay_switch_subbuf(struct rchan_buf *buf,
148extern struct dentry *relayfs_create_dir(const char *name, 148extern struct dentry *relayfs_create_dir(const char *name,
149 struct dentry *parent); 149 struct dentry *parent);
150extern int relayfs_remove_dir(struct dentry *dentry); 150extern int relayfs_remove_dir(struct dentry *dentry);
151extern struct dentry *relayfs_create_file(const char *name,
152 struct dentry *parent,
153 int mode,
154 struct file_operations *fops,
155 void *data);
151 156
152/** 157/**
153 * relay_write - write data into the channel 158 * relay_write - write data into the channel