summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2016-02-18 01:49:38 +0100
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2016-03-30 23:12:22 +0200
commit9a08c352d05305ca7651540c3b107da1e4e1f40b (patch)
treed8b850a2330ab9f98c5a1c00fe54ac741e6e6c82
parentLinux 4.6-rc1 (diff)
downloadlinux-9a08c352d05305ca7651540c3b107da1e4e1f40b.tar.xz
linux-9a08c352d05305ca7651540c3b107da1e4e1f40b.zip
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,
struct file_handle __user *ufh, int open_flag);
extern int open_check_o_direct(struct file *f);
extern int vfs_open(const struct path *, struct file *, const struct cred *);
+extern struct file *filp_clone_open(struct file *);
/*
* 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,
}
EXPORT_SYMBOL(file_open_root);
+struct file *filp_clone_open(struct file *oldfile)
+{
+ struct file *file;
+ int retval;
+
+ file = get_empty_filp();
+ if (IS_ERR(file))
+ return file;
+
+ file->f_flags = oldfile->f_flags;
+ retval = vfs_open(&oldfile->f_path, file, oldfile->f_cred);
+ if (retval) {
+ put_filp(file);
+ return ERR_PTR(retval);
+ }
+
+ return file;
+}
+EXPORT_SYMBOL(filp_clone_open);
+
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
struct open_flags op;