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
next prev 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).