2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
7 #include <linux/module.h>
8 #include <linux/init.h>
9 #include <linux/slab.h>
10 #include <linux/list.h>
11 #include <linux/kernel.h>
12 #include <linux/ctype.h>
13 #include <linux/dcache.h>
14 #include <linux/statfs.h>
15 #include <asm/uaccess.h>
16 #include <asm/fcntl.h>
19 static int init_inode(struct inode
*inode
, struct dentry
*dentry
);
22 struct list_head list
;
23 char contents
[PAGE_SIZE
- sizeof(struct list_head
)];
26 struct hppfs_private
{
27 struct file
*proc_file
;
30 struct hppfs_data
*contents
;
33 struct hppfs_inode_info
{
34 struct dentry
*proc_dentry
;
35 struct inode vfs_inode
;
38 static inline struct hppfs_inode_info
*HPPFS_I(struct inode
*inode
)
40 return(list_entry(inode
, struct hppfs_inode_info
, vfs_inode
));
43 #define HPPFS_SUPER_MAGIC 0xb00000ee
45 static struct super_operations hppfs_sbops
;
47 static int is_pid(struct dentry
*dentry
)
49 struct super_block
*sb
;
53 if((sb
->s_op
!= &hppfs_sbops
) || (dentry
->d_parent
!= sb
->s_root
))
56 for(i
= 0; i
< dentry
->d_name
.len
; i
++){
57 if(!isdigit(dentry
->d_name
.name
[i
]))
63 static char *dentry_name(struct dentry
*dentry
, int extra
)
65 struct dentry
*parent
;
72 while(parent
->d_parent
!= parent
){
74 len
+= strlen("pid") + 1;
75 else len
+= parent
->d_name
.len
+ 1;
76 parent
= parent
->d_parent
;
81 name
= kmalloc(len
+ extra
+ 1, GFP_KERNEL
);
82 if(name
== NULL
) return(NULL
);
86 while(parent
->d_parent
!= parent
){
89 seg_len
= strlen("pid");
92 seg_name
= parent
->d_name
.name
;
93 seg_len
= parent
->d_name
.len
;
98 strncpy(&name
[len
+ 1], seg_name
, seg_len
);
99 parent
= parent
->d_parent
;
101 strncpy(name
, root
, strlen(root
));
105 struct dentry_operations hppfs_dentry_ops
= {
108 static int file_removed(struct dentry
*dentry
, const char *file
)
114 if(file
!= NULL
) extra
+= strlen(file
) + 1;
116 host_file
= dentry_name(dentry
, extra
+ strlen("/remove"));
117 if(host_file
== NULL
){
118 printk("file_removed : allocation failed\n");
123 strcat(host_file
, "/");
124 strcat(host_file
, file
);
126 strcat(host_file
, "/remove");
128 fd
= os_open_file(host_file
, of_read(OPENFLAGS()), 0);
137 static void hppfs_read_inode(struct inode
*ino
)
139 struct inode
*proc_ino
;
141 if(HPPFS_I(ino
)->proc_dentry
== NULL
)
144 proc_ino
= HPPFS_I(ino
)->proc_dentry
->d_inode
;
145 ino
->i_uid
= proc_ino
->i_uid
;
146 ino
->i_gid
= proc_ino
->i_gid
;
147 ino
->i_atime
= proc_ino
->i_atime
;
148 ino
->i_mtime
= proc_ino
->i_mtime
;
149 ino
->i_ctime
= proc_ino
->i_ctime
;
150 ino
->i_ino
= proc_ino
->i_ino
;
151 ino
->i_mode
= proc_ino
->i_mode
;
152 ino
->i_nlink
= proc_ino
->i_nlink
;
153 ino
->i_size
= proc_ino
->i_size
;
154 ino
->i_blksize
= proc_ino
->i_blksize
;
155 ino
->i_blocks
= proc_ino
->i_blocks
;
158 static struct dentry
*hppfs_lookup(struct inode
*ino
, struct dentry
*dentry
,
159 struct nameidata
*nd
)
161 struct dentry
*proc_dentry
, *new, *parent
;
165 deleted
= file_removed(dentry
, NULL
);
167 return(ERR_PTR(deleted
));
169 return(ERR_PTR(-ENOENT
));
172 parent
= HPPFS_I(ino
)->proc_dentry
;
173 down(&parent
->d_inode
->i_sem
);
174 proc_dentry
= d_lookup(parent
, &dentry
->d_name
);
175 if(proc_dentry
== NULL
){
176 proc_dentry
= d_alloc(parent
, &dentry
->d_name
);
177 if(proc_dentry
== NULL
){
178 up(&parent
->d_inode
->i_sem
);
181 new = (*parent
->d_inode
->i_op
->lookup
)(parent
->d_inode
,
188 up(&parent
->d_inode
->i_sem
);
190 if(IS_ERR(proc_dentry
))
193 inode
= iget(ino
->i_sb
, 0);
197 err
= init_inode(inode
, proc_dentry
);
201 hppfs_read_inode(inode
);
203 d_add(dentry
, inode
);
204 dentry
->d_op
= &hppfs_dentry_ops
;
212 return(ERR_PTR(err
));
215 static struct inode_operations hppfs_file_iops
= {
218 static ssize_t
read_proc(struct file
*file
, char *buf
, ssize_t count
,
219 loff_t
*ppos
, int is_user
)
221 ssize_t (*read
)(struct file
*, char *, size_t, loff_t
*);
224 read
= file
->f_dentry
->d_inode
->i_fop
->read
;
229 n
= (*read
)(file
, buf
, count
, &file
->f_pos
);
234 if(ppos
) *ppos
= file
->f_pos
;
238 static ssize_t
hppfs_read_file(int fd
, char *buf
, ssize_t count
)
245 new_buf
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
247 printk("hppfs_read_file : kmalloc failed\n");
252 cur
= min_t(ssize_t
, count
, PAGE_SIZE
);
253 err
= os_read_file(fd
, new_buf
, cur
);
255 printk("hppfs_read : read failed, errno = %d\n",
263 if(copy_to_user(buf
, new_buf
, err
)){
276 static ssize_t
hppfs_read(struct file
*file
, char *buf
, size_t count
,
279 struct hppfs_private
*hppfs
= file
->private_data
;
280 struct hppfs_data
*data
;
284 if(hppfs
->contents
!= NULL
){
285 if(*ppos
>= hppfs
->len
) return(0);
287 data
= hppfs
->contents
;
289 while(off
>= sizeof(data
->contents
)){
290 data
= list_entry(data
->list
.next
, struct hppfs_data
,
292 off
-= sizeof(data
->contents
);
295 if(off
+ count
> hppfs
->len
)
296 count
= hppfs
->len
- off
;
297 copy_to_user(buf
, &data
->contents
[off
], count
);
300 else if(hppfs
->host_fd
!= -1){
301 err
= os_seek_file(hppfs
->host_fd
, *ppos
);
303 printk("hppfs_read : seek failed, errno = %d\n", err
);
306 count
= hppfs_read_file(hppfs
->host_fd
, buf
, count
);
310 else count
= read_proc(hppfs
->proc_file
, buf
, count
, ppos
, 1);
315 static ssize_t
hppfs_write(struct file
*file
, const char *buf
, size_t len
,
318 struct hppfs_private
*data
= file
->private_data
;
319 struct file
*proc_file
= data
->proc_file
;
320 ssize_t (*write
)(struct file
*, const char *, size_t, loff_t
*);
323 write
= proc_file
->f_dentry
->d_inode
->i_fop
->write
;
325 proc_file
->f_pos
= file
->f_pos
;
326 err
= (*write
)(proc_file
, buf
, len
, &proc_file
->f_pos
);
327 file
->f_pos
= proc_file
->f_pos
;
332 static int open_host_sock(char *host_file
, int *filter_out
)
337 end
= &host_file
[strlen(host_file
)];
340 fd
= os_connect_socket(host_file
);
346 fd
= os_connect_socket(host_file
);
350 static void free_contents(struct hppfs_data
*head
)
352 struct hppfs_data
*data
;
353 struct list_head
*ele
, *next
;
355 if(head
== NULL
) return;
357 list_for_each_safe(ele
, next
, &head
->list
){
358 data
= list_entry(ele
, struct hppfs_data
, list
);
364 static struct hppfs_data
*hppfs_get_data(int fd
, int filter
,
365 struct file
*proc_file
,
366 struct file
*hppfs_file
,
369 struct hppfs_data
*data
, *new, *head
;
373 data
= kmalloc(sizeof(*data
), GFP_KERNEL
);
375 printk("hppfs_get_data : head allocation failed\n");
379 INIT_LIST_HEAD(&data
->list
);
385 while((n
= read_proc(proc_file
, data
->contents
,
386 sizeof(data
->contents
), NULL
, 0)) > 0)
387 os_write_file(fd
, data
->contents
, n
);
388 err
= os_shutdown_socket(fd
, 0, 1);
390 printk("hppfs_get_data : failed to shut down "
396 n
= os_read_file(fd
, data
->contents
, sizeof(data
->contents
));
399 printk("hppfs_get_data : read failed, errno = %d\n",
408 if(n
< sizeof(data
->contents
))
411 new = kmalloc(sizeof(*data
), GFP_KERNEL
);
413 printk("hppfs_get_data : data allocation failed\n");
418 INIT_LIST_HEAD(&new->list
);
419 list_add(&new->list
, &data
->list
);
427 return(ERR_PTR(err
));
430 static struct hppfs_private
*hppfs_data(void)
432 struct hppfs_private
*data
;
434 data
= kmalloc(sizeof(*data
), GFP_KERNEL
);
438 *data
= ((struct hppfs_private
) { .host_fd
= -1,
440 .contents
= NULL
} );
444 static int file_mode(int fmode
)
446 if(fmode
== (FMODE_READ
| FMODE_WRITE
))
448 if(fmode
== FMODE_READ
)
450 if(fmode
== FMODE_WRITE
)
455 static int hppfs_open(struct inode
*inode
, struct file
*file
)
457 struct hppfs_private
*data
;
458 struct dentry
*proc_dentry
;
460 int err
, fd
, type
, filter
;
467 host_file
= dentry_name(file
->f_dentry
, strlen("/rw"));
468 if(host_file
== NULL
)
471 proc_dentry
= HPPFS_I(inode
)->proc_dentry
;
473 /* XXX This isn't closed anywhere */
474 data
->proc_file
= dentry_open(dget(proc_dentry
), NULL
,
475 file_mode(file
->f_mode
));
476 err
= PTR_ERR(data
->proc_file
);
477 if(IS_ERR(data
->proc_file
))
480 type
= os_file_type(host_file
);
481 if(type
== OS_TYPE_FILE
){
482 fd
= os_open_file(host_file
, of_read(OPENFLAGS()), 0);
485 else printk("hppfs_open : failed to open '%s', errno = %d\n",
488 data
->contents
= NULL
;
490 else if(type
== OS_TYPE_DIR
){
491 fd
= open_host_sock(host_file
, &filter
);
493 data
->contents
= hppfs_get_data(fd
, filter
,
496 if(!IS_ERR(data
->contents
))
499 else printk("hppfs_open : failed to open a socket in "
500 "'%s', errno = %d\n", host_file
, -fd
);
504 file
->private_data
= data
;
510 free_contents(data
->contents
);
516 static int hppfs_dir_open(struct inode
*inode
, struct file
*file
)
518 struct hppfs_private
*data
;
519 struct dentry
*proc_dentry
;
527 proc_dentry
= HPPFS_I(inode
)->proc_dentry
;
528 data
->proc_file
= dentry_open(dget(proc_dentry
), NULL
,
529 file_mode(file
->f_mode
));
530 err
= PTR_ERR(data
->proc_file
);
531 if(IS_ERR(data
->proc_file
))
534 file
->private_data
= data
;
543 static loff_t
hppfs_llseek(struct file
*file
, loff_t off
, int where
)
545 struct hppfs_private
*data
= file
->private_data
;
546 struct file
*proc_file
= &data
->proc_file
;
547 loff_t (*llseek
)(struct file
*, loff_t
, int);
550 llseek
= proc_file
->f_dentry
->d_inode
->i_fop
->llseek
;
552 ret
= (*llseek
)(proc_file
, off
, where
);
557 return(default_llseek(file
, off
, where
));
560 static struct file_operations hppfs_file_fops
= {
562 .llseek
= hppfs_llseek
,
564 .write
= hppfs_write
,
568 struct hppfs_dirent
{
571 struct dentry
*dentry
;
574 static int hppfs_filldir(void *d
, const char *name
, int size
,
575 loff_t offset
, ino_t inode
, unsigned int type
)
577 struct hppfs_dirent
*dirent
= d
;
579 if(file_removed(dirent
->dentry
, name
))
582 return((*dirent
->filldir
)(dirent
->vfs_dirent
, name
, size
, offset
,
586 static int hppfs_readdir(struct file
*file
, void *ent
, filldir_t filldir
)
588 struct hppfs_private
*data
= file
->private_data
;
589 struct file
*proc_file
= &data
->proc_file
;
590 int (*readdir
)(struct file
*, void *, filldir_t
);
591 struct hppfs_dirent dirent
= ((struct hppfs_dirent
)
594 .dentry
= file
->f_dentry
} );
597 readdir
= proc_file
->f_dentry
->d_inode
->i_fop
->readdir
;
599 proc_file
->f_pos
= file
->f_pos
;
600 err
= (*readdir
)(proc_file
, &dirent
, hppfs_filldir
);
601 file
->f_pos
= proc_file
->f_pos
;
606 static int hppfs_fsync(struct file
*file
, struct dentry
*dentry
, int datasync
)
611 static struct file_operations hppfs_dir_fops
= {
613 .readdir
= hppfs_readdir
,
614 .open
= hppfs_dir_open
,
615 .fsync
= hppfs_fsync
,
618 static int hppfs_statfs(struct super_block
*sb
, struct kstatfs
*sf
)
625 sf
->f_type
= HPPFS_SUPER_MAGIC
;
629 static struct inode
*hppfs_alloc_inode(struct super_block
*sb
)
631 struct hppfs_inode_info
*hi
;
633 hi
= kmalloc(sizeof(*hi
), GFP_KERNEL
);
637 *hi
= ((struct hppfs_inode_info
) { .proc_dentry
= NULL
});
638 inode_init_once(&hi
->vfs_inode
);
639 return(&hi
->vfs_inode
);
642 void hppfs_delete_inode(struct inode
*ino
)
647 static void hppfs_destroy_inode(struct inode
*inode
)
649 kfree(HPPFS_I(inode
));
652 static struct super_operations hppfs_sbops
= {
653 .alloc_inode
= hppfs_alloc_inode
,
654 .destroy_inode
= hppfs_destroy_inode
,
655 .read_inode
= hppfs_read_inode
,
656 .delete_inode
= hppfs_delete_inode
,
657 .statfs
= hppfs_statfs
,
660 static int hppfs_readlink(struct dentry
*dentry
, char *buffer
, int buflen
)
662 struct file
*proc_file
;
663 struct dentry
*proc_dentry
;
664 int (*readlink
)(struct dentry
*, char *, int);
667 proc_dentry
= HPPFS_I(dentry
->d_inode
)->proc_dentry
;
668 proc_file
= dentry_open(dget(proc_dentry
), NULL
, O_RDONLY
);
669 err
= PTR_ERR(proc_dentry
);
670 if(IS_ERR(proc_dentry
))
673 readlink
= proc_dentry
->d_inode
->i_op
->readlink
;
674 n
= (*readlink
)(proc_dentry
, buffer
, buflen
);
681 static int hppfs_follow_link(struct dentry
*dentry
, struct nameidata
*nd
)
683 struct file
*proc_file
;
684 struct dentry
*proc_dentry
;
685 int (*follow_link
)(struct dentry
*, struct nameidata
*);
688 proc_dentry
= HPPFS_I(dentry
->d_inode
)->proc_dentry
;
689 proc_file
= dentry_open(dget(proc_dentry
), NULL
, O_RDONLY
);
690 err
= PTR_ERR(proc_dentry
);
691 if(IS_ERR(proc_dentry
))
694 follow_link
= proc_dentry
->d_inode
->i_op
->follow_link
;
695 n
= (*follow_link
)(proc_dentry
, nd
);
702 static struct inode_operations hppfs_dir_iops
= {
703 .lookup
= hppfs_lookup
,
706 static struct inode_operations hppfs_link_iops
= {
707 .readlink
= hppfs_readlink
,
708 .follow_link
= hppfs_follow_link
,
711 static int init_inode(struct inode
*inode
, struct dentry
*dentry
)
713 if(S_ISDIR(dentry
->d_inode
->i_mode
)){
714 inode
->i_op
= &hppfs_dir_iops
;
715 inode
->i_fop
= &hppfs_dir_fops
;
717 else if(S_ISLNK(dentry
->d_inode
->i_mode
)){
718 inode
->i_op
= &hppfs_link_iops
;
719 inode
->i_fop
= &hppfs_file_fops
;
722 inode
->i_op
= &hppfs_file_iops
;
723 inode
->i_fop
= &hppfs_file_fops
;
726 HPPFS_I(inode
)->proc_dentry
= dentry
;
731 static int hppfs_fill_super(struct super_block
*sb
, void *d
, int silent
)
733 struct inode
*root_inode
;
734 struct file_system_type
*procfs
;
735 struct super_block
*proc_sb
;
739 procfs
= get_fs_type("proc");
743 if(list_empty(&procfs
->fs_supers
))
746 proc_sb
= list_entry(procfs
->fs_supers
.next
, struct super_block
,
749 sb
->s_blocksize
= 1024;
750 sb
->s_blocksize_bits
= 10;
751 sb
->s_magic
= HPPFS_SUPER_MAGIC
;
752 sb
->s_op
= &hppfs_sbops
;
754 root_inode
= iget(sb
, 0);
755 if(root_inode
== NULL
)
758 err
= init_inode(root_inode
, proc_sb
->s_root
);
763 sb
->s_root
= d_alloc_root(root_inode
);
764 if(sb
->s_root
== NULL
)
767 hppfs_read_inode(root_inode
);
777 static struct super_block
*hppfs_read_super(struct file_system_type
*type
,
778 int flags
, const char *dev_name
,
781 return(get_sb_nodev(type
, flags
, data
, hppfs_fill_super
));
784 static struct file_system_type hppfs_type
= {
785 .owner
= THIS_MODULE
,
787 .get_sb
= hppfs_read_super
,
788 .kill_sb
= kill_anon_super
,
792 static int __init
init_hppfs(void)
794 return(register_filesystem(&hppfs_type
));
797 static void __exit
exit_hppfs(void)
799 unregister_filesystem(&hppfs_type
);
802 module_init(init_hppfs
)
803 module_exit(exit_hppfs
)
804 MODULE_LICENSE("GPL");
807 * Overrides for Emacs so that we follow Linus's tabbing style.
808 * Emacs will notice this stuff at the end of the file and automatically
809 * adjust the settings for this buffer only. This must remain at the end
811 * ---------------------------------------------------------------------------
813 * c-file-style: "linux"