aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2016-02-17 19:49:38 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2016-03-30 17:12:22 -0400
commit9a08c352d05305ca7651540c3b107da1e4e1f40b (patch)
treed8b850a2330ab9f98c5a1c00fe54ac741e6e6c82
parentf55532a0c0b8bb6148f4e07853b876ef73bc69ca (diff)
fs: add filp_clone_open API
I need an API that allows me to obtain a clone of the current file pointer to pass in to an exec handler. I've labelled this as an internal API because I can't see how it would be useful outside of the fs subsystem. The use case will be a persistent binfmt_misc handler. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Acked-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/internal.h1
-rw-r--r--fs/open.c20
2 files changed, 21 insertions, 0 deletions
diff --git a/fs/internal.h b/fs/internal.h
index b71deeecea17..c8ca0c957743 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -108,6 +108,7 @@ extern long do_handle_open(int mountdirfd,
108 struct file_handle __user *ufh, int open_flag); 108 struct file_handle __user *ufh, int open_flag);
109extern int open_check_o_direct(struct file *f); 109extern int open_check_o_direct(struct file *f);
110extern int vfs_open(const struct path *, struct file *, const struct cred *); 110extern int vfs_open(const struct path *, struct file *, const struct cred *);
111extern struct file *filp_clone_open(struct file *);
111 112
112/* 113/*
113 * inode.c 114 * inode.c
diff --git a/fs/open.c b/fs/open.c
index 17cb6b1dab75..bfe6f2b8345f 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1002,6 +1002,26 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
1002} 1002}
1003EXPORT_SYMBOL(file_open_root); 1003EXPORT_SYMBOL(file_open_root);
1004 1004
1005struct file *filp_clone_open(struct file *oldfile)
1006{
1007 struct file *file;
1008 int retval;
1009
1010 file = get_empty_filp();
1011 if (IS_ERR(file))
1012 return file;
1013
1014 file->f_flags = oldfile->f_flags;
1015 retval = vfs_open(&oldfile->f_path, file, oldfile->f_cred);
1016 if (retval) {
1017 put_filp(file);
1018 return ERR_PTR(retval);
1019 }
1020
1021 return file;
1022}
1023EXPORT_SYMBOL(filp_clone_open);
1024
1005long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) 1025long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
1006{ 1026{
1007 struct open_flags op; 1027 struct open_flags op;