diff mbox

[04/39] vfs: add path_open()

Message ID 20180529144339.16538-5-mszeredi@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Miklos Szeredi May 29, 2018, 2:43 p.m. UTC
Currently opening an overlay file results in:

 - the real file on the underlying layer being opened
 - f_path being set to the overlay {mount, dentry} pair

This patch adds a new helper that allows the above to be explicitly
performed.  I.e. it's the same as dentry_open(), except the underlying
inode to open is given as a separate argument.

This is in preparation for stacking I/O operations on overlay files.

Later, when implicit opening is removed, dentry_open() can be implemented
by just calling path_open().

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
 fs/open.c          | 31 +++++++++++++++++++++++++++++++
 include/linux/fs.h |  2 ++
 2 files changed, 33 insertions(+)

Comments

Christoph Hellwig June 4, 2018, 8:46 a.m. UTC | #1
> +EXPORT_SYMBOL(path_open);

EXPORT_SYMBOL_GPL, please.
Al Viro June 10, 2018, 4:36 a.m. UTC | #2
On Mon, Jun 04, 2018 at 01:46:09AM -0700, Christoph Hellwig wrote:
> > +EXPORT_SYMBOL(path_open);
> 
> EXPORT_SYMBOL_GPL, please.

	No.

	If interface makes sense, export it.  If it doens't, don't.
Don't mix "it's a shit API, but we need it for some in-kernel module"
with "out-of-tree code should be GPL, especially if it uses this".
For non-trivial work I will, teeth gritting, accept that kind of
stuff.  For anything as trivial as this - fuck, no.

	In this particular case, it *is* a dubious API - AFAICS,
ovl_open_realfile() could just pass vfsmount/dentry from the right
layer to vfs_open().  We might or might not need path_open() for the
duration of the series (I hadn't looked into the PITA it would be
to reorder), but it really looks like it could disappear by the end
of it, along with the temporary export.
diff mbox

Patch

diff --git a/fs/open.c b/fs/open.c
index c5ee7cd60424..d0bf7f061a1a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -906,6 +906,37 @@  int vfs_open(const struct path *path, struct file *file,
 	return do_dentry_open(file, d_backing_inode(dentry), NULL, cred);
 }
 
+/**
+ * path_open() - Open an inode by a particular name.
+ * @path: The name of the file.
+ * @flags: The O_ flags used to open this file.
+ * @inode: The inode to open.
+ * @cred: The task's credentials used when opening this file.
+ *
+ * Context: Process context.
+ * Return: A pointer to a struct file or an IS_ERR pointer.  Cannot return NULL.
+ */
+struct file *path_open(const struct path *path, int flags, struct inode *inode,
+		       const struct cred *cred)
+{
+	struct file *file;
+	int retval;
+
+	file = get_empty_filp();
+	if (IS_ERR(file))
+		return file;
+
+	file->f_flags = flags;
+	file->f_path = *path;
+	retval = do_dentry_open(file, inode, NULL, cred);
+	if (retval) {
+		put_filp(file);
+		return ERR_PTR(retval);
+	}
+	return file;
+}
+EXPORT_SYMBOL(path_open);
+
 struct file *dentry_open(const struct path *path, int flags,
 			 const struct cred *cred)
 {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b0f290944220..9473e68280d0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2401,6 +2401,8 @@  extern struct file *filp_open(const char *, int, umode_t);
 extern struct file *file_open_root(struct dentry *, struct vfsmount *,
 				   const char *, int, umode_t);
 extern struct file * dentry_open(const struct path *, int, const struct cred *);
+extern struct file *path_open(const struct path *, int, struct inode *,
+			      const struct cred *);
 extern int filp_close(struct file *, fl_owner_t id);
 
 extern struct filename *getname_flags(const char __user *, int, int *);