]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Revert "xfs: remove xfs_cancel_ioend"
authorWengang Wang <wen.gang.wang@oracle.com>
Tue, 29 Jan 2019 03:19:09 +0000 (19:19 -0800)
committerBrian Maly <brian.maly@oracle.com>
Wed, 30 Jan 2019 03:58:52 +0000 (22:58 -0500)
This reverts commit c680537035066177fa845053354974f7245c02d8.

These commits are very possibly to cause SIGBUS issue. (We can't verify
that in customer's environment). Revert them.

Orabug: 29279692

Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
Reviewed-by: Shan Hai <shan.hai@oracle.com>
Signed-off-by: Brian Maly <brian.maly@oracle.com>
fs/xfs/xfs_aops.c

index 0a0f5c9294f18eaf2b23e02954a32196faa100b0..75edf5846f32b182dfe8543174b5c8e564df3fc3 100644 (file)
@@ -527,6 +527,38 @@ xfs_submit_ioend(
        } while ((ioend = next) != NULL);
 }
 
+/*
+ * Cancel submission of all buffer_heads so far in this endio.
+ * Toss the endio too.  Only ever called for the initial page
+ * in a writepage request, so only ever one page.
+ */
+STATIC void
+xfs_cancel_ioend(
+       xfs_ioend_t             *ioend)
+{
+       xfs_ioend_t             *next;
+       struct buffer_head      *bh, *next_bh;
+
+       do {
+               next = ioend->io_list;
+               bh = ioend->io_buffer_head;
+               do {
+                       next_bh = bh->b_private;
+                       clear_buffer_async_write(bh);
+                       /*
+                        * The unwritten flag is cleared when added to the
+                        * ioend. We're not submitting for I/O so mark the
+                        * buffer unwritten again for next time around.
+                        */
+                       if (ioend->io_type == XFS_IO_UNWRITTEN)
+                               set_buffer_unwritten(bh);
+                       unlock_buffer(bh);
+               } while ((bh = next_bh) != NULL);
+
+               mempool_free(ioend, xfs_ioend_pool);
+       } while ((ioend = next) != NULL);
+}
+
 /*
  * Test to see if we've been building up a completion structure for
  * earlier buffers -- if so, we try to append to this ioend if we
@@ -899,28 +931,6 @@ out_invalidate:
        return;
 }
 
-static int
-xfs_writepage_submit(
-       struct xfs_ioend        *ioend,
-       struct xfs_ioend        *iohead,
-       struct writeback_control *wbc,
-       int                     status)
-{
-       struct blk_plug         plug;
-
-       /* Reserve log space if we might write beyond the on-disk inode size. */
-       if (!status && ioend && ioend->io_type != XFS_IO_UNWRITTEN &&
-           xfs_ioend_is_append(ioend))
-               status = xfs_setfilesize_trans_alloc(ioend);
-
-       if (iohead) {
-               blk_start_plug(&plug);
-               xfs_submit_ioend(wbc, iohead, status);
-               blk_finish_plug(&plug);
-       }
-       return status;
-}
-
 /*
  * Write out a dirty page.
  *
@@ -1132,7 +1142,6 @@ xfs_vm_writepage(
                return 0;
 
        ASSERT(iohead);
-       ASSERT(err == 0);
 
        /*
         * Any errors from this point onwards need tobe reported through the IO
@@ -1158,33 +1167,25 @@ xfs_vm_writepage(
                                  wbc, end_index);
        }
 
-       return xfs_writepage_submit(ioend, iohead, wbc, 0);
 
-error:
        /*
-        * On error, we have to fail the iohead here because we buffers locked
-        * in the ioend chain. If we don't do this, we'll deadlock invalidating
-        * the page as that tries to lock the buffers on the page. Also, because
-        * we may have set pages under writeback, we have to run IO completion to
-        * mark the error state of the IO appropriately, so we can't cancel the
-        * ioend directly here. That means we have to mark this page as under
-        * writeback if we included any buffers from it in the ioend chain.
+        * Reserve log space if we might write beyond the on-disk inode size.
         */
-       if (count)
-               xfs_start_page_writeback(page, 0, count);
-       xfs_writepage_submit(ioend, iohead, wbc, err);
+       err = 0;
+       if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend))
+               err = xfs_setfilesize_trans_alloc(ioend);
 
-       /*
-        * We can only discard the page we had the IO error on if we haven't
-        * included it in the ioend above. If it has already been errored out,
-        * the it is unlocked and we can't touch it here.
-        */
-       if (!count) {
-               xfs_aops_discard_page(page);
-               ClearPageUptodate(page);
-               unlock_page(page);
-       }
-       mapping_set_error(page->mapping, err);
+       xfs_submit_ioend(wbc, iohead, err);
+
+       return 0;
+
+error:
+       if (iohead)
+               xfs_cancel_ioend(iohead);
+
+       xfs_aops_discard_page(page);
+       ClearPageUptodate(page);
+       unlock_page(page);
        return err;
 
 redirty: