2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
6 #include <linux/ctype.h>
7 #include <linux/dcache.h>
8 #include <linux/file.h>
10 #include <linux/init.h>
11 #include <linux/kernel.h>
12 #include <linux/list.h>
13 #include <linux/module.h>
14 #include <linux/mount.h>
15 #include <linux/slab.h>
16 #include <linux/statfs.h>
17 #include <linux/types.h>
18 #include <asm/uaccess.h>
21 static struct inode
*get_inode(struct super_block
*, struct dentry
*);
24 struct list_head list
;
25 char contents
[PAGE_SIZE
- sizeof(struct list_head
)];
28 struct hppfs_private
{
29 struct file
*proc_file
;
32 struct hppfs_data
*contents
;
35 struct hppfs_inode_info
{
36 struct dentry
*proc_dentry
;
37 struct inode vfs_inode
;
40 static inline struct hppfs_inode_info
*HPPFS_I(struct inode
*inode
)
42 return container_of(inode
, struct hppfs_inode_info
, vfs_inode
);
45 #define HPPFS_SUPER_MAGIC 0xb00000ee
47 static const struct super_operations hppfs_sbops
;
49 static int is_pid(struct dentry
*dentry
)
51 struct super_block
*sb
;
55 if ((sb
->s_op
!= &hppfs_sbops
) || (dentry
->d_parent
!= sb
->s_root
))
58 for (i
= 0; i
< dentry
->d_name
.len
; i
++) {
59 if (!isdigit(dentry
->d_name
.name
[i
]))
65 static char *dentry_name(struct dentry
*dentry
, int extra
)
67 struct dentry
*parent
;
74 while (parent
->d_parent
!= parent
) {
76 len
+= strlen("pid") + 1;
77 else len
+= parent
->d_name
.len
+ 1;
78 parent
= parent
->d_parent
;
83 name
= kmalloc(len
+ extra
+ 1, GFP_KERNEL
);
89 while (parent
->d_parent
!= parent
) {
92 seg_len
= strlen("pid");
95 seg_name
= parent
->d_name
.name
;
96 seg_len
= parent
->d_name
.len
;
101 strncpy(&name
[len
+ 1], seg_name
, seg_len
);
102 parent
= parent
->d_parent
;
104 strncpy(name
, root
, strlen(root
));
108 static int file_removed(struct dentry
*dentry
, const char *file
)
115 extra
+= strlen(file
) + 1;
117 host_file
= dentry_name(dentry
, extra
+ strlen("/remove"));
118 if (host_file
== NULL
) {
119 printk(KERN_ERR
"file_removed : allocation failed\n");
124 strcat(host_file
, "/");
125 strcat(host_file
, file
);
127 strcat(host_file
, "/remove");
129 fd
= os_open_file(host_file
, of_read(OPENFLAGS()), 0);
138 static struct dentry
*hppfs_lookup(struct inode
*ino
, struct dentry
*dentry
,
139 struct nameidata
*nd
)
141 struct dentry
*proc_dentry
, *new, *parent
;
145 deleted
= file_removed(dentry
, NULL
);
147 return ERR_PTR(deleted
);
149 return ERR_PTR(-ENOENT
);
152 parent
= HPPFS_I(ino
)->proc_dentry
;
153 mutex_lock(&parent
->d_inode
->i_mutex
);
154 proc_dentry
= d_lookup(parent
, &dentry
->d_name
);
155 if (proc_dentry
== NULL
) {
156 proc_dentry
= d_alloc(parent
, &dentry
->d_name
);
157 if (proc_dentry
== NULL
) {
158 mutex_unlock(&parent
->d_inode
->i_mutex
);
161 new = (*parent
->d_inode
->i_op
->lookup
)(parent
->d_inode
,
168 mutex_unlock(&parent
->d_inode
->i_mutex
);
170 if (IS_ERR(proc_dentry
))
174 inode
= get_inode(ino
->i_sb
, proc_dentry
);
178 d_add(dentry
, inode
);
187 static const struct inode_operations hppfs_file_iops
= {
190 static ssize_t
read_proc(struct file
*file
, char __user
*buf
, ssize_t count
,
191 loff_t
*ppos
, int is_user
)
193 ssize_t (*read
)(struct file
*, char __user
*, size_t, loff_t
*);
196 read
= file
->f_path
.dentry
->d_inode
->i_fop
->read
;
201 n
= (*read
)(file
, buf
, count
, &file
->f_pos
);
211 static ssize_t
hppfs_read_file(int fd
, char __user
*buf
, ssize_t count
)
218 new_buf
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
219 if (new_buf
== NULL
) {
220 printk(KERN_ERR
"hppfs_read_file : kmalloc failed\n");
225 cur
= min_t(ssize_t
, count
, PAGE_SIZE
);
226 err
= os_read_file(fd
, new_buf
, cur
);
228 printk(KERN_ERR
"hppfs_read : read failed, "
229 "errno = %d\n", err
);
235 if (copy_to_user(buf
, new_buf
, err
)) {
248 static ssize_t
hppfs_read(struct file
*file
, char __user
*buf
, size_t count
,
251 struct hppfs_private
*hppfs
= file
->private_data
;
252 struct hppfs_data
*data
;
256 if (hppfs
->contents
!= NULL
) {
257 if (*ppos
>= hppfs
->len
)
260 data
= hppfs
->contents
;
262 while (off
>= sizeof(data
->contents
)) {
263 data
= list_entry(data
->list
.next
, struct hppfs_data
,
265 off
-= sizeof(data
->contents
);
268 if (off
+ count
> hppfs
->len
)
269 count
= hppfs
->len
- off
;
270 copy_to_user(buf
, &data
->contents
[off
], count
);
272 } else if (hppfs
->host_fd
!= -1) {
273 err
= os_seek_file(hppfs
->host_fd
, *ppos
);
275 printk(KERN_ERR
"hppfs_read : seek failed, "
276 "errno = %d\n", err
);
279 count
= hppfs_read_file(hppfs
->host_fd
, buf
, count
);
283 else count
= read_proc(hppfs
->proc_file
, buf
, count
, ppos
, 1);
288 static ssize_t
hppfs_write(struct file
*file
, const char __user
*buf
, size_t len
,
291 struct hppfs_private
*data
= file
->private_data
;
292 struct file
*proc_file
= data
->proc_file
;
293 ssize_t (*write
)(struct file
*, const char __user
*, size_t, loff_t
*);
296 write
= proc_file
->f_path
.dentry
->d_inode
->i_fop
->write
;
298 proc_file
->f_pos
= file
->f_pos
;
299 err
= (*write
)(proc_file
, buf
, len
, &proc_file
->f_pos
);
300 file
->f_pos
= proc_file
->f_pos
;
305 static int open_host_sock(char *host_file
, int *filter_out
)
310 end
= &host_file
[strlen(host_file
)];
313 fd
= os_connect_socket(host_file
);
319 fd
= os_connect_socket(host_file
);
323 static void free_contents(struct hppfs_data
*head
)
325 struct hppfs_data
*data
;
326 struct list_head
*ele
, *next
;
331 list_for_each_safe(ele
, next
, &head
->list
) {
332 data
= list_entry(ele
, struct hppfs_data
, list
);
338 static struct hppfs_data
*hppfs_get_data(int fd
, int filter
,
339 struct file
*proc_file
,
340 struct file
*hppfs_file
,
343 struct hppfs_data
*data
, *new, *head
;
347 data
= kmalloc(sizeof(*data
), GFP_KERNEL
);
349 printk(KERN_ERR
"hppfs_get_data : head allocation failed\n");
353 INIT_LIST_HEAD(&data
->list
);
359 while ((n
= read_proc(proc_file
, data
->contents
,
360 sizeof(data
->contents
), NULL
, 0)) > 0)
361 os_write_file(fd
, data
->contents
, n
);
362 err
= os_shutdown_socket(fd
, 0, 1);
364 printk(KERN_ERR
"hppfs_get_data : failed to shut down "
370 n
= os_read_file(fd
, data
->contents
, sizeof(data
->contents
));
373 printk(KERN_ERR
"hppfs_get_data : read failed, "
374 "errno = %d\n", err
);
381 if (n
< sizeof(data
->contents
))
384 new = kmalloc(sizeof(*data
), GFP_KERNEL
);
386 printk(KERN_ERR
"hppfs_get_data : data allocation "
392 INIT_LIST_HEAD(&new->list
);
393 list_add(&new->list
, &data
->list
);
404 static struct hppfs_private
*hppfs_data(void)
406 struct hppfs_private
*data
;
408 data
= kmalloc(sizeof(*data
), GFP_KERNEL
);
412 *data
= ((struct hppfs_private
) { .host_fd
= -1,
414 .contents
= NULL
} );
418 static int file_mode(int fmode
)
420 if (fmode
== (FMODE_READ
| FMODE_WRITE
))
422 if (fmode
== FMODE_READ
)
424 if (fmode
== FMODE_WRITE
)
429 static int hppfs_open(struct inode
*inode
, struct file
*file
)
431 struct hppfs_private
*data
;
432 struct dentry
*proc_dentry
;
433 struct vfsmount
*proc_mnt
;
435 int err
, fd
, type
, filter
;
442 host_file
= dentry_name(file
->f_path
.dentry
, strlen("/rw"));
443 if (host_file
== NULL
)
446 proc_dentry
= HPPFS_I(inode
)->proc_dentry
;
447 proc_mnt
= inode
->i_sb
->s_fs_info
;
449 /* XXX This isn't closed anywhere */
450 data
->proc_file
= dentry_open(dget(proc_dentry
), mntget(proc_mnt
),
451 file_mode(file
->f_mode
));
452 err
= PTR_ERR(data
->proc_file
);
453 if (IS_ERR(data
->proc_file
))
456 type
= os_file_type(host_file
);
457 if (type
== OS_TYPE_FILE
) {
458 fd
= os_open_file(host_file
, of_read(OPENFLAGS()), 0);
462 printk(KERN_ERR
"hppfs_open : failed to open '%s', "
463 "errno = %d\n", host_file
, -fd
);
465 data
->contents
= NULL
;
466 } else if (type
== OS_TYPE_DIR
) {
467 fd
= open_host_sock(host_file
, &filter
);
469 data
->contents
= hppfs_get_data(fd
, filter
,
472 if (!IS_ERR(data
->contents
))
475 printk(KERN_ERR
"hppfs_open : failed to open a socket "
476 "in '%s', errno = %d\n", host_file
, -fd
);
480 file
->private_data
= data
;
486 free_contents(data
->contents
);
492 static int hppfs_dir_open(struct inode
*inode
, struct file
*file
)
494 struct hppfs_private
*data
;
495 struct dentry
*proc_dentry
;
496 struct vfsmount
*proc_mnt
;
504 proc_dentry
= HPPFS_I(inode
)->proc_dentry
;
505 proc_mnt
= inode
->i_sb
->s_fs_info
;
506 data
->proc_file
= dentry_open(dget(proc_dentry
), mntget(proc_mnt
),
507 file_mode(file
->f_mode
));
508 err
= PTR_ERR(data
->proc_file
);
509 if (IS_ERR(data
->proc_file
))
512 file
->private_data
= data
;
521 static loff_t
hppfs_llseek(struct file
*file
, loff_t off
, int where
)
523 struct hppfs_private
*data
= file
->private_data
;
524 struct file
*proc_file
= data
->proc_file
;
525 loff_t (*llseek
)(struct file
*, loff_t
, int);
528 llseek
= proc_file
->f_path
.dentry
->d_inode
->i_fop
->llseek
;
529 if (llseek
!= NULL
) {
530 ret
= (*llseek
)(proc_file
, off
, where
);
535 return default_llseek(file
, off
, where
);
538 static const struct file_operations hppfs_file_fops
= {
540 .llseek
= hppfs_llseek
,
542 .write
= hppfs_write
,
546 struct hppfs_dirent
{
549 struct dentry
*dentry
;
552 static int hppfs_filldir(void *d
, const char *name
, int size
,
553 loff_t offset
, u64 inode
, unsigned int type
)
555 struct hppfs_dirent
*dirent
= d
;
557 if (file_removed(dirent
->dentry
, name
))
560 return (*dirent
->filldir
)(dirent
->vfs_dirent
, name
, size
, offset
,
564 static int hppfs_readdir(struct file
*file
, void *ent
, filldir_t filldir
)
566 struct hppfs_private
*data
= file
->private_data
;
567 struct file
*proc_file
= data
->proc_file
;
568 int (*readdir
)(struct file
*, void *, filldir_t
);
569 struct hppfs_dirent dirent
= ((struct hppfs_dirent
)
572 .dentry
= file
->f_path
.dentry
576 readdir
= proc_file
->f_path
.dentry
->d_inode
->i_fop
->readdir
;
578 proc_file
->f_pos
= file
->f_pos
;
579 err
= (*readdir
)(proc_file
, &dirent
, hppfs_filldir
);
580 file
->f_pos
= proc_file
->f_pos
;
585 static int hppfs_fsync(struct file
*file
, struct dentry
*dentry
, int datasync
)
590 static const struct file_operations hppfs_dir_fops
= {
592 .readdir
= hppfs_readdir
,
593 .open
= hppfs_dir_open
,
594 .fsync
= hppfs_fsync
,
597 static int hppfs_statfs(struct dentry
*dentry
, struct kstatfs
*sf
)
604 sf
->f_type
= HPPFS_SUPER_MAGIC
;
608 static struct inode
*hppfs_alloc_inode(struct super_block
*sb
)
610 struct hppfs_inode_info
*hi
;
612 hi
= kmalloc(sizeof(*hi
), GFP_KERNEL
);
616 hi
->proc_dentry
= NULL
;
617 inode_init_once(&hi
->vfs_inode
);
618 return &hi
->vfs_inode
;
621 void hppfs_delete_inode(struct inode
*ino
)
626 static void hppfs_destroy_inode(struct inode
*inode
)
628 kfree(HPPFS_I(inode
));
631 static void hppfs_put_super(struct super_block
*sb
)
633 mntput(sb
->s_fs_info
);
636 static const struct super_operations hppfs_sbops
= {
637 .alloc_inode
= hppfs_alloc_inode
,
638 .destroy_inode
= hppfs_destroy_inode
,
639 .delete_inode
= hppfs_delete_inode
,
640 .statfs
= hppfs_statfs
,
641 .put_super
= hppfs_put_super
,
644 static int hppfs_readlink(struct dentry
*dentry
, char __user
*buffer
,
647 struct file
*proc_file
;
648 struct dentry
*proc_dentry
;
649 struct vfsmount
*proc_mnt
;
652 proc_dentry
= HPPFS_I(dentry
->d_inode
)->proc_dentry
;
653 proc_mnt
= dentry
->d_sb
->s_fs_info
;
655 proc_file
= dentry_open(dget(proc_dentry
), mntget(proc_mnt
), O_RDONLY
);
656 if (IS_ERR(proc_file
))
657 return PTR_ERR(proc_file
);
659 ret
= proc_dentry
->d_inode
->i_op
->readlink(proc_dentry
, buffer
, buflen
);
666 static void* hppfs_follow_link(struct dentry
*dentry
, struct nameidata
*nd
)
668 struct file
*proc_file
;
669 struct dentry
*proc_dentry
;
670 struct vfsmount
*proc_mnt
;
673 proc_dentry
= HPPFS_I(dentry
->d_inode
)->proc_dentry
;
674 proc_mnt
= dentry
->d_sb
->s_fs_info
;
676 proc_file
= dentry_open(dget(proc_dentry
), mntget(proc_mnt
), O_RDONLY
);
677 if (IS_ERR(proc_file
))
680 ret
= proc_dentry
->d_inode
->i_op
->follow_link(proc_dentry
, nd
);
687 static const struct inode_operations hppfs_dir_iops
= {
688 .lookup
= hppfs_lookup
,
691 static const struct inode_operations hppfs_link_iops
= {
692 .readlink
= hppfs_readlink
,
693 .follow_link
= hppfs_follow_link
,
696 static struct inode
*get_inode(struct super_block
*sb
, struct dentry
*dentry
)
698 struct inode
*proc_ino
= dentry
->d_inode
;
699 struct inode
*inode
= new_inode(sb
);
702 return ERR_PTR(-ENOMEM
);
704 if (S_ISDIR(dentry
->d_inode
->i_mode
)) {
705 inode
->i_op
= &hppfs_dir_iops
;
706 inode
->i_fop
= &hppfs_dir_fops
;
707 } else if (S_ISLNK(dentry
->d_inode
->i_mode
)) {
708 inode
->i_op
= &hppfs_link_iops
;
709 inode
->i_fop
= &hppfs_file_fops
;
711 inode
->i_op
= &hppfs_file_iops
;
712 inode
->i_fop
= &hppfs_file_fops
;
715 HPPFS_I(inode
)->proc_dentry
= dentry
;
717 inode
->i_uid
= proc_ino
->i_uid
;
718 inode
->i_gid
= proc_ino
->i_gid
;
719 inode
->i_atime
= proc_ino
->i_atime
;
720 inode
->i_mtime
= proc_ino
->i_mtime
;
721 inode
->i_ctime
= proc_ino
->i_ctime
;
722 inode
->i_ino
= proc_ino
->i_ino
;
723 inode
->i_mode
= proc_ino
->i_mode
;
724 inode
->i_nlink
= proc_ino
->i_nlink
;
725 inode
->i_size
= proc_ino
->i_size
;
726 inode
->i_blocks
= proc_ino
->i_blocks
;
731 static int hppfs_fill_super(struct super_block
*sb
, void *d
, int silent
)
733 struct inode
*root_inode
;
734 struct vfsmount
*proc_mnt
;
737 proc_mnt
= do_kern_mount("proc", 0, "proc", NULL
);
738 if (IS_ERR(proc_mnt
))
741 sb
->s_blocksize
= 1024;
742 sb
->s_blocksize_bits
= 10;
743 sb
->s_magic
= HPPFS_SUPER_MAGIC
;
744 sb
->s_op
= &hppfs_sbops
;
745 sb
->s_fs_info
= proc_mnt
;
748 root_inode
= get_inode(sb
, proc_mnt
->mnt_sb
->s_root
);
752 sb
->s_root
= d_alloc_root(root_inode
);
766 static int hppfs_read_super(struct file_system_type
*type
,
767 int flags
, const char *dev_name
,
768 void *data
, struct vfsmount
*mnt
)
770 return get_sb_nodev(type
, flags
, data
, hppfs_fill_super
, mnt
);
773 static struct file_system_type hppfs_type
= {
774 .owner
= THIS_MODULE
,
776 .get_sb
= hppfs_read_super
,
777 .kill_sb
= kill_anon_super
,
781 static int __init
init_hppfs(void)
783 return register_filesystem(&hppfs_type
);
786 static void __exit
exit_hppfs(void)
788 unregister_filesystem(&hppfs_type
);
791 module_init(init_hppfs
)
792 module_exit(exit_hppfs
)
793 MODULE_LICENSE("GPL");