diff options
author | Matthew Wilcox (Oracle) <willy@infradead.org> | 2024-01-24 17:52:44 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-04-13 12:50:04 +0200 |
commit | 4aa554832b9dc9e66249df75b8f447d87853e12e (patch) | |
tree | 95a5dfe95c8ca6bcaa337f2f8d9373ceb88fb725 /fs/ubifs | |
parent | 9840d1897e28f8733cc1e38f97e044f987dc0a63 (diff) | |
download | linux-stable-4aa554832b9dc9e66249df75b8f447d87853e12e.tar.gz linux-stable-4aa554832b9dc9e66249df75b8f447d87853e12e.tar.bz2 linux-stable-4aa554832b9dc9e66249df75b8f447d87853e12e.zip |
ubifs: Set page uptodate in the correct place
[ Upstream commit 723012cab779eee8228376754e22c6594229bf8f ]
Page cache reads are lockless, so setting the freshly allocated page
uptodate before we've overwritten it with the data it's supposed to have
in it will allow a simultaneous reader to see old data. Move the call
to SetPageUptodate into ubifs_write_end(), which is after we copied the
new data into the page.
Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
Cc: stable@vger.kernel.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/ubifs')
-rw-r--r-- | fs/ubifs/file.c | 13 |
1 files changed, 4 insertions, 9 deletions
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index fca3b7f483c7..e373e5d057fd 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -274,9 +274,6 @@ static int write_begin_slow(struct address_space *mapping, return err; } } - - SetPageUptodate(page); - ClearPageError(page); } if (PagePrivate(page)) @@ -475,9 +472,6 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, return err; } } - - SetPageUptodate(page); - ClearPageError(page); } err = allocate_budget(c, page, ui, appending); @@ -487,10 +481,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, * If we skipped reading the page because we were going to * write all of it, then it is not up to date. */ - if (skipped_read) { + if (skipped_read) ClearPageChecked(page); - ClearPageUptodate(page); - } /* * Budgeting failed which means it would have to force * write-back but didn't, because we set the @fast flag in the @@ -581,6 +573,9 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping, goto out; } + if (len == PAGE_SIZE) + SetPageUptodate(page); + if (!PagePrivate(page)) { SetPagePrivate(page); atomic_long_inc(&c->dirty_pg_cnt); |