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 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.