| From be3f06fb87edc51b3e0635c65e4ef8fdb51187ad Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 22 Oct 2020 14:40:31 +0100 |
| Subject: afs: Fix afs_launder_page to not clear PG_writeback |
| |
| From: David Howells <dhowells@redhat.com> |
| |
| [ Upstream commit d383e346f97d6bb0d654bb3d63c44ab106d92d29 ] |
| |
| Fix afs_launder_page() to not clear PG_writeback on the page it is |
| laundering as the flag isn't set in this case. |
| |
| Fixes: 4343d00872e1 ("afs: Get rid of the afs_writeback record") |
| Signed-off-by: David Howells <dhowells@redhat.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/afs/internal.h | 1 + |
| fs/afs/write.c | 10 ++++++---- |
| 2 files changed, 7 insertions(+), 4 deletions(-) |
| |
| diff --git a/fs/afs/internal.h b/fs/afs/internal.h |
| index 06e617ee4cd1e..c8acb58ac5d8f 100644 |
| --- a/fs/afs/internal.h |
| +++ b/fs/afs/internal.h |
| @@ -811,6 +811,7 @@ struct afs_operation { |
| pgoff_t last; /* last page in mapping to deal with */ |
| unsigned first_offset; /* offset into mapping[first] */ |
| unsigned last_to; /* amount of mapping[last] */ |
| + bool laundering; /* Laundering page, PG_writeback not set */ |
| } store; |
| struct { |
| struct iattr *attr; |
| diff --git a/fs/afs/write.c b/fs/afs/write.c |
| index da12abd6db213..b937ec047ec98 100644 |
| --- a/fs/afs/write.c |
| +++ b/fs/afs/write.c |
| @@ -396,7 +396,8 @@ static void afs_store_data_success(struct afs_operation *op) |
| op->ctime = op->file[0].scb.status.mtime_client; |
| afs_vnode_commit_status(op, &op->file[0]); |
| if (op->error == 0) { |
| - afs_pages_written_back(vnode, op->store.first, op->store.last); |
| + if (!op->store.laundering) |
| + afs_pages_written_back(vnode, op->store.first, op->store.last); |
| afs_stat_v(vnode, n_stores); |
| atomic_long_add((op->store.last * PAGE_SIZE + op->store.last_to) - |
| (op->store.first * PAGE_SIZE + op->store.first_offset), |
| @@ -415,7 +416,7 @@ static const struct afs_operation_ops afs_store_data_operation = { |
| */ |
| static int afs_store_data(struct address_space *mapping, |
| pgoff_t first, pgoff_t last, |
| - unsigned offset, unsigned to) |
| + unsigned offset, unsigned to, bool laundering) |
| { |
| struct afs_vnode *vnode = AFS_FS_I(mapping->host); |
| struct afs_operation *op; |
| @@ -448,6 +449,7 @@ static int afs_store_data(struct address_space *mapping, |
| op->store.last = last; |
| op->store.first_offset = offset; |
| op->store.last_to = to; |
| + op->store.laundering = laundering; |
| op->mtime = vnode->vfs_inode.i_mtime; |
| op->flags |= AFS_OPERATION_UNINTR; |
| op->ops = &afs_store_data_operation; |
| @@ -601,7 +603,7 @@ no_more: |
| if (end > i_size) |
| to = i_size & ~PAGE_MASK; |
| |
| - ret = afs_store_data(mapping, first, last, offset, to); |
| + ret = afs_store_data(mapping, first, last, offset, to, false); |
| switch (ret) { |
| case 0: |
| ret = count; |
| @@ -921,7 +923,7 @@ int afs_launder_page(struct page *page) |
| |
| trace_afs_page_dirty(vnode, tracepoint_string("launder"), |
| page->index, priv); |
| - ret = afs_store_data(mapping, page->index, page->index, t, f); |
| + ret = afs_store_data(mapping, page->index, page->index, t, f, true); |
| } |
| |
| trace_afs_page_dirty(vnode, tracepoint_string("laundered"), |
| -- |
| 2.27.0 |
| |