xfs: do not discard page cache data on EAGAIN
authorChristoph Hellwig <[email protected]>
Tue, 24 Aug 2010 01:47:51 +0000 (11:47 +1000)
committerDave Chinner <[email protected]>
Tue, 24 Aug 2010 01:47:51 +0000 (11:47 +1000)
If xfs_map_blocks returns EAGAIN because of lock contention we must redirty the
page and not disard the pagecache content and return an error from writepage.
We used to do this correctly, but the logic got lost during the recent
reshuffle of the writepage code.

Signed-off-by: Christoph Hellwig <[email protected]>
Reported-by: Mike Gao <[email protected]>
Tested-by: Mike Gao <[email protected]>
Reviewed-by: Dave Chinner <[email protected]>
Signed-off-by: Dave Chinner <[email protected]>
fs/xfs/linux-2.6/xfs_aops.c

index 528be1ba1402f31238429931ac64e3822041d4f2..b552f816de15942095f82ad0302b8656f7db09ae 100644 (file)
@@ -1068,7 +1068,7 @@ xfs_vm_writepage(
         * by themselves.
         */
        if ((current->flags & (PF_MEMALLOC|PF_KSWAPD)) == PF_MEMALLOC)
-               goto out_fail;
+               goto redirty;
 
        /*
         * We need a transaction if there are delalloc or unwritten buffers
@@ -1080,7 +1080,7 @@ xfs_vm_writepage(
         */
        xfs_count_page_state(page, &delalloc, &unwritten);
        if ((current->flags & PF_FSTRANS) && (delalloc || unwritten))
-               goto out_fail;
+               goto redirty;
 
        /* Is this page beyond the end of the file? */
        offset = i_size_read(inode);
@@ -1245,12 +1245,15 @@ error:
        if (iohead)
                xfs_cancel_ioend(iohead);
 
+       if (err == -EAGAIN)
+               goto redirty;
+
        xfs_aops_discard_page(page);
        ClearPageUptodate(page);
        unlock_page(page);
        return err;
 
-out_fail:
+redirty:
        redirty_page_for_writepage(wbc, page);
        unlock_page(page);
        return 0;