aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/rpc_pipe.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2005-07-24 18:53:01 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-09-23 12:38:57 -0400
commit278c995c8a153bb2a9bc427e931cfb9c8034c9d7 (patch)
treefe1b62d1686c78659133d751393ab2d5acf38665 /net/sunrpc/rpc_pipe.c
parent470056c288334eb0b37be26c9ff8aee37ed1cc7a (diff)
[PATCH] RPC,NFS: new rpc_pipefs patch
Currently rpc_mkdir/rpc_rmdir and rpc_mkpipe/mk_unlink have an API that's a little unfortunate. They take a path relative to the rpc_pipefs root and thus need to perform a full lookup. If you look at debugfs or usbfs they always store the dentry for directories they created and thus can pass in a dentry + single pathname component pair into their equivalents of the above functions. And in fact rpc_pipefs actually stores a dentry for all but one component so this change not only simplifies the core rpc_pipe code but also the callers. Unfortuntately this code path is only used by the NFS4 idmapper and AUTH_GSSAPI for which I don't have a test enviroment. Could someone give it a spin? It's the last bit needed before we can rework the lookup_hash API Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r--net/sunrpc/rpc_pipe.c268
1 files changed, 94 insertions, 174 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index ded6c63f11ec..b382809726d8 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -414,38 +414,6 @@ rpc_put_mount(void)
414 simple_release_fs(&rpc_mount, &rpc_mount_count); 414 simple_release_fs(&rpc_mount, &rpc_mount_count);
415} 415}
416 416
417static int
418rpc_lookup_parent(char *path, struct nameidata *nd)
419{
420 if (path[0] == '\0')
421 return -ENOENT;
422 if (rpc_get_mount()) {
423 printk(KERN_WARNING "%s: %s failed to mount "
424 "pseudofilesystem \n", __FILE__, __FUNCTION__);
425 return -ENODEV;
426 }
427 nd->mnt = mntget(rpc_mount);
428 nd->dentry = dget(rpc_mount->mnt_root);
429 nd->last_type = LAST_ROOT;
430 nd->flags = LOOKUP_PARENT;
431 nd->depth = 0;
432
433 if (path_walk(path, nd)) {
434 printk(KERN_WARNING "%s: %s failed to find path %s\n",
435 __FILE__, __FUNCTION__, path);
436 rpc_put_mount();
437 return -ENOENT;
438 }
439 return 0;
440}
441
442static void
443rpc_release_path(struct nameidata *nd)
444{
445 path_release(nd);
446 rpc_put_mount();
447}
448
449static struct inode * 417static struct inode *
450rpc_get_inode(struct super_block *sb, int mode) 418rpc_get_inode(struct super_block *sb, int mode)
451{ 419{
@@ -550,197 +518,149 @@ out_bad:
550 return -ENOMEM; 518 return -ENOMEM;
551} 519}
552 520
553static int 521struct dentry *
554__rpc_mkdir(struct inode *dir, struct dentry *dentry) 522rpc_mkdir(struct dentry *parent, char *name, struct rpc_clnt *rpc_client)
555{ 523{
524 struct inode *dir;
525 struct dentry *dentry;
556 struct inode *inode; 526 struct inode *inode;
557
558 inode = rpc_get_inode(dir->i_sb, S_IFDIR | S_IRUSR | S_IXUSR);
559 if (!inode)
560 goto out_err;
561 inode->i_ino = iunique(dir->i_sb, 100);
562 d_instantiate(dentry, inode);
563 dir->i_nlink++;
564 inode_dir_notify(dir, DN_CREATE);
565 rpc_get_mount();
566 return 0;
567out_err:
568 printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n",
569 __FILE__, __FUNCTION__, dentry->d_name.name);
570 return -ENOMEM;
571}
572
573static int
574__rpc_rmdir(struct inode *dir, struct dentry *dentry)
575{
576 int error; 527 int error;
577 528
578 shrink_dcache_parent(dentry); 529 if (!parent)
579 if (dentry->d_inode) { 530 parent = rpc_mount->mnt_root;
580 rpc_close_pipes(dentry->d_inode);
581 rpc_inode_setowner(dentry->d_inode, NULL);
582 }
583 if ((error = simple_rmdir(dir, dentry)) != 0)
584 return error;
585 if (!error) {
586 inode_dir_notify(dir, DN_DELETE);
587 d_drop(dentry);
588 rpc_put_mount();
589 }
590 return 0;
591}
592 531
593static struct dentry * 532 dir = parent->d_inode;
594rpc_lookup_negative(char *path, struct nameidata *nd) 533
595{ 534 error = rpc_get_mount();
596 struct dentry *dentry; 535 if (error)
597 struct inode *dir;
598 int error;
599
600 if ((error = rpc_lookup_parent(path, nd)) != 0)
601 return ERR_PTR(error); 536 return ERR_PTR(error);
602 dir = nd->dentry->d_inode; 537
603 down(&dir->i_sem); 538 down(&dir->i_sem);
604 dentry = lookup_hash(&nd->last, nd->dentry); 539 dentry = lookup_one_len(name, parent, strlen(name));
605 if (IS_ERR(dentry)) 540 if (IS_ERR(dentry))
606 goto out_err; 541 goto out_unlock;
607 if (dentry->d_inode) { 542 if (dentry->d_inode) {
608 dput(dentry);
609 dentry = ERR_PTR(-EEXIST); 543 dentry = ERR_PTR(-EEXIST);
610 goto out_err; 544 goto out_dput;
611 } 545 }
612 return dentry;
613out_err:
614 up(&dir->i_sem);
615 rpc_release_path(nd);
616 return dentry;
617}
618 546
547 inode = rpc_get_inode(dir->i_sb, S_IFDIR | S_IRUSR | S_IXUSR);
548 if (!inode)
549 goto out_dput;
550 inode->i_ino = iunique(dir->i_sb, 100);
551 dir->i_nlink++;
552 RPC_I(dentry->d_inode)->private = rpc_client;
619 553
620struct dentry * 554 d_instantiate(dentry, inode);
621rpc_mkdir(char *path, struct rpc_clnt *rpc_client) 555 dget(dentry);
622{ 556 up(&dir->i_sem);
623 struct nameidata nd; 557
624 struct dentry *dentry; 558 inode_dir_notify(dir, DN_CREATE);
625 struct inode *dir;
626 int error;
627 559
628 dentry = rpc_lookup_negative(path, &nd);
629 if (IS_ERR(dentry))
630 return dentry;
631 dir = nd.dentry->d_inode;
632 if ((error = __rpc_mkdir(dir, dentry)) != 0)
633 goto err_dput;
634 RPC_I(dentry->d_inode)->private = rpc_client;
635 error = rpc_populate(dentry, authfiles, 560 error = rpc_populate(dentry, authfiles,
636 RPCAUTH_info, RPCAUTH_EOF); 561 RPCAUTH_info, RPCAUTH_EOF);
637 if (error) 562 if (error)
638 goto err_depopulate; 563 goto out_depopulate;
639out: 564
640 up(&dir->i_sem);
641 rpc_release_path(&nd);
642 return dentry; 565 return dentry;
643err_depopulate: 566
644 rpc_depopulate(dentry); 567 out_depopulate:
645 __rpc_rmdir(dir, dentry); 568 rpc_rmdir(dentry);
646err_dput: 569 out_dput:
647 dput(dentry); 570 dput(dentry);
648 printk(KERN_WARNING "%s: %s() failed to create directory %s (errno = %d)\n", 571 out_unlock:
649 __FILE__, __FUNCTION__, path, error); 572 up(&dir->i_sem);
650 dentry = ERR_PTR(error); 573 rpc_put_mount();
651 goto out; 574 return dentry;
652} 575}
653 576
654int 577void
655rpc_rmdir(char *path) 578rpc_rmdir(struct dentry *dentry)
656{ 579{
657 struct nameidata nd; 580 struct dentry *parent = dentry->d_parent;
658 struct dentry *dentry;
659 struct inode *dir;
660 int error;
661 581
662 if ((error = rpc_lookup_parent(path, &nd)) != 0)
663 return error;
664 dir = nd.dentry->d_inode;
665 down(&dir->i_sem);
666 dentry = lookup_hash(&nd.last, nd.dentry);
667 if (IS_ERR(dentry)) {
668 error = PTR_ERR(dentry);
669 goto out_release;
670 }
671 rpc_depopulate(dentry); 582 rpc_depopulate(dentry);
672 error = __rpc_rmdir(dir, dentry); 583
673 dput(dentry); 584 down(&parent->d_inode->i_sem);
674out_release: 585 if (dentry->d_inode) {
675 up(&dir->i_sem); 586 rpc_close_pipes(dentry->d_inode);
676 rpc_release_path(&nd); 587 rpc_inode_setowner(dentry->d_inode, NULL);
677 return error; 588 simple_rmdir(parent->d_inode, dentry);
589 }
590 up(&parent->d_inode->i_sem);
591
592 inode_dir_notify(parent->d_inode, DN_DELETE);
593 rpc_put_mount();
678} 594}
679 595
680struct dentry * 596struct dentry *
681rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags) 597rpc_mkpipe(struct dentry *parent, char *name, void *private,
598 struct rpc_pipe_ops *ops, int flags)
682{ 599{
683 struct nameidata nd; 600 struct inode *dir = parent->d_inode;
684 struct dentry *dentry; 601 struct dentry *dentry;
685 struct inode *dir, *inode; 602 struct inode *inode;
686 struct rpc_inode *rpci; 603 struct rpc_inode *rpci;
604 int error;
605
606 error = rpc_get_mount();
607 if (error)
608 return ERR_PTR(error);
687 609
688 dentry = rpc_lookup_negative(path, &nd); 610 down(&parent->d_inode->i_sem);
611 dentry = lookup_one_len(name, parent, strlen(name));
689 if (IS_ERR(dentry)) 612 if (IS_ERR(dentry))
690 return dentry; 613 goto out_unlock;
691 dir = nd.dentry->d_inode; 614 if (dentry->d_inode) {
692 inode = rpc_get_inode(dir->i_sb, S_IFSOCK | S_IRUSR | S_IWUSR); 615 dentry = ERR_PTR(-EEXIST);
693 if (!inode) 616 goto out_dput;
694 goto err_dput; 617 }
618
619 inode = rpc_get_inode(parent->d_inode->i_sb,
620 S_IFSOCK | S_IRUSR | S_IWUSR);
621 if (!inode) {
622 dentry = ERR_PTR(-ENOMEM);
623 goto out_dput;
624 }
625
695 inode->i_ino = iunique(dir->i_sb, 100); 626 inode->i_ino = iunique(dir->i_sb, 100);
696 inode->i_fop = &rpc_pipe_fops; 627 inode->i_fop = &rpc_pipe_fops;
697 d_instantiate(dentry, inode); 628
698 rpci = RPC_I(inode); 629 rpci = RPC_I(inode);
699 rpci->private = private; 630 rpci->private = private;
700 rpci->flags = flags; 631 rpci->flags = flags;
701 rpci->ops = ops; 632 rpci->ops = ops;
633
634 d_instantiate(dentry, inode);
635 dget(dentry);
636 up(&parent->d_inode->i_sem);
637
702 inode_dir_notify(dir, DN_CREATE); 638 inode_dir_notify(dir, DN_CREATE);
703out:
704 up(&dir->i_sem);
705 rpc_release_path(&nd);
706 return dentry; 639 return dentry;
707err_dput: 640
641 out_dput:
708 dput(dentry); 642 dput(dentry);
709 dentry = ERR_PTR(-ENOMEM); 643 out_unlock:
710 printk(KERN_WARNING "%s: %s() failed to create pipe %s (errno = %d)\n", 644 up(&parent->d_inode->i_sem);
711 __FILE__, __FUNCTION__, path, -ENOMEM); 645 rpc_put_mount();
712 goto out; 646 return dentry;
713} 647}
714 648
715int 649void
716rpc_unlink(char *path) 650rpc_unlink(struct dentry *dentry)
717{ 651{
718 struct nameidata nd; 652 struct dentry *parent = dentry->d_parent;
719 struct dentry *dentry;
720 struct inode *dir;
721 int error;
722 653
723 if ((error = rpc_lookup_parent(path, &nd)) != 0) 654 down(&parent->d_inode->i_sem);
724 return error;
725 dir = nd.dentry->d_inode;
726 down(&dir->i_sem);
727 dentry = lookup_hash(&nd.last, nd.dentry);
728 if (IS_ERR(dentry)) {
729 error = PTR_ERR(dentry);
730 goto out_release;
731 }
732 d_drop(dentry);
733 if (dentry->d_inode) { 655 if (dentry->d_inode) {
734 rpc_close_pipes(dentry->d_inode); 656 rpc_close_pipes(dentry->d_inode);
735 rpc_inode_setowner(dentry->d_inode, NULL); 657 rpc_inode_setowner(dentry->d_inode, NULL);
736 error = simple_unlink(dir, dentry); 658 simple_unlink(parent->d_inode, dentry);
737 } 659 }
738 dput(dentry); 660 up(&parent->d_inode->i_sem);
739 inode_dir_notify(dir, DN_DELETE); 661
740out_release: 662 inode_dir_notify(parent->d_inode, DN_DELETE);
741 up(&dir->i_sem); 663 rpc_put_mount();
742 rpc_release_path(&nd);
743 return error;
744} 664}
745 665
746/* 666/*