aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c87
1 files changed, 2 insertions, 85 deletions
diff --git a/fs/open.c b/fs/open.c
index 13bece4f36a4..937f4ec20180 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -771,46 +771,6 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
771} 771}
772 772
773/** 773/**
774 * lookup_instantiate_filp - instantiates the open intent filp
775 * @nd: pointer to nameidata
776 * @dentry: pointer to dentry
777 * @open: open callback
778 *
779 * Helper for filesystems that want to use lookup open intents and pass back
780 * a fully instantiated struct file to the caller.
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()
790 * filesystem callback is substituted.
791 */
792struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
793 int (*open)(struct inode *, struct file *))
794{
795 const struct cred *cred = current_cred();
796
797 if (IS_ERR(nd->intent.open.file))
798 goto out;
799 if (IS_ERR(dentry))
800 goto out_err;
801 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
802 nd->intent.open.file,
803 open, cred);
804out:
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}
811EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
812
813/**
814 * finish_open - finish opening a file 774 * finish_open - finish opening a file
815 * @od: opaque open data 775 * @od: opaque open data
816 * @dentry: pointer to dentry 776 * @dentry: pointer to dentry
@@ -829,9 +789,9 @@ struct file *finish_open(struct opendata *od, struct dentry *dentry,
829 mntget(od->mnt); 789 mntget(od->mnt);
830 dget(dentry); 790 dget(dentry);
831 791
832 res = do_dentry_open(dentry, od->mnt, *od->filp, open, current_cred()); 792 res = do_dentry_open(dentry, od->mnt, od->filp, open, current_cred());
833 if (!IS_ERR(res)) 793 if (!IS_ERR(res))
834 *od->filp = NULL; 794 od->filp = NULL;
835 795
836 return res; 796 return res;
837} 797}
@@ -852,49 +812,6 @@ void finish_no_open(struct opendata *od, struct dentry *dentry)
852} 812}
853EXPORT_SYMBOL(finish_no_open); 813EXPORT_SYMBOL(finish_no_open);
854 814
855/**
856 * nameidata_to_filp - convert a nameidata to an open filp.
857 * @nd: pointer to nameidata
858 * @flags: open flags
859 *
860 * Note that this function destroys the original nameidata
861 */
862struct file *nameidata_to_filp(struct nameidata *nd)
863{
864 const struct cred *cred = current_cred();
865 struct file *filp;
866
867 /* Pick up the filp from the open intent */
868 filp = nd->intent.open.file;
869
870 /* Has the filesystem initialised the file for us? */
871 if (filp->f_path.dentry != NULL) {
872 nd->intent.open.file = NULL;
873 } else {
874 struct file *res;
875
876 path_get(&nd->path);
877 res = do_dentry_open(nd->path.dentry, nd->path.mnt,
878 filp, NULL, cred);
879 if (!IS_ERR(res)) {
880 int error;
881
882 nd->intent.open.file = NULL;
883 BUG_ON(res != filp);
884
885 error = open_check_o_direct(filp);
886 if (error) {
887 fput(filp);
888 filp = ERR_PTR(error);
889 }
890 } else {
891 /* Allow nd->intent.open.file to be recycled */
892 filp = res;
893 }
894 }
895 return filp;
896}
897
898/* 815/*
899 * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an 816 * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an
900 * error. 817 * error.