aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c211
1 files changed, 65 insertions, 146 deletions
diff --git a/fs/open.c b/fs/open.c
index 1540632d8387..1e914b397e12 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -537,25 +537,6 @@ static int chown_common(struct path *path, uid_t user, gid_t group)
537 return error; 537 return error;
538} 538}
539 539
540SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
541{
542 struct path path;
543 int error;
544
545 error = user_path(filename, &path);
546 if (error)
547 goto out;
548 error = mnt_want_write(path.mnt);
549 if (error)
550 goto out_release;
551 error = chown_common(&path, user, group);
552 mnt_drop_write(path.mnt);
553out_release:
554 path_put(&path);
555out:
556 return error;
557}
558
559SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, 540SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
560 gid_t, group, int, flag) 541 gid_t, group, int, flag)
561{ 542{
@@ -583,23 +564,15 @@ out:
583 return error; 564 return error;
584} 565}
585 566
586SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group) 567SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
587{ 568{
588 struct path path; 569 return sys_fchownat(AT_FDCWD, filename, user, group, 0);
589 int error; 570}
590 571
591 error = user_lpath(filename, &path); 572SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
592 if (error) 573{
593 goto out; 574 return sys_fchownat(AT_FDCWD, filename, user, group,
594 error = mnt_want_write(path.mnt); 575 AT_SYMLINK_NOFOLLOW);
595 if (error)
596 goto out_release;
597 error = chown_common(&path, user, group);
598 mnt_drop_write(path.mnt);
599out_release:
600 path_put(&path);
601out:
602 return error;
603} 576}
604 577
605SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) 578SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
@@ -667,10 +640,9 @@ int open_check_o_direct(struct file *f)
667 return 0; 640 return 0;
668} 641}
669 642
670static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt, 643static int do_dentry_open(struct file *f,
671 struct file *f, 644 int (*open)(struct inode *, struct file *),
672 int (*open)(struct inode *, struct file *), 645 const struct cred *cred)
673 const struct cred *cred)
674{ 646{
675 static const struct file_operations empty_fops = {}; 647 static const struct file_operations empty_fops = {};
676 struct inode *inode; 648 struct inode *inode;
@@ -682,9 +654,9 @@ static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt,
682 if (unlikely(f->f_flags & O_PATH)) 654 if (unlikely(f->f_flags & O_PATH))
683 f->f_mode = FMODE_PATH; 655 f->f_mode = FMODE_PATH;
684 656
685 inode = dentry->d_inode; 657 inode = f->f_path.dentry->d_inode;
686 if (f->f_mode & FMODE_WRITE) { 658 if (f->f_mode & FMODE_WRITE) {
687 error = __get_file_write_access(inode, mnt); 659 error = __get_file_write_access(inode, f->f_path.mnt);
688 if (error) 660 if (error)
689 goto cleanup_file; 661 goto cleanup_file;
690 if (!special_file(inode->i_mode)) 662 if (!special_file(inode->i_mode))
@@ -692,14 +664,12 @@ static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt,
692 } 664 }
693 665
694 f->f_mapping = inode->i_mapping; 666 f->f_mapping = inode->i_mapping;
695 f->f_path.dentry = dentry;
696 f->f_path.mnt = mnt;
697 f->f_pos = 0; 667 f->f_pos = 0;
698 file_sb_list_add(f, inode->i_sb); 668 file_sb_list_add(f, inode->i_sb);
699 669
700 if (unlikely(f->f_mode & FMODE_PATH)) { 670 if (unlikely(f->f_mode & FMODE_PATH)) {
701 f->f_op = &empty_fops; 671 f->f_op = &empty_fops;
702 return f; 672 return 0;
703 } 673 }
704 674
705 f->f_op = fops_get(inode->i_fop); 675 f->f_op = fops_get(inode->i_fop);
@@ -726,10 +696,11 @@ static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt,
726 696
727 file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); 697 file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
728 698
729 return f; 699 return 0;
730 700
731cleanup_all: 701cleanup_all:
732 fops_put(f->f_op); 702 fops_put(f->f_op);
703 file_sb_list_del(f);
733 if (f->f_mode & FMODE_WRITE) { 704 if (f->f_mode & FMODE_WRITE) {
734 put_write_access(inode); 705 put_write_access(inode);
735 if (!special_file(inode->i_mode)) { 706 if (!special_file(inode->i_mode)) {
@@ -740,124 +711,62 @@ cleanup_all:
740 * here, so just reset the state. 711 * here, so just reset the state.
741 */ 712 */
742 file_reset_write(f); 713 file_reset_write(f);
743 mnt_drop_write(mnt); 714 mnt_drop_write(f->f_path.mnt);
744 } 715 }
745 } 716 }
746 file_sb_list_del(f);
747 f->f_path.dentry = NULL;
748 f->f_path.mnt = NULL;
749cleanup_file: 717cleanup_file:
750 dput(dentry); 718 path_put(&f->f_path);
751 mntput(mnt); 719 f->f_path.mnt = NULL;
752 return ERR_PTR(error); 720 f->f_path.dentry = NULL;
753} 721 return error;
754
755static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
756 struct file *f,
757 int (*open)(struct inode *, struct file *),
758 const struct cred *cred)
759{
760 struct file *res = do_dentry_open(dentry, mnt, f, open, cred);
761 if (!IS_ERR(res)) {
762 int error = open_check_o_direct(f);
763 if (error) {
764 fput(res);
765 res = ERR_PTR(error);
766 }
767 } else {
768 put_filp(f);
769 }
770 return res;
771} 722}
772 723
773/** 724/**
774 * lookup_instantiate_filp - instantiates the open intent filp 725 * finish_open - finish opening a file
775 * @nd: pointer to nameidata 726 * @od: opaque open data
776 * @dentry: pointer to dentry 727 * @dentry: pointer to dentry
777 * @open: open callback 728 * @open: open callback
778 * 729 *
779 * Helper for filesystems that want to use lookup open intents and pass back 730 * This can be used to finish opening a file passed to i_op->atomic_open().
780 * a fully instantiated struct file to the caller. 731 *
781 * This function is meant to be called from within a filesystem's
782 * lookup method.
783 * Beware of calling it for non-regular files! Those ->open methods might block
784 * (e.g. in fifo_open), leaving you with parent locked (and in case of fifo,
785 * leading to a deadlock, as nobody can open that fifo anymore, because
786 * another process to open fifo will block on locked parent when doing lookup).
787 * Note that in case of error, nd->intent.open.file is destroyed, but the
788 * path information remains valid.
789 * If the open callback is set to NULL, then the standard f_op->open() 732 * If the open callback is set to NULL, then the standard f_op->open()
790 * filesystem callback is substituted. 733 * filesystem callback is substituted.
791 */ 734 */
792struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, 735int finish_open(struct file *file, struct dentry *dentry,
793 int (*open)(struct inode *, struct file *)) 736 int (*open)(struct inode *, struct file *),
737 int *opened)
794{ 738{
795 const struct cred *cred = current_cred(); 739 int error;
740 BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
796 741
797 if (IS_ERR(nd->intent.open.file)) 742 mntget(file->f_path.mnt);
798 goto out; 743 file->f_path.dentry = dget(dentry);
799 if (IS_ERR(dentry)) 744
800 goto out_err; 745 error = do_dentry_open(file, open, current_cred());
801 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), 746 if (!error)
802 nd->intent.open.file, 747 *opened |= FILE_OPENED;
803 open, cred); 748
804out: 749 return error;
805 return nd->intent.open.file;
806out_err:
807 release_open_intent(nd);
808 nd->intent.open.file = ERR_CAST(dentry);
809 goto out;
810} 750}
811EXPORT_SYMBOL_GPL(lookup_instantiate_filp); 751EXPORT_SYMBOL(finish_open);
812 752
813/** 753/**
814 * nameidata_to_filp - convert a nameidata to an open filp. 754 * finish_no_open - finish ->atomic_open() without opening the file
815 * @nd: pointer to nameidata 755 *
816 * @flags: open flags 756 * @od: opaque open data
757 * @dentry: dentry or NULL (as returned from ->lookup())
817 * 758 *
818 * Note that this function destroys the original nameidata 759 * This can be used to set the result of a successful lookup in ->atomic_open().
760 * The filesystem's atomic_open() method shall return NULL after calling this.
819 */ 761 */
820struct file *nameidata_to_filp(struct nameidata *nd) 762int finish_no_open(struct file *file, struct dentry *dentry)
821{ 763{
822 const struct cred *cred = current_cred(); 764 file->f_path.dentry = dentry;
823 struct file *filp; 765 return 1;
824
825 /* Pick up the filp from the open intent */
826 filp = nd->intent.open.file;
827
828 /* Has the filesystem initialised the file for us? */
829 if (filp->f_path.dentry != NULL) {
830 nd->intent.open.file = NULL;
831 } else {
832 struct file *res;
833
834 path_get(&nd->path);
835 res = do_dentry_open(nd->path.dentry, nd->path.mnt,
836 filp, NULL, cred);
837 if (!IS_ERR(res)) {
838 int error;
839
840 nd->intent.open.file = NULL;
841 BUG_ON(res != filp);
842
843 error = open_check_o_direct(filp);
844 if (error) {
845 fput(filp);
846 filp = ERR_PTR(error);
847 }
848 } else {
849 /* Allow nd->intent.open.file to be recycled */
850 filp = res;
851 }
852 }
853 return filp;
854} 766}
767EXPORT_SYMBOL(finish_no_open);
855 768
856/* 769struct file *dentry_open(const struct path *path, int flags,
857 * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an
858 * error.
859 */
860struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
861 const struct cred *cred) 770 const struct cred *cred)
862{ 771{
863 int error; 772 int error;
@@ -866,18 +775,28 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
866 validate_creds(cred); 775 validate_creds(cred);
867 776
868 /* We must always pass in a valid mount pointer. */ 777 /* We must always pass in a valid mount pointer. */
869 BUG_ON(!mnt); 778 BUG_ON(!path->mnt);
870 779
871 error = -ENFILE; 780 error = -ENFILE;
872 f = get_empty_filp(); 781 f = get_empty_filp();
873 if (f == NULL) { 782 if (f == NULL)
874 dput(dentry);
875 mntput(mnt);
876 return ERR_PTR(error); 783 return ERR_PTR(error);
877 }
878 784
879 f->f_flags = flags; 785 f->f_flags = flags;
880 return __dentry_open(dentry, mnt, f, NULL, cred); 786 f->f_path = *path;
787 path_get(&f->f_path);
788 error = do_dentry_open(f, NULL, cred);
789 if (!error) {
790 error = open_check_o_direct(f);
791 if (error) {
792 fput(f);
793 f = ERR_PTR(error);
794 }
795 } else {
796 put_filp(f);
797 f = ERR_PTR(error);
798 }
799 return f;
881} 800}
882EXPORT_SYMBOL(dentry_open); 801EXPORT_SYMBOL(dentry_open);
883 802