All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miklos Szeredi <mszeredi@redhat.com>
To: linux-fsdevel@vger.kernel.org
Cc: Al Viro <viro@ZenIV.linux.org.uk>,
	Amir Goldstein <amir73il@gmail.com>,
	David Howells <dhowells@redhat.com>,
	Yu-li Lin <yulilin@google.com>,
	Chirantan Ekbote <chirantan@chromium.org>
Subject: [PATCH v2 6/8] vfs: move open right after ->tmpfile()
Date: Mon, 19 Sep 2022 16:10:29 +0200	[thread overview]
Message-ID: <20220919141031.1834447-7-mszeredi@redhat.com> (raw)
In-Reply-To: <20220919141031.1834447-1-mszeredi@redhat.com>

Create a helper finish_open_simple() that opens the file with the original
dentry.  Handle the error case here as well to simplify callers.

Call this helper right after ->tmpfile() is called.

Next patch will change the tmpfile API and move this call into tmpfile
instances.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
 fs/namei.c         | 65 ++++++++++++++++++++--------------------------
 include/linux/fs.h |  9 +++++++
 2 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 652d09ae66fb..eb1e1956450f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3583,11 +3583,12 @@ static int do_open(struct nameidata *nd,
  * On non-idmapped mounts or if permission checking is to be performed on the
  * raw inode simply passs init_user_ns.
  */
-static struct dentry *vfs_tmpfile(struct user_namespace *mnt_userns,
-			   struct dentry *dentry, umode_t mode, int open_flag)
+static int vfs_tmpfile(struct user_namespace *mnt_userns,
+		       const struct path *parentpath,
+		       struct file *file, umode_t mode)
 {
-	struct dentry *child = NULL;
-	struct inode *dir = dentry->d_inode;
+	struct dentry *child;
+	struct inode *dir = d_inode(parentpath->dentry);
 	struct inode *inode;
 	int error;
 
@@ -3599,28 +3600,34 @@ static struct dentry *vfs_tmpfile(struct user_namespace *mnt_userns,
 	if (!dir->i_op->tmpfile)
 		goto out_err;
 	error = -ENOMEM;
-	child = d_alloc(dentry, &slash_name);
+	child = d_alloc(parentpath->dentry, &slash_name);
 	if (unlikely(!child))
 		goto out_err;
+	file->f_path.mnt = parentpath->mnt;
+	file->f_path.dentry = child;
 	mode = vfs_prepare_mode(mnt_userns, dir, mode, mode, mode);
 	error = dir->i_op->tmpfile(mnt_userns, dir, child, mode);
+	error = finish_open_simple(file, error);
+	dput(child);
+	if (error)
+		goto out_err;
+	error = may_open(mnt_userns, &file->f_path, 0, file->f_flags);
 	if (error)
 		goto out_err;
 	error = -ENOENT;
 	inode = child->d_inode;
 	if (unlikely(!inode))
 		goto out_err;
-	if (!(open_flag & O_EXCL)) {
+	if (!(file->f_flags & O_EXCL)) {
 		spin_lock(&inode->i_lock);
 		inode->i_state |= I_LINKABLE;
 		spin_unlock(&inode->i_lock);
 	}
 	ima_post_create_tmpfile(mnt_userns, inode);
-	return child;
+	return 0;
 
 out_err:
-	dput(child);
-	return ERR_PTR(error);
+	return error;
 }
 
 /**
@@ -3641,25 +3648,15 @@ struct file *tmpfile_open(struct user_namespace *mnt_userns,
 {
 	struct file *file;
 	int error;
-	struct path path = { .mnt = parentpath->mnt };
-
-	path.dentry = vfs_tmpfile(mnt_userns, parentpath->dentry, mode, open_flag);
-	if (IS_ERR(path.dentry))
-		return ERR_CAST(path.dentry);
-
-	error = may_open(mnt_userns, &path, 0, open_flag);
-	file = ERR_PTR(error);
-	if (error)
-		goto out_dput;
-
-	/*
-	 * This relies on the "noaccount" property of fake open, otherwise
-	 * equivalent to dentry_open().
-	 */
-	file = open_with_fake_path(&path, open_flag, d_inode(path.dentry), cred);
-out_dput:
-	dput(path.dentry);
 
+	file = alloc_empty_file_noaccount(open_flag, cred);
+	if (!IS_ERR(file)) {
+		error = vfs_tmpfile(mnt_userns, parentpath, file, mode);
+		if (error) {
+			fput(file);
+			file = ERR_PTR(error);
+		}
+	}
 	return file;
 }
 EXPORT_SYMBOL(tmpfile_open);
@@ -3669,26 +3666,20 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags,
 		struct file *file)
 {
 	struct user_namespace *mnt_userns;
-	struct dentry *child;
 	struct path path;
 	int error = path_lookupat(nd, flags | LOOKUP_DIRECTORY, &path);
+
 	if (unlikely(error))
 		return error;
 	error = mnt_want_write(path.mnt);
 	if (unlikely(error))
 		goto out;
 	mnt_userns = mnt_user_ns(path.mnt);
-	child = vfs_tmpfile(mnt_userns, path.dentry, op->mode, op->open_flag);
-	error = PTR_ERR(child);
-	if (IS_ERR(child))
+	error = vfs_tmpfile(mnt_userns, &path, file, op->mode);
+	if (error)
 		goto out2;
-	dput(path.dentry);
-	path.dentry = child;
-	audit_inode(nd->name, child, 0);
+	audit_inode(nd->name, file->f_path.dentry, 0);
 	/* Don't check for other permissions, the inode was just created */
-	error = may_open(mnt_userns, &path, 0, op->open_flag);
-	if (!error)
-		error = vfs_open(&path, file);
 out2:
 	mnt_drop_write(path.mnt);
 out:
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a445da4842e0..f0d17eefb966 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2780,6 +2780,15 @@ extern int finish_open(struct file *file, struct dentry *dentry,
 			int (*open)(struct inode *, struct file *));
 extern int finish_no_open(struct file *file, struct dentry *dentry);
 
+/* Helper for the simple case when original dentry is used */
+static inline int finish_open_simple(struct file *file, int error)
+{
+	if (error)
+		return error;
+
+	return finish_open(file, file->f_path.dentry, NULL);
+}
+
 /* fs/dcache.c */
 extern void __init vfs_caches_init_early(void);
 extern void __init vfs_caches_init(void);
-- 
2.37.3


  parent reply	other threads:[~2022-09-19 14:10 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-19 14:10 [PATCH v2 0/8] fuse tmpfile Miklos Szeredi
2022-09-19 14:10 ` [PATCH v2 1/8] cachefiles: tmpfile error handling cleanup Miklos Szeredi
2022-09-19 14:10 ` [PATCH v2 2/8] vfs: add tmpfile_open() helper Miklos Szeredi
2022-09-19 14:10 ` [PATCH v2 3/8] cachefiles: use " Miklos Szeredi
2022-09-19 14:10 ` [PATCH v2 4/8] ovl: " Miklos Szeredi
2022-09-20  1:33   ` Al Viro
2022-09-20  8:02     ` Miklos Szeredi
2022-09-19 14:10 ` [PATCH v2 5/8] vfs: make vfs_tmpfile() static Miklos Szeredi
2022-09-19 14:10 ` Miklos Szeredi [this message]
2022-09-20  1:40   ` [PATCH v2 6/8] vfs: move open right after ->tmpfile() Al Viro
2022-09-20  8:08     ` Miklos Szeredi
2022-09-19 14:10 ` [PATCH v2 7/8] vfs: open inside ->tmpfile() Miklos Szeredi
2022-09-20  1:50   ` Al Viro
2022-09-20  8:44     ` Miklos Szeredi
2022-09-19 14:10 ` [PATCH v2 8/8] fuse: implement ->tmpfile() Miklos Szeredi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220919141031.1834447-7-mszeredi@redhat.com \
    --to=mszeredi@redhat.com \
    --cc=amir73il@gmail.com \
    --cc=chirantan@chromium.org \
    --cc=dhowells@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=viro@ZenIV.linux.org.uk \
    --cc=yulilin@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.