linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: linux-fsdevel@vger.kernel.org
Cc: Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>,
	Amir Goldstein <amir73il@gmail.com>,
	Miklos Szeredi <miklos@szeredi.hu>
Subject: [PATCH 3/3] [experimental] another way to deal with scopes for overlayfs real_fd-under-inode_lock
Date: Fri, 4 Oct 2024 00:48:55 +0100	[thread overview]
Message-ID: <20241003234855.GD147780@ZenIV> (raw)
In-Reply-To: <20241003234534.GM4017910@ZenIV>

[incremental to the previous]

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/overlayfs/file.c | 113 +++++++++++++++++++++-----------------------
 1 file changed, 55 insertions(+), 58 deletions(-)

diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
index a0ab981b13d9..e10a009d32e7 100644
--- a/fs/overlayfs/file.c
+++ b/fs/overlayfs/file.c
@@ -268,6 +268,15 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 				      &ctx);
 }
 
+static ssize_t ovl_write_locked(struct kiocb *iocb, struct iov_iter *iter, int ifl,
+				 struct backing_file_ctx *ctx)
+{
+	CLASS(fd_real, real)(ctx->user_file);
+	if (fd_empty(real))
+		return fd_err(real);
+	return backing_file_write_iter(fd_file(real), iter, iocb, ifl, ctx);
+}
+
 static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct file *file = iocb->ki_filp;
@@ -287,14 +296,6 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
 	/* Update mode */
 	ovl_copyattr(inode);
 
-	{
-
-	CLASS(fd_real, real)(file);
-	if (fd_empty(real)) {
-		ret = fd_err(real);
-		goto out_unlock;
-	}
-
 	if (!ovl_should_sync(OVL_FS(inode->i_sb)))
 		ifl &= ~(IOCB_DSYNC | IOCB_SYNC);
 
@@ -303,11 +304,8 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
 	 * this property in case it is set by the issuer.
 	 */
 	ifl &= ~IOCB_DIO_CALLER_COMP;
-	ret = backing_file_write_iter(fd_file(real), iter, iocb, ifl, &ctx);
-
-	}
+	ret = ovl_write_locked(iocb, iter, ifl, &ctx);
 
-out_unlock:
 	inode_unlock(inode);
 
 	return ret;
@@ -331,6 +329,16 @@ static ssize_t ovl_splice_read(struct file *in, loff_t *ppos,
 					&ctx);
 }
 
+static ssize_t ovl_splice_locked(struct pipe_inode_info *pipe, 
+				 loff_t *ppos, size_t len, unsigned int flags,
+				 struct backing_file_ctx *ctx)
+{
+	CLASS(fd_real, real)(ctx->user_file);
+	if (fd_empty(real))
+		return fd_err(real);
+	return backing_file_splice_write(pipe, fd_file(real), ppos, len, flags, ctx);
+}
+
 /*
  * Calling iter_file_splice_write() directly from overlay's f_op may deadlock
  * due to lock order inversion between pipe->mutex in iter_file_splice_write()
@@ -353,19 +361,7 @@ static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
 	inode_lock(inode);
 	/* Update mode */
 	ovl_copyattr(inode);
-
-	{
-
-	CLASS(fd_real, real)(out);
-	if (fd_empty(real)) {
-		ret = fd_err(real);
-		goto out_unlock;
-	}
-
-	ret = backing_file_splice_write(pipe, fd_file(real), ppos, len, flags, &ctx);
-
-	}
-out_unlock:
+	ret = ovl_splice_locked(pipe, ppos, len, flags, &ctx);
 	inode_unlock(inode);
 
 	return ret;
@@ -409,25 +405,14 @@ static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
 	return backing_file_mmap(realfile, vma, &ctx);
 }
 
