diff options
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
| -rw-r--r-- | net/sunrpc/rpc_pipe.c | 122 |
1 files changed, 57 insertions, 65 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 8241fa726803..700c6e061a04 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | * Copyright (c) 2002, Trond Myklebust <trond.myklebust@fys.uio.no> | 8 | * Copyright (c) 2002, Trond Myklebust <trond.myklebust@fys.uio.no> |
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | #include <linux/config.h> | ||
| 12 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 13 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
| 14 | #include <linux/string.h> | 13 | #include <linux/string.h> |
| @@ -328,10 +327,8 @@ rpc_show_info(struct seq_file *m, void *v) | |||
| 328 | seq_printf(m, "RPC server: %s\n", clnt->cl_server); | 327 | seq_printf(m, "RPC server: %s\n", clnt->cl_server); |
| 329 | seq_printf(m, "service: %s (%d) version %d\n", clnt->cl_protname, | 328 | seq_printf(m, "service: %s (%d) version %d\n", clnt->cl_protname, |
| 330 | clnt->cl_prog, clnt->cl_vers); | 329 | clnt->cl_prog, clnt->cl_vers); |
| 331 | seq_printf(m, "address: %u.%u.%u.%u\n", | 330 | seq_printf(m, "address: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR)); |
| 332 | NIPQUAD(clnt->cl_xprt->addr.sin_addr.s_addr)); | 331 | seq_printf(m, "protocol: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_PROTO)); |
| 333 | seq_printf(m, "protocol: %s\n", | ||
| 334 | clnt->cl_xprt->prot == IPPROTO_UDP ? "udp" : "tcp"); | ||
| 335 | return 0; | 332 | return 0; |
| 336 | } | 333 | } |
| 337 | 334 | ||
| @@ -439,7 +436,7 @@ struct vfsmount *rpc_get_mount(void) | |||
| 439 | { | 436 | { |
| 440 | int err; | 437 | int err; |
| 441 | 438 | ||
| 442 | err = simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count); | 439 | err = simple_pin_fs(&rpc_pipe_fs_type, &rpc_mount, &rpc_mount_count); |
| 443 | if (err != 0) | 440 | if (err != 0) |
| 444 | return ERR_PTR(err); | 441 | return ERR_PTR(err); |
| 445 | return rpc_mount; | 442 | return rpc_mount; |
| @@ -491,7 +488,6 @@ rpc_get_inode(struct super_block *sb, int mode) | |||
| 491 | return NULL; | 488 | return NULL; |
| 492 | inode->i_mode = mode; | 489 | inode->i_mode = mode; |
| 493 | inode->i_uid = inode->i_gid = 0; | 490 | inode->i_uid = inode->i_gid = 0; |
| 494 | inode->i_blksize = PAGE_CACHE_SIZE; | ||
| 495 | inode->i_blocks = 0; | 491 | inode->i_blocks = 0; |
| 496 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 492 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
| 497 | switch(mode & S_IFMT) { | 493 | switch(mode & S_IFMT) { |
| @@ -516,7 +512,7 @@ rpc_depopulate(struct dentry *parent) | |||
| 516 | struct dentry *dentry, *dvec[10]; | 512 | struct dentry *dentry, *dvec[10]; |
| 517 | int n = 0; | 513 | int n = 0; |
| 518 | 514 | ||
| 519 | mutex_lock(&dir->i_mutex); | 515 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_CHILD); |
| 520 | repeat: | 516 | repeat: |
| 521 | spin_lock(&dcache_lock); | 517 | spin_lock(&dcache_lock); |
| 522 | list_for_each_safe(pos, next, &parent->d_subdirs) { | 518 | list_for_each_safe(pos, next, &parent->d_subdirs) { |
| @@ -540,6 +536,7 @@ repeat: | |||
| 540 | rpc_close_pipes(dentry->d_inode); | 536 | rpc_close_pipes(dentry->d_inode); |
| 541 | simple_unlink(dir, dentry); | 537 | simple_unlink(dir, dentry); |
| 542 | } | 538 | } |
| 539 | inode_dir_notify(dir, DN_DELETE); | ||
| 543 | dput(dentry); | 540 | dput(dentry); |
| 544 | } while (n); | 541 | } while (n); |
| 545 | goto repeat; | 542 | goto repeat; |
| @@ -611,8 +608,8 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 611 | int error; | 608 | int error; |
| 612 | 609 | ||
| 613 | shrink_dcache_parent(dentry); | 610 | shrink_dcache_parent(dentry); |
| 614 | if (dentry->d_inode) | 611 | if (d_unhashed(dentry)) |
| 615 | rpc_close_pipes(dentry->d_inode); | 612 | return 0; |
| 616 | if ((error = simple_rmdir(dir, dentry)) != 0) | 613 | if ((error = simple_rmdir(dir, dentry)) != 0) |
| 617 | return error; | 614 | return error; |
| 618 | if (!error) { | 615 | if (!error) { |
| @@ -623,17 +620,13 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 623 | } | 620 | } |
| 624 | 621 | ||
| 625 | static struct dentry * | 622 | static struct dentry * |
| 626 | rpc_lookup_negative(char *path, struct nameidata *nd) | 623 | rpc_lookup_create(struct dentry *parent, const char *name, int len) |
| 627 | { | 624 | { |
| 625 | struct inode *dir = parent->d_inode; | ||
| 628 | struct dentry *dentry; | 626 | struct dentry *dentry; |
| 629 | struct inode *dir; | ||
| 630 | int error; | ||
| 631 | 627 | ||
| 632 | if ((error = rpc_lookup_parent(path, nd)) != 0) | 628 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
| 633 | return ERR_PTR(error); | 629 | dentry = lookup_one_len(name, parent, len); |
| 634 | dir = nd->dentry->d_inode; | ||
| 635 | mutex_lock(&dir->i_mutex); | ||
| 636 | dentry = lookup_one_len(nd->last.name, nd->dentry, nd->last.len); | ||
| 637 | if (IS_ERR(dentry)) | 630 | if (IS_ERR(dentry)) |
| 638 | goto out_err; | 631 | goto out_err; |
| 639 | if (dentry->d_inode) { | 632 | if (dentry->d_inode) { |
| @@ -644,7 +637,20 @@ rpc_lookup_negative(char *path, struct nameidata *nd) | |||
| 644 | return dentry; | 637 | return dentry; |
| 645 | out_err: | 638 | out_err: |
| 646 | mutex_unlock(&dir->i_mutex); | 639 | mutex_unlock(&dir->i_mutex); |
| 647 | rpc_release_path(nd); | 640 | return dentry; |
| 641 | } | ||
| 642 | |||
| 643 | static struct dentry * | ||
| 644 | rpc_lookup_negative(char *path, struct nameidata *nd) | ||
| 645 | { | ||
| 646 | struct dentry *dentry; | ||
| 647 | int error; | ||
| 648 | |||
| 649 | if ((error = rpc_lookup_parent(path, nd)) != 0) | ||
| 650 | return ERR_PTR(error); | ||
| 651 | dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len); | ||
| 652 | if (IS_ERR(dentry)) | ||
| 653 | rpc_release_path(nd); | ||
| 648 | return dentry; | 654 | return dentry; |
| 649 | } | 655 | } |
| 650 | 656 | ||
| @@ -668,10 +674,11 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client) | |||
| 668 | RPCAUTH_info, RPCAUTH_EOF); | 674 | RPCAUTH_info, RPCAUTH_EOF); |
| 669 | if (error) | 675 | if (error) |
| 670 | goto err_depopulate; | 676 | goto err_depopulate; |
| 677 | dget(dentry); | ||
| 671 | out: | 678 | out: |
| 672 | mutex_unlock(&dir->i_mutex); | 679 | mutex_unlock(&dir->i_mutex); |
| 673 | rpc_release_path(&nd); | 680 | rpc_release_path(&nd); |
| 674 | return dget(dentry); | 681 | return dentry; |
| 675 | err_depopulate: | 682 | err_depopulate: |
| 676 | rpc_depopulate(dentry); | 683 | rpc_depopulate(dentry); |
| 677 | __rpc_rmdir(dir, dentry); | 684 | __rpc_rmdir(dir, dentry); |
| @@ -684,44 +691,35 @@ err_dput: | |||
| 684 | } | 691 | } |
| 685 | 692 | ||
| 686 | int | 693 | int |
| 687 | rpc_rmdir(char *path) | 694 | rpc_rmdir(struct dentry *dentry) |
| 688 | { | 695 | { |
| 689 | struct nameidata nd; | 696 | struct dentry *parent; |
| 690 | struct dentry *dentry; | ||
| 691 | struct inode *dir; | 697 | struct inode *dir; |
| 692 | int error; | 698 | int error; |
| 693 | 699 | ||
| 694 | if ((error = rpc_lookup_parent(path, &nd)) != 0) | 700 | parent = dget_parent(dentry); |
| 695 | return error; | 701 | dir = parent->d_inode; |
| 696 | dir = nd.dentry->d_inode; | 702 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
| 697 | mutex_lock(&dir->i_mutex); | ||
| 698 | dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len); | ||
| 699 | if (IS_ERR(dentry)) { | ||
| 700 | error = PTR_ERR(dentry); | ||
| 701 | goto out_release; | ||
| 702 | } | ||
| 703 | rpc_depopulate(dentry); | 703 | rpc_depopulate(dentry); |
| 704 | error = __rpc_rmdir(dir, dentry); | 704 | error = __rpc_rmdir(dir, dentry); |
| 705 | dput(dentry); | 705 | dput(dentry); |
| 706 | out_release: | ||
| 707 | mutex_unlock(&dir->i_mutex); | 706 | mutex_unlock(&dir->i_mutex); |
| 708 | rpc_release_path(&nd); | 707 | dput(parent); |
| 709 | return error; | 708 | return error; |
| 710 | } | 709 | } |
| 711 | 710 | ||
| 712 | struct dentry * | 711 | struct dentry * |
| 713 | rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags) | 712 | rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pipe_ops *ops, int flags) |
| 714 | { | 713 | { |
| 715 | struct nameidata nd; | ||
| 716 | struct dentry *dentry; | 714 | struct dentry *dentry; |
| 717 | struct inode *dir, *inode; | 715 | struct inode *dir, *inode; |
| 718 | struct rpc_inode *rpci; | 716 | struct rpc_inode *rpci; |
| 719 | 717 | ||
| 720 | dentry = rpc_lookup_negative(path, &nd); | 718 | dentry = rpc_lookup_create(parent, name, strlen(name)); |
| 721 | if (IS_ERR(dentry)) | 719 | if (IS_ERR(dentry)) |
| 722 | return dentry; | 720 | return dentry; |
| 723 | dir = nd.dentry->d_inode; | 721 | dir = parent->d_inode; |
| 724 | inode = rpc_get_inode(dir->i_sb, S_IFSOCK | S_IRUSR | S_IWUSR); | 722 | inode = rpc_get_inode(dir->i_sb, S_IFIFO | S_IRUSR | S_IWUSR); |
| 725 | if (!inode) | 723 | if (!inode) |
| 726 | goto err_dput; | 724 | goto err_dput; |
| 727 | inode->i_ino = iunique(dir->i_sb, 100); | 725 | inode->i_ino = iunique(dir->i_sb, 100); |
| @@ -732,45 +730,40 @@ rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags) | |||
| 732 | rpci->flags = flags; | 730 | rpci->flags = flags; |
| 733 | rpci->ops = ops; | 731 | rpci->ops = ops; |
| 734 | inode_dir_notify(dir, DN_CREATE); | 732 | inode_dir_notify(dir, DN_CREATE); |
| 733 | dget(dentry); | ||
| 735 | out: | 734 | out: |
| 736 | mutex_unlock(&dir->i_mutex); | 735 | mutex_unlock(&dir->i_mutex); |
| 737 | rpc_release_path(&nd); | 736 | return dentry; |
| 738 | return dget(dentry); | ||
| 739 | err_dput: | 737 | err_dput: |
| 740 | dput(dentry); | 738 | dput(dentry); |
| 741 | dentry = ERR_PTR(-ENOMEM); | 739 | dentry = ERR_PTR(-ENOMEM); |
| 742 | printk(KERN_WARNING "%s: %s() failed to create pipe %s (errno = %d)\n", | 740 | printk(KERN_WARNING "%s: %s() failed to create pipe %s/%s (errno = %d)\n", |
| 743 | __FILE__, __FUNCTION__, path, -ENOMEM); | 741 | __FILE__, __FUNCTION__, parent->d_name.name, name, |
| 742 | -ENOMEM); | ||
| 744 | goto out; | 743 | goto out; |
| 745 | } | 744 | } |
| 746 | 745 | ||
| 747 | int | 746 | int |
| 748 | rpc_unlink(char *path) | 747 | rpc_unlink(struct dentry *dentry) |
| 749 | { | 748 | { |
| 750 | struct nameidata nd; | 749 | struct dentry *parent; |
| 751 | struct dentry *dentry; | ||
| 752 | struct inode *dir; | 750 | struct inode *dir; |
| 753 | int error; | 751 | int error = 0; |
| 754 | 752 | ||
| 755 | if ((error = rpc_lookup_parent(path, &nd)) != 0) | 753 | parent = dget_parent(dentry); |
| 756 | return error; | 754 | dir = parent->d_inode; |
| 757 | dir = nd.dentry->d_inode; | 755 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
| 758 | mutex_lock(&dir->i_mutex); | 756 | if (!d_unhashed(dentry)) { |
| 759 | dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len); | 757 | d_drop(dentry); |
| 760 | if (IS_ERR(dentry)) { | 758 | if (dentry->d_inode) { |
| 761 | error = PTR_ERR(dentry); | 759 | rpc_close_pipes(dentry->d_inode); |
| 762 | goto out_release; | 760 | error = simple_unlink(dir, dentry); |
| 763 | } | 761 | } |
| 764 | d_drop(dentry); | 762 | inode_dir_notify(dir, DN_DELETE); |
| 765 | if (dentry->d_inode) { | ||
| 766 | rpc_close_pipes(dentry->d_inode); | ||
| 767 | error = simple_unlink(dir, dentry); | ||
| 768 | } | 763 | } |
| 769 | dput(dentry); | 764 | dput(dentry); |
| 770 | inode_dir_notify(dir, DN_DELETE); | ||
| 771 | out_release: | ||
| 772 | mutex_unlock(&dir->i_mutex); | 765 | mutex_unlock(&dir->i_mutex); |
| 773 | rpc_release_path(&nd); | 766 | dput(parent); |
| 774 | return error; | 767 | return error; |
| 775 | } | 768 | } |
| 776 | 769 | ||
| @@ -864,7 +857,6 @@ int register_rpc_pipefs(void) | |||
| 864 | 857 | ||
| 865 | void unregister_rpc_pipefs(void) | 858 | void unregister_rpc_pipefs(void) |
| 866 | { | 859 | { |
| 867 | if (kmem_cache_destroy(rpc_inode_cachep)) | 860 | kmem_cache_destroy(rpc_inode_cachep); |
| 868 | printk(KERN_WARNING "RPC: unable to free inode cache\n"); | ||
| 869 | unregister_filesystem(&rpc_pipe_fs_type); | 861 | unregister_filesystem(&rpc_pipe_fs_type); |
| 870 | } | 862 | } |
