diff options
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 120 |
1 files changed, 77 insertions, 43 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 2940b926648c..d8c78150e9ca 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -539,6 +539,68 @@ rpc_get_inode(struct super_block *sb, umode_t mode) | |||
539 | return inode; | 539 | return inode; |
540 | } | 540 | } |
541 | 541 | ||
542 | static int __rpc_create_common(struct inode *dir, struct dentry *dentry, | ||
543 | umode_t mode, | ||
544 | const struct file_operations *i_fop, | ||
545 | void *private) | ||
546 | { | ||
547 | struct inode *inode; | ||
548 | |||
549 | BUG_ON(!d_unhashed(dentry)); | ||
550 | inode = rpc_get_inode(dir->i_sb, mode); | ||
551 | if (!inode) | ||
552 | goto out_err; | ||
553 | inode->i_ino = iunique(dir->i_sb, 100); | ||
554 | if (i_fop) | ||
555 | inode->i_fop = i_fop; | ||
556 | if (private) | ||
557 | rpc_inode_setowner(inode, private); | ||
558 | d_add(dentry, inode); | ||
559 | return 0; | ||
560 | out_err: | ||
561 | printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n", | ||
562 | __FILE__, __func__, dentry->d_name.name); | ||
563 | dput(dentry); | ||
564 | return -ENOMEM; | ||
565 | } | ||
566 | |||
567 | static int __rpc_mkdir(struct inode *dir, struct dentry *dentry, | ||
568 | umode_t mode, | ||
569 | const struct file_operations *i_fop, | ||
570 | void *private) | ||
571 | { | ||
572 | int err; | ||
573 | |||
574 | err = __rpc_create_common(dir, dentry, S_IFDIR | mode, i_fop, private); | ||
575 | if (err) | ||
576 | return err; | ||
577 | inc_nlink(dir); | ||
578 | fsnotify_mkdir(dir, dentry); | ||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | static int __rpc_mkpipe(struct inode *dir, struct dentry *dentry, | ||
583 | umode_t mode, | ||
584 | const struct file_operations *i_fop, | ||
585 | void *private, | ||
586 | const struct rpc_pipe_ops *ops, | ||
587 | int flags) | ||
588 | { | ||
589 | struct rpc_inode *rpci; | ||
590 | int err; | ||
591 | |||
592 | err = __rpc_create_common(dir, dentry, S_IFIFO | mode, i_fop, private); | ||
593 | if (err) | ||
594 | return err; | ||
595 | rpci = RPC_I(dentry->d_inode); | ||
596 | rpci->nkern_readwriters = 1; | ||
597 | rpci->private = private; | ||
598 | rpci->flags = flags; | ||
599 | rpci->ops = ops; | ||
600 | fsnotify_create(dir, dentry); | ||
601 | return 0; | ||
602 | } | ||
603 | |||
542 | /* | 604 | /* |
543 | * FIXME: This probably has races. | 605 | * FIXME: This probably has races. |
544 | */ | 606 | */ |
@@ -629,25 +691,6 @@ out_bad: | |||
629 | } | 691 | } |
630 | 692 | ||
631 | static int | 693 | static int |
632 | __rpc_mkdir(struct inode *dir, struct dentry *dentry) | ||
633 | { | ||
634 | struct inode *inode; | ||
635 | |||
636 | inode = rpc_get_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO); | ||
637 | if (!inode) | ||
638 | goto out_err; | ||
639 | inode->i_ino = iunique(dir->i_sb, 100); | ||
640 | d_instantiate(dentry, inode); | ||
641 | inc_nlink(dir); | ||
642 | fsnotify_mkdir(dir, dentry); | ||
643 | return 0; | ||
644 | out_err: | ||
645 | printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n", | ||
646 | __FILE__, __func__, dentry->d_name.name); | ||
647 | return -ENOMEM; | ||
648 | } | ||
649 | |||
650 | static int | ||
651 | __rpc_rmdir(struct inode *dir, struct dentry *dentry) | 694 | __rpc_rmdir(struct inode *dir, struct dentry *dentry) |
652 | { | 695 | { |
653 | int error; | 696 | int error; |
@@ -717,9 +760,9 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client) | |||
717 | if (IS_ERR(dentry)) | 760 | if (IS_ERR(dentry)) |
718 | return dentry; | 761 | return dentry; |
719 | dir = nd.path.dentry->d_inode; | 762 | dir = nd.path.dentry->d_inode; |
720 | if ((error = __rpc_mkdir(dir, dentry)) != 0) | 763 | error = __rpc_mkdir(dir, dentry, S_IRUGO | S_IXUGO, NULL, rpc_client); |
721 | goto err_dput; | 764 | if (error != 0) |
722 | RPC_I(dentry->d_inode)->private = rpc_client; | 765 | goto out_err; |
723 | error = rpc_populate(dentry, authfiles, | 766 | error = rpc_populate(dentry, authfiles, |
724 | RPCAUTH_info, RPCAUTH_EOF); | 767 | RPCAUTH_info, RPCAUTH_EOF); |
725 | if (error) | 768 | if (error) |
@@ -732,8 +775,7 @@ out: | |||
732 | err_depopulate: | 775 | err_depopulate: |
733 | rpc_depopulate(dentry, RPCAUTH_info, RPCAUTH_EOF); | 776 | rpc_depopulate(dentry, RPCAUTH_info, RPCAUTH_EOF); |
734 | __rpc_rmdir(dir, dentry); | 777 | __rpc_rmdir(dir, dentry); |
735 | err_dput: | 778 | out_err: |
736 | dput(dentry); | ||
737 | printk(KERN_WARNING "%s: %s() failed to create directory %s (errno = %d)\n", | 779 | printk(KERN_WARNING "%s: %s() failed to create directory %s (errno = %d)\n", |
738 | __FILE__, __func__, path, error); | 780 | __FILE__, __func__, path, error); |
739 | dentry = ERR_PTR(error); | 781 | dentry = ERR_PTR(error); |
@@ -787,9 +829,9 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name, | |||
787 | int flags) | 829 | int flags) |
788 | { | 830 | { |
789 | struct dentry *dentry; | 831 | struct dentry *dentry; |
790 | struct inode *dir, *inode; | 832 | struct inode *dir = parent->d_inode; |
791 | struct rpc_inode *rpci; | ||
792 | umode_t umode = S_IFIFO | S_IRUSR | S_IWUSR; | 833 | umode_t umode = S_IFIFO | S_IRUSR | S_IWUSR; |
834 | int err; | ||
793 | 835 | ||
794 | if (ops->upcall == NULL) | 836 | if (ops->upcall == NULL) |
795 | umode &= ~S_IRUGO; | 837 | umode &= ~S_IRUGO; |
@@ -801,7 +843,7 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name, | |||
801 | return dentry; | 843 | return dentry; |
802 | dir = parent->d_inode; | 844 | dir = parent->d_inode; |
803 | if (dentry->d_inode) { | 845 | if (dentry->d_inode) { |
804 | rpci = RPC_I(dentry->d_inode); | 846 | struct rpc_inode *rpci = RPC_I(dentry->d_inode); |
805 | if (rpci->private != private || | 847 | if (rpci->private != private || |
806 | rpci->ops != ops || | 848 | rpci->ops != ops || |
807 | rpci->flags != flags) { | 849 | rpci->flags != flags) { |
@@ -811,28 +853,20 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name, | |||
811 | rpci->nkern_readwriters++; | 853 | rpci->nkern_readwriters++; |
812 | goto out; | 854 | goto out; |
813 | } | 855 | } |
814 | inode = rpc_get_inode(dir->i_sb, umode); | 856 | |
815 | if (!inode) | 857 | err = __rpc_mkpipe(dir, dentry, umode, &rpc_pipe_fops, |
816 | goto err_dput; | 858 | private, ops, flags); |
817 | inode->i_ino = iunique(dir->i_sb, 100); | 859 | if (err) |
818 | inode->i_fop = &rpc_pipe_fops; | 860 | goto out_err; |
819 | d_instantiate(dentry, inode); | ||
820 | rpci = RPC_I(inode); | ||
821 | rpci->private = private; | ||
822 | rpci->flags = flags; | ||
823 | rpci->ops = ops; | ||
824 | rpci->nkern_readwriters = 1; | ||
825 | fsnotify_create(dir, dentry); | ||
826 | dget(dentry); | 861 | dget(dentry); |
827 | out: | 862 | out: |
828 | mutex_unlock(&dir->i_mutex); | 863 | mutex_unlock(&dir->i_mutex); |
829 | return dentry; | 864 | return dentry; |
830 | err_dput: | 865 | out_err: |
831 | dput(dentry); | 866 | dentry = ERR_PTR(err); |
832 | dentry = ERR_PTR(-ENOMEM); | ||
833 | printk(KERN_WARNING "%s: %s() failed to create pipe %s/%s (errno = %d)\n", | 867 | printk(KERN_WARNING "%s: %s() failed to create pipe %s/%s (errno = %d)\n", |
834 | __FILE__, __func__, parent->d_name.name, name, | 868 | __FILE__, __func__, parent->d_name.name, name, |
835 | -ENOMEM); | 869 | err); |
836 | goto out; | 870 | goto out; |
837 | } | 871 | } |
838 | EXPORT_SYMBOL_GPL(rpc_mkpipe); | 872 | EXPORT_SYMBOL_GPL(rpc_mkpipe); |