-static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
+static long ovl_fallocate_locked(struct file *file, int mode, loff_t offset, loff_t len)
 {
-	struct inode *inode = file_inode(file);
 	const struct cred *old_cred;
 	int ret;
 
-	inode_lock(inode);
-	/* Update mode */
-	ovl_copyattr(inode);
-	ret = file_remove_privs(file);
-	if (ret)
-		goto out_unlock;
-	{
-
 	CLASS(fd_real, real)(file);
-	if (fd_empty(real)) {
-		ret = fd_err(real);
-		goto out_unlock;
-	}
+	if (fd_empty(real))
+		return fd_err(real);
 
 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
 	ret = vfs_fallocate(fd_file(real), mode, offset, len);
@@ -435,9 +420,20 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len
 
 	/* Update size */
 	ovl_file_modified(file);
+	return ret;
+}
 
-	}
-out_unlock:
+static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
+{
+	struct inode *inode = file_inode(file);
+	int ret;
+
+	inode_lock(inode);
+	/* Update mode */
+	ovl_copyattr(inode);
+	ret = file_remove_privs(file);
+	if (!ret)
+		ret = ovl_fallocate_locked(file, mode, offset, len);
 	inode_unlock(inode);
 
 	return ret;
@@ -465,36 +461,28 @@ enum ovl_copyop {
 	OVL_DEDUPE,
 };
 
-static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
+static loff_t ovl_copyfile_locked(struct file *file_in, loff_t pos_in,
 			    struct file *file_out, loff_t pos_out,
 			    loff_t len, unsigned int flags, enum ovl_copyop op)
 {
-	struct inode *inode_out = file_inode(file_out);
 	const struct cred *old_cred;
 	loff_t ret;
 
-	inode_lock(inode_out);
 	if (op != OVL_DEDUPE) {
 		/* Update mode */
-		ovl_copyattr(inode_out);
+		ovl_copyattr(file_inode(file_out));
 		ret = file_remove_privs(file_out);
 		if (ret)
-			goto out_unlock;
+			return ret;
 	}
 
-	{
-
 	CLASS(fd_real, real_out)(file_out);
-	if (fd_empty(real_out)) {
-		ret = fd_err(real_out);
-		goto out_unlock;
-	}
+	if (fd_empty(real_out))
+		return fd_err(real_out);
 
 	CLASS(fd_real, real_in)(file_in);
-	if (fd_empty(real_in)) {
-		ret = fd_err(real_in);
-		goto out_unlock;
-	}
+	if (fd_empty(real_in))
+		return fd_err(real_in);
 
 	old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
 	switch (op) {
@@ -518,10 +506,19 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
 
 	/* Update size */
 	ovl_file_modified(file_out);
+	return ret;
+}
 
-	}
+static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
+			    struct file *file_out, loff_t pos_out,
+			    loff_t len, unsigned int flags, enum ovl_copyop op)
+{
+	struct inode *inode_out = file_inode(file_out);
+	loff_t ret;
 
-out_unlock:
+	inode_lock(inode_out);
+	ret = ovl_copyfile_locked(file_in, pos_in, file_out, pos_out,
+				  len, flags, op);
 	inode_unlock(inode_out);
 
 	return ret;
-- 
2.39.5


  parent reply	other threads:[~2024-10-03 23:48 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-03 23:45 [RFC][PATCHES] struct fderr Al Viro
2024-10-03 23:47 ` Al Viro
2024-10-03 23:47 ` introduce struct fderr, convert overlayfs uses to that Al Viro
2024-10-04  9:43   ` Christian Brauner
2024-10-04 10:47   ` Amir Goldstein
2024-10-17 19:47     ` Al Viro
2024-10-03 23:48 ` [PATCH 2/3] experimental: convert fs/overlayfs/file.c to CLASS(...) Al Viro
2024-10-04  9:40   ` Christian Brauner
2024-10-03 23:48 ` Al Viro [this message]
2024-10-04 10:32 ` [RFC][PATCHES] struct fderr Amir Goldstein

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=20241003234855.GD147780@ZenIV \
    --to=viro@zeniv.linux.org.uk \
    --cc=amir73il@gmail.com \
    --cc=brauner@kernel.org \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).