diff options
Diffstat (limited to 'fs/hppfs')
-rw-r--r-- | fs/hppfs/hppfs_kern.c | 82 |
1 files changed, 30 insertions, 52 deletions
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c index 8601d8ef3b55..65077aa90f0a 100644 --- a/fs/hppfs/hppfs_kern.c +++ b/fs/hppfs/hppfs_kern.c | |||
@@ -33,7 +33,7 @@ struct hppfs_private { | |||
33 | }; | 33 | }; |
34 | 34 | ||
35 | struct hppfs_inode_info { | 35 | struct hppfs_inode_info { |
36 | struct dentry *proc_dentry; | 36 | struct dentry *proc_dentry; |
37 | struct inode vfs_inode; | 37 | struct inode vfs_inode; |
38 | }; | 38 | }; |
39 | 39 | ||
@@ -52,7 +52,7 @@ static int is_pid(struct dentry *dentry) | |||
52 | int i; | 52 | int i; |
53 | 53 | ||
54 | sb = dentry->d_sb; | 54 | sb = dentry->d_sb; |
55 | if ((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root)) | 55 | if (dentry->d_parent != sb->s_root) |
56 | return 0; | 56 | return 0; |
57 | 57 | ||
58 | for (i = 0; i < dentry->d_name.len; i++) { | 58 | for (i = 0; i < dentry->d_name.len; i++) { |
@@ -136,7 +136,7 @@ static int file_removed(struct dentry *dentry, const char *file) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, | 138 | static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, |
139 | struct nameidata *nd) | 139 | struct nameidata *nd) |
140 | { | 140 | { |
141 | struct dentry *proc_dentry, *new, *parent; | 141 | struct dentry *proc_dentry, *new, *parent; |
142 | struct inode *inode; | 142 | struct inode *inode; |
@@ -254,6 +254,8 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count, | |||
254 | int err; | 254 | int err; |
255 | 255 | ||
256 | if (hppfs->contents != NULL) { | 256 | if (hppfs->contents != NULL) { |
257 | int rem; | ||
258 | |||
257 | if (*ppos >= hppfs->len) | 259 | if (*ppos >= hppfs->len) |
258 | return 0; | 260 | return 0; |
259 | 261 | ||
@@ -267,8 +269,10 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count, | |||
267 | 269 | ||
268 | if (off + count > hppfs->len) | 270 | if (off + count > hppfs->len) |
269 | count = hppfs->len - off; | 271 | count = hppfs->len - off; |
270 | copy_to_user(buf, &data->contents[off], count); | 272 | rem = copy_to_user(buf, &data->contents[off], count); |
271 | *ppos += count; | 273 | *ppos += count - rem; |
274 | if (rem > 0) | ||
275 | return -EFAULT; | ||
272 | } else if (hppfs->host_fd != -1) { | 276 | } else if (hppfs->host_fd != -1) { |
273 | err = os_seek_file(hppfs->host_fd, *ppos); | 277 | err = os_seek_file(hppfs->host_fd, *ppos); |
274 | if (err) { | 278 | if (err) { |
@@ -285,21 +289,15 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count, | |||
285 | return count; | 289 | return count; |
286 | } | 290 | } |
287 | 291 | ||
288 | static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len, | 292 | static ssize_t hppfs_write(struct file *file, const char __user *buf, |
289 | loff_t *ppos) | 293 | size_t len, loff_t *ppos) |
290 | { | 294 | { |
291 | struct hppfs_private *data = file->private_data; | 295 | struct hppfs_private *data = file->private_data; |
292 | struct file *proc_file = data->proc_file; | 296 | struct file *proc_file = data->proc_file; |
293 | ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); | 297 | ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); |
294 | int err; | ||
295 | 298 | ||
296 | write = proc_file->f_path.dentry->d_inode->i_fop->write; | 299 | write = proc_file->f_path.dentry->d_inode->i_fop->write; |
297 | 300 | return (*write)(proc_file, buf, len, ppos); | |
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; | ||
301 | |||
302 | return err; | ||
303 | } | 301 | } |
304 | 302 | ||
305 | static int open_host_sock(char *host_file, int *filter_out) | 303 | static int open_host_sock(char *host_file, int *filter_out) |
@@ -357,7 +355,7 @@ static struct hppfs_data *hppfs_get_data(int fd, int filter, | |||
357 | 355 | ||
358 | if (filter) { | 356 | if (filter) { |
359 | while ((n = read_proc(proc_file, data->contents, | 357 | while ((n = read_proc(proc_file, data->contents, |
360 | sizeof(data->contents), NULL, 0)) > 0) | 358 | sizeof(data->contents), NULL, 0)) > 0) |
361 | os_write_file(fd, data->contents, n); | 359 | os_write_file(fd, data->contents, n); |
362 | err = os_shutdown_socket(fd, 0, 1); | 360 | err = os_shutdown_socket(fd, 0, 1); |
363 | if (err) { | 361 | if (err) { |
@@ -429,8 +427,8 @@ static int file_mode(int fmode) | |||
429 | static int hppfs_open(struct inode *inode, struct file *file) | 427 | static int hppfs_open(struct inode *inode, struct file *file) |
430 | { | 428 | { |
431 | struct hppfs_private *data; | 429 | struct hppfs_private *data; |
432 | struct dentry *proc_dentry; | ||
433 | struct vfsmount *proc_mnt; | 430 | struct vfsmount *proc_mnt; |
431 | struct dentry *proc_dentry; | ||
434 | char *host_file; | 432 | char *host_file; |
435 | int err, fd, type, filter; | 433 | int err, fd, type, filter; |
436 | 434 | ||
@@ -492,8 +490,8 @@ static int hppfs_open(struct inode *inode, struct file *file) | |||
492 | static int hppfs_dir_open(struct inode *inode, struct file *file) | 490 | static int hppfs_dir_open(struct inode *inode, struct file *file) |
493 | { | 491 | { |
494 | struct hppfs_private *data; | 492 | struct hppfs_private *data; |
495 | struct dentry *proc_dentry; | ||
496 | struct vfsmount *proc_mnt; | 493 | struct vfsmount *proc_mnt; |
494 | struct dentry *proc_dentry; | ||
497 | int err; | 495 | int err; |
498 | 496 | ||
499 | err = -ENOMEM; | 497 | err = -ENOMEM; |
@@ -620,6 +618,9 @@ static struct inode *hppfs_alloc_inode(struct super_block *sb) | |||
620 | 618 | ||
621 | void hppfs_delete_inode(struct inode *ino) | 619 | void hppfs_delete_inode(struct inode *ino) |
622 | { | 620 | { |
621 | dput(HPPFS_I(ino)->proc_dentry); | ||
622 | mntput(ino->i_sb->s_fs_info); | ||
623 | |||
623 | clear_inode(ino); | 624 | clear_inode(ino); |
624 | } | 625 | } |
625 | 626 | ||
@@ -628,69 +629,46 @@ static void hppfs_destroy_inode(struct inode *inode) | |||
628 | kfree(HPPFS_I(inode)); | 629 | kfree(HPPFS_I(inode)); |
629 | } | 630 | } |
630 | 631 | ||
631 | static void hppfs_put_super(struct super_block *sb) | ||
632 | { | ||
633 | mntput(sb->s_fs_info); | ||
634 | } | ||
635 | |||
636 | static const struct super_operations hppfs_sbops = { | 632 | static const struct super_operations hppfs_sbops = { |
637 | .alloc_inode = hppfs_alloc_inode, | 633 | .alloc_inode = hppfs_alloc_inode, |
638 | .destroy_inode = hppfs_destroy_inode, | 634 | .destroy_inode = hppfs_destroy_inode, |
639 | .delete_inode = hppfs_delete_inode, | 635 | .delete_inode = hppfs_delete_inode, |
640 | .statfs = hppfs_statfs, | 636 | .statfs = hppfs_statfs, |
641 | .put_super = hppfs_put_super, | ||
642 | }; | 637 | }; |
643 | 638 | ||
644 | static int hppfs_readlink(struct dentry *dentry, char __user *buffer, | 639 | static int hppfs_readlink(struct dentry *dentry, char __user *buffer, |
645 | int buflen) | 640 | int buflen) |
646 | { | 641 | { |
647 | struct file *proc_file; | ||
648 | struct dentry *proc_dentry; | 642 | struct dentry *proc_dentry; |
649 | struct vfsmount *proc_mnt; | ||
650 | int ret; | ||
651 | 643 | ||
652 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; | 644 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; |
653 | proc_mnt = dentry->d_sb->s_fs_info; | 645 | return proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, |
654 | 646 | buflen); | |
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); | ||
658 | |||
659 | ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen); | ||
660 | |||
661 | fput(proc_file); | ||
662 | |||
663 | return ret; | ||
664 | } | 647 | } |
665 | 648 | ||
666 | static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) | 649 | static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) |
667 | { | 650 | { |
668 | struct file *proc_file; | ||
669 | struct dentry *proc_dentry; | 651 | struct dentry *proc_dentry; |
670 | struct vfsmount *proc_mnt; | ||
671 | void *ret; | ||
672 | 652 | ||
673 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; | 653 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; |
674 | proc_mnt = dentry->d_sb->s_fs_info; | ||
675 | |||
676 | proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY); | ||
677 | if (IS_ERR(proc_file)) | ||
678 | return proc_file; | ||
679 | |||
680 | ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd); | ||
681 | 654 | ||
682 | fput(proc_file); | 655 | return proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd); |
656 | } | ||
683 | 657 | ||
684 | return ret; | 658 | int hppfs_permission(struct inode *inode, int mask, struct nameidata *nd) |
659 | { | ||
660 | return generic_permission(inode, mask, NULL); | ||
685 | } | 661 | } |
686 | 662 | ||
687 | static const struct inode_operations hppfs_dir_iops = { | 663 | static const struct inode_operations hppfs_dir_iops = { |
688 | .lookup = hppfs_lookup, | 664 | .lookup = hppfs_lookup, |
665 | .permission = hppfs_permission, | ||
689 | }; | 666 | }; |
690 | 667 | ||
691 | static const struct inode_operations hppfs_link_iops = { | 668 | static const struct inode_operations hppfs_link_iops = { |
692 | .readlink = hppfs_readlink, | 669 | .readlink = hppfs_readlink, |
693 | .follow_link = hppfs_follow_link, | 670 | .follow_link = hppfs_follow_link, |
671 | .permission = hppfs_permission, | ||
694 | }; | 672 | }; |
695 | 673 | ||
696 | static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) | 674 | static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) |
@@ -712,7 +690,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) | |||
712 | inode->i_fop = &hppfs_file_fops; | 690 | inode->i_fop = &hppfs_file_fops; |
713 | } | 691 | } |
714 | 692 | ||
715 | HPPFS_I(inode)->proc_dentry = dentry; | 693 | HPPFS_I(inode)->proc_dentry = dget(dentry); |
716 | 694 | ||
717 | inode->i_uid = proc_ino->i_uid; | 695 | inode->i_uid = proc_ino->i_uid; |
718 | inode->i_gid = proc_ino->i_gid; | 696 | inode->i_gid = proc_ino->i_gid; |
@@ -725,7 +703,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) | |||
725 | inode->i_size = proc_ino->i_size; | 703 | inode->i_size = proc_ino->i_size; |
726 | inode->i_blocks = proc_ino->i_blocks; | 704 | inode->i_blocks = proc_ino->i_blocks; |
727 | 705 | ||
728 | return 0; | 706 | return inode; |
729 | } | 707 | } |
730 | 708 | ||
731 | static int hppfs_fill_super(struct super_block *sb, void *d, int silent) | 709 | static int hppfs_fill_super(struct super_block *sb, void *d, int silent) |