OSDN Git Service

afs: Fix afs_launder_page to not clear PG_writeback
authorDavid Howells <dhowells@redhat.com>
Thu, 22 Oct 2020 13:40:31 +0000 (14:40 +0100)
committerDavid Howells <dhowells@redhat.com>
Tue, 27 Oct 2020 22:05:56 +0000 (22:05 +0000)
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>
fs/afs/internal.h
fs/afs/write.c

index 81b0485..289f5df 100644 (file)
@@ -812,6 +812,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;
index da12abd..b937ec0 100644 (file)
@@ -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"),