From: Al Viro <viro@zeniv.linux.org.uk>
To: Amir Goldstein <amir73il@gmail.com>
Cc: Miklos Szeredi <miklos@szeredi.hu>,
Christian Brauner <brauner@kernel.org>,
linux-fsdevel@vger.kernel.org, linux-unionfs@vger.kernel.org
Subject: Re: [PATCH 1/4] ovl: do not open non-data lower file for fsync
Date: Sat, 5 Oct 2024 20:49:26 +0100 [thread overview]
Message-ID: <20241005194926.GY4017910@ZenIV> (raw)
In-Reply-To: <CAOQ4uxiqrHeBbF49C0OkoyQm=BqQjvUYEd7k8oinCMwCSOuP3w@mail.gmail.com>
On Sat, Oct 05, 2024 at 08:30:23AM +0200, Amir Goldstein wrote:
> I understand your concern, but honestly, I am not sure that returning
> struct fderr is fundamentally different from checking IS_ERR_OR_NULL.
>
> What I can do is refactor the helpers differently so that ovl_fsync() will
> call ovl_file_upper() to clarify that it may return NULL, just like
ovl_dentry_upper(), you mean?
> ovl_{dentry,inode,path}_upper() and all the other callers will
> call ovl_file_real() which cannot return NULL, because it returns
> either lower or upper file, just like ovl_{inode,path}_real{,data}().
OK... One thing I'm not happy about is the control (and data) flow in there:
stashed_upper:
if (upperfile && file_inode(upperfile) == d_inode(realpath.dentry))
realfile = upperfile;
/*
* If realfile is lower and has been copied up since we'd opened it,
* open the real upper file and stash it in backing_file_private().
*/
if (unlikely(file_inode(realfile) != d_inode(realpath.dentry))) {
struct file *old;
/* Stashed upperfile has a mismatched inode */
if (unlikely(upperfile))
return ERR_PTR(-EIO);
upperfile = ovl_open_realfile(file, &realpath);
if (IS_ERR(upperfile))
return upperfile;
old = cmpxchg_release(backing_file_private_ptr(realfile), NULL,
upperfile);
if (old) {
fput(upperfile);
upperfile = old;
}
goto stashed_upper;
}
Unless I'm misreading that, the value of realfile seen inside the second
if is always the original; reassignment in the first if might as well had
been followed by goto past the second one. What's more, if you win the
race in the second if, you'll have upperfile != NULL and its file_inode()
matching realpath.dentry->d_inode (you'd better, or you have a real problem
in backing_file_open()). So that branch to stashed_upper in case old == NULL
might as well had been "realfile = upperfile;". Correct? In case old != NULL
we go there with upperfile != NULL. If it (i.e. old) has the right file_inode(),
we are done; otherwise it's going to hit ERR_PTR(-EIO) in the second if.
So it seems to be equivalent to this:
if (unlikely(file_inode(realfile) != d_inode(realpath.dentry))) {
/*
* If realfile is lower and has been copied up since we'd
* opened it, we need the real upper file opened. Whoever gets
* there first stashes the result in backing_file_private().
*/
struct file *upperfile = backing_file_private(realfile);
if (unlikely(!upperfile)) {
struct file *old;
upperfile = ovl_open_realfile(file, &realpath);
if (IS_ERR(upperfile))
return upperfile;
old = cmpxchg_release(backing_file_private_ptr(realfile), NULL,
upperfile);
if (old) {
fput(upperfile);
upperfile = old;
}
}
// upperfile reference is owned by realfile at that point
if (unlikely(file_inode(upperfile) != d_inode(realpath.dentry)))
/* Stashed upperfile has a mismatched inode */
return ERR_PTR(-EIO);
realfile = upperfile;
}
Or am I misreading it? Seems to be more straightforward that way...
next prev parent reply other threads:[~2024-10-05 19:49 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-04 10:23 [PATCH 0/4] Stash overlay real upper file in backing_file Amir Goldstein
2024-10-04 10:23 ` [PATCH 1/4] ovl: do not open non-data lower file for fsync Amir Goldstein
2024-10-04 22:16 ` Al Viro
2024-10-04 22:28 ` Al Viro
2024-10-05 1:35 ` Al Viro
2024-10-05 6:30 ` Amir Goldstein
2024-10-05 19:49 ` Al Viro [this message]
2024-10-06 8:03 ` Amir Goldstein
2024-10-04 10:23 ` [PATCH 2/4] ovl: stash upper real file in backing_file struct Amir Goldstein
2024-10-04 10:23 ` [PATCH 3/4] ovl: convert ovl_real_fdget_meta() callers to ovl_real_file_meta() Amir Goldstein
2024-10-04 22:23 ` Al Viro
2024-10-05 12:37 ` Amir Goldstein
2024-10-04 10:23 ` [PATCH 4/4] ovl: convert ovl_real_fdget() callers to ovl_real_file() Amir Goldstein
2024-10-04 22:25 ` Al Viro
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=20241005194926.GY4017910@ZenIV \
--to=viro@zeniv.linux.org.uk \
--cc=amir73il@gmail.com \
--cc=brauner@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-unionfs@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).