diff options
Diffstat (limited to 'fs/relayfs/inode.c')
-rw-r--r-- | fs/relayfs/inode.c | 41 |
1 files changed, 26 insertions, 15 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 | ||
36 | static struct inode *relayfs_get_inode(struct super_block *sb, int mode, | 36 | static 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, | |||
82 | static struct dentry *relayfs_create_entry(const char *name, | 85 | static 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 | */ |
154 | struct dentry *relayfs_create_file(const char *name, struct dentry *parent, | 159 | struct 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, | |||
173 | struct dentry *relayfs_create_dir(const char *name, struct dentry *parent) | 183 | struct 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 | */ |
235 | static int relayfs_open(struct inode *inode, struct file *filp) | 245 | static 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) | |||
250 | static int relayfs_mmap(struct file *filp, struct vm_area_struct *vma) | 260 | static 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 | */ |
289 | static int relayfs_release(struct inode *inode, struct file *filp) | 299 | static 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) | |||
589 | EXPORT_SYMBOL_GPL(relayfs_file_operations); | 599 | EXPORT_SYMBOL_GPL(relayfs_file_operations); |
590 | EXPORT_SYMBOL_GPL(relayfs_create_dir); | 600 | EXPORT_SYMBOL_GPL(relayfs_create_dir); |
591 | EXPORT_SYMBOL_GPL(relayfs_remove_dir); | 601 | EXPORT_SYMBOL_GPL(relayfs_remove_dir); |
602 | EXPORT_SYMBOL_GPL(relayfs_create_file); | ||
592 | 603 | ||
593 | MODULE_AUTHOR("Tom Zanussi <zanussi@us.ibm.com> and Karim Yaghmour <karim@opersys.com>"); | 604 | MODULE_AUTHOR("Tom Zanussi <zanussi@us.ibm.com> and Karim Yaghmour <karim@opersys.com>"); |
594 | MODULE_DESCRIPTION("Relay Filesystem"); | 605 | MODULE_DESCRIPTION("Relay Filesystem"); |