|
@@ -3324,6 +3324,7 @@ static int extent_write_cache_pages(struct extent_io_tree *tree,
|
|
writepage_t writepage, void *data,
|
|
writepage_t writepage, void *data,
|
|
void (*flush_fn)(void *))
|
|
void (*flush_fn)(void *))
|
|
{
|
|
{
|
|
|
|
+ struct inode *inode = mapping->host;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
int done = 0;
|
|
int done = 0;
|
|
int nr_to_write_done = 0;
|
|
int nr_to_write_done = 0;
|
|
@@ -3334,6 +3335,18 @@ static int extent_write_cache_pages(struct extent_io_tree *tree,
|
|
int scanned = 0;
|
|
int scanned = 0;
|
|
int tag;
|
|
int tag;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * We have to hold onto the inode so that ordered extents can do their
|
|
|
|
+ * work when the IO finishes. The alternative to this is failing to add
|
|
|
|
+ * an ordered extent if the igrab() fails there and that is a huge pain
|
|
|
|
+ * to deal with, so instead just hold onto the inode throughout the
|
|
|
|
+ * writepages operation. If it fails here we are freeing up the inode
|
|
|
|
+ * anyway and we'd rather not waste our time writing out stuff that is
|
|
|
|
+ * going to be truncated anyway.
|
|
|
|
+ */
|
|
|
|
+ if (!igrab(inode))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
pagevec_init(&pvec, 0);
|
|
pagevec_init(&pvec, 0);
|
|
if (wbc->range_cyclic) {
|
|
if (wbc->range_cyclic) {
|
|
index = mapping->writeback_index; /* Start from prev offset */
|
|
index = mapping->writeback_index; /* Start from prev offset */
|
|
@@ -3428,6 +3441,7 @@ retry:
|
|
index = 0;
|
|
index = 0;
|
|
goto retry;
|
|
goto retry;
|
|
}
|
|
}
|
|
|
|
+ btrfs_add_delayed_iput(inode);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|