linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][RESEND] vfs: serialize updates to file->f_sb_err with f_lock
@ 2021-01-04 18:43 Jeff Layton
  2021-01-04 18:57 ` Al Viro
  0 siblings, 1 reply; 3+ messages in thread
From: Jeff Layton @ 2021-01-04 18:43 UTC (permalink / raw)
  To: viro; +Cc: linux-fsdevel, linux-kernel, sargun, amir73il, vgoyal

When I added the ability for syncfs to report writeback errors, I
neglected to adequately protect file->f_sb_err. While changes to
sb->s_wb_err don't require locking, we do need to protect the errseq_t
cursor in file->f_sb_err.

We could have racing updates to that value if two tasks are issuing
syncfs() on the same fd at the same time, possibly causing an error to
be reported twice or not at all.

Fix this by protecting the f_sb_err field with the file->f_lock.

Fixes: 735e4ae5ba28 ("vfs: track per-sb writeback errors and report them to syncfs")
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/sync.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

Al, could you pick up this patch for v5.11 or v5.12? I sent the original
version about a month ago, but it didn't get picked up.

In the original posting I marked this for stable, but I'm not sure it
really qualifies since it's a pretty unlikely race with an oddball
use-case (overlapping syncfs() calls on the same fd).

diff --git a/fs/sync.c b/fs/sync.c
index 1373a610dc78..3be26ff72431 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -162,7 +162,7 @@ SYSCALL_DEFINE1(syncfs, int, fd)
 {
 	struct fd f = fdget(fd);
 	struct super_block *sb;
-	int ret, ret2;
+	int ret, ret2 = 0;
 
 	if (!f.file)
 		return -EBADF;
@@ -172,7 +172,12 @@ SYSCALL_DEFINE1(syncfs, int, fd)
 	ret = sync_filesystem(sb);
 	up_read(&sb->s_umount);
 
-	ret2 = errseq_check_and_advance(&sb->s_wb_err, &f.file->f_sb_err);
+	if (errseq_check(&sb->s_wb_err, f.file->f_sb_err)) {
+		/* Something changed, must use slow path */
+		spin_lock(&f.file->f_lock);
+		ret2 = errseq_check_and_advance(&sb->s_wb_err, &f.file->f_sb_err);
+		spin_unlock(&f.file->f_lock);
+	}
 
 	fdput(f);
 	return ret ? ret : ret2;
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH][RESEND] vfs: serialize updates to file->f_sb_err with f_lock
  2021-01-04 18:43 [PATCH][RESEND] vfs: serialize updates to file->f_sb_err with f_lock Jeff Layton
@ 2021-01-04 18:57 ` Al Viro
  2021-01-04 19:00   ` Jeff Layton
  0 siblings, 1 reply; 3+ messages in thread
From: Al Viro @ 2021-01-04 18:57 UTC (permalink / raw)
  To: Jeff Layton; +Cc: linux-fsdevel, linux-kernel, sargun, amir73il, vgoyal

On Mon, Jan 04, 2021 at 01:43:47PM -0500, Jeff Layton wrote:
> @@ -172,7 +172,12 @@ SYSCALL_DEFINE1(syncfs, int, fd)
>  	ret = sync_filesystem(sb);
>  	up_read(&sb->s_umount);
>  
> -	ret2 = errseq_check_and_advance(&sb->s_wb_err, &f.file->f_sb_err);
> +	if (errseq_check(&sb->s_wb_err, f.file->f_sb_err)) {
> +		/* Something changed, must use slow path */
> +		spin_lock(&f.file->f_lock);
> +		ret2 = errseq_check_and_advance(&sb->s_wb_err, &f.file->f_sb_err);
> +		spin_unlock(&f.file->f_lock);
> +	}

	Is there any point bothering with the fastpath here?
I mean, look at the up_read() immediately prior to that thing...

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][RESEND] vfs: serialize updates to file->f_sb_err with f_lock
  2021-01-04 18:57 ` Al Viro
@ 2021-01-04 19:00   ` Jeff Layton
  0 siblings, 0 replies; 3+ messages in thread
From: Jeff Layton @ 2021-01-04 19:00 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-fsdevel, linux-kernel, sargun, amir73il, vgoyal

On Mon, 2021-01-04 at 18:57 +0000, Al Viro wrote:
> On Mon, Jan 04, 2021 at 01:43:47PM -0500, Jeff Layton wrote:
> > @@ -172,7 +172,12 @@ SYSCALL_DEFINE1(syncfs, int, fd)
> >  	ret = sync_filesystem(sb);
> >  	up_read(&sb->s_umount);
> >  
> > 
> > -	ret2 = errseq_check_and_advance(&sb->s_wb_err, &f.file->f_sb_err);
> > +	if (errseq_check(&sb->s_wb_err, f.file->f_sb_err)) {
> > +		/* Something changed, must use slow path */
> > +		spin_lock(&f.file->f_lock);
> > +		ret2 = errseq_check_and_advance(&sb->s_wb_err, &f.file->f_sb_err);
> > +		spin_unlock(&f.file->f_lock);
> > +	}
> 
> 	Is there any point bothering with the fastpath here?
> I mean, look at the up_read() immediately prior to that thing...

It is a micro-optimization, but the vastly common case is that we will
avoid the spinlock there. That said, I'm fine with dropping the fastpath
if you prefer.

-- 
Jeff Layton <jlayton@kernel.org>


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-01-04 19:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-04 18:43 [PATCH][RESEND] vfs: serialize updates to file->f_sb_err with f_lock Jeff Layton
2021-01-04 18:57 ` Al Viro
2021-01-04 19:00   ` Jeff Layton

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