aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2015-10-22 15:05:09 -0400
committerDavid Sterba <dsterba@suse.com>2016-01-07 08:26:58 -0500
commitbe7bd730841e69fe8f70120098596f648cd1f3ff (patch)
tree54a0a2b42e3a6ce7dfe097d0240ed27e8d50ce2a
parentb2acdddfad13c38a1e8b927d83c3cf321f63601a (diff)
Btrfs: igrab inode in writepage
We hit this panic on a few of our boxes this week where we have an ordered_extent with an NULL inode. We do an igrab() of the inode in writepages, but weren't doing it in writepage which can be called directly from the VM on dirty pages. If the inode has been unlinked then we could have I_FREEING set which means igrab() would return NULL and we get this panic. Fix this by trying to igrab in btrfs_writepage, and if it returns NULL then just redirty the page and return AOP_WRITEPAGE_ACTIVATE; so the VM knows it wasn't successful. Thanks, Signed-off-by: Josef Bacik <jbacik@fb.com> Reviewed-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/inode.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index a70c5790f8f5..e8d9f9c8d00d 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8534,15 +8534,28 @@ int btrfs_readpage(struct file *file, struct page *page)
8534static int btrfs_writepage(struct page *page, struct writeback_control *wbc) 8534static int btrfs_writepage(struct page *page, struct writeback_control *wbc)
8535{ 8535{
8536 struct extent_io_tree *tree; 8536 struct extent_io_tree *tree;
8537 8537 struct inode *inode = page->mapping->host;
8538 int ret;
8538 8539
8539 if (current->flags & PF_MEMALLOC) { 8540 if (current->flags & PF_MEMALLOC) {
8540 redirty_page_for_writepage(wbc, page); 8541 redirty_page_for_writepage(wbc, page);
8541 unlock_page(page); 8542 unlock_page(page);
8542 return 0; 8543 return 0;
8543 } 8544 }
8545
8546 /*
8547 * If we are under memory pressure we will call this directly from the
8548 * VM, we need to make sure we have the inode referenced for the ordered
8549 * extent. If not just return like we didn't do anything.
8550 */
8551 if (!igrab(inode)) {
8552 redirty_page_for_writepage(wbc, page);
8553 return AOP_WRITEPAGE_ACTIVATE;
8554 }
8544 tree = &BTRFS_I(page->mapping->host)->io_tree; 8555 tree = &BTRFS_I(page->mapping->host)->io_tree;
8545 return extent_write_full_page(tree, page, btrfs_get_extent, wbc); 8556 ret = extent_write_full_page(tree, page, btrfs_get_extent, wbc);
8557 btrfs_add_delayed_iput(inode);
8558 return ret;
8546} 8559}
8547 8560
8548static int btrfs_writepages(struct address_space *mapping, 8561static int btrfs_writepages(struct address_space *mapping,