|
@@ -2043,11 +2043,12 @@ static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh)
|
|
return !buffer_mapped(bh) || buffer_delay(bh);
|
|
return !buffer_mapped(bh) || buffer_delay(bh);
|
|
}
|
|
}
|
|
|
|
|
|
-/* FIXME!! only support data=writeback mode */
|
|
|
|
/*
|
|
/*
|
|
* get called vi ext4_da_writepages after taking page lock
|
|
* get called vi ext4_da_writepages after taking page lock
|
|
* We may end up doing block allocation here in case
|
|
* We may end up doing block allocation here in case
|
|
* mpage_da_map_blocks failed to allocate blocks.
|
|
* mpage_da_map_blocks failed to allocate blocks.
|
|
|
|
+ *
|
|
|
|
+ * We also get called via journal_submit_inode_data_buffers
|
|
*/
|
|
*/
|
|
static int ext4_da_writepage(struct page *page,
|
|
static int ext4_da_writepage(struct page *page,
|
|
struct writeback_control *wbc)
|
|
struct writeback_control *wbc)
|
|
@@ -2066,6 +2067,7 @@ static int ext4_da_writepage(struct page *page,
|
|
* ext4_da_writepages() but directly (shrink_page_list).
|
|
* ext4_da_writepages() but directly (shrink_page_list).
|
|
* We cannot easily start a transaction here so we just skip
|
|
* We cannot easily start a transaction here so we just skip
|
|
* writing the page in case we would have to do so.
|
|
* writing the page in case we would have to do so.
|
|
|
|
+ * We reach here also via journal_submit_inode_data_buffers
|
|
*/
|
|
*/
|
|
size = i_size_read(inode);
|
|
size = i_size_read(inode);
|
|
|
|
|
|
@@ -2081,8 +2083,11 @@ static int ext4_da_writepage(struct page *page,
|
|
* We can't do block allocation under
|
|
* We can't do block allocation under
|
|
* page lock without a handle . So redirty
|
|
* page lock without a handle . So redirty
|
|
* the page and return
|
|
* the page and return
|
|
|
|
+ * We may reach here when we do a journal commit
|
|
|
|
+ * via journal_submit_inode_data_buffers.
|
|
|
|
+ * If we don't have mapping block we just ignore
|
|
|
|
+ * them
|
|
*/
|
|
*/
|
|
- BUG_ON(wbc->sync_mode != WB_SYNC_NONE);
|
|
|
|
redirty_page_for_writepage(wbc, page);
|
|
redirty_page_for_writepage(wbc, page);
|
|
unlock_page(page);
|
|
unlock_page(page);
|
|
return 0;
|
|
return 0;
|
|
@@ -2097,7 +2102,6 @@ static int ext4_da_writepage(struct page *page,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* For now just follow the DIO way to estimate the max credits
|
|
* For now just follow the DIO way to estimate the max credits
|
|
* needed to write out EXT4_MAX_WRITEBACK_PAGES.
|
|
* needed to write out EXT4_MAX_WRITEBACK_PAGES.
|
|
@@ -2130,7 +2134,7 @@ static int ext4_da_writepages(struct address_space *mapping,
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
/*
|
|
/*
|
|
- * Estimate the worse case needed credits to write out
|
|
|
|
|
|
+ * Estimate the worse case needed credits to write out
|
|
* EXT4_MAX_BUF_BLOCKS pages
|
|
* EXT4_MAX_BUF_BLOCKS pages
|
|
*/
|
|
*/
|
|
needed_blocks = EXT4_MAX_WRITEBACK_CREDITS;
|
|
needed_blocks = EXT4_MAX_WRITEBACK_CREDITS;
|
|
@@ -2152,6 +2156,19 @@ static int ext4_da_writepages(struct address_space *mapping,
|
|
ret = PTR_ERR(handle);
|
|
ret = PTR_ERR(handle);
|
|
goto out_writepages;
|
|
goto out_writepages;
|
|
}
|
|
}
|
|
|
|
+ if (ext4_should_order_data(inode)) {
|
|
|
|
+ /*
|
|
|
|
+ * With ordered mode we need to add
|
|
|
|
+ * the inode to the journal handle
|
|
|
|
+ * when we do block allocation.
|
|
|
|
+ */
|
|
|
|
+ ret = ext4_jbd2_file_inode(handle, inode);
|
|
|
|
+ if (ret) {
|
|
|
|
+ ext4_journal_stop(handle);
|
|
|
|
+ goto out_writepages;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
/*
|
|
/*
|
|
* set the max dirty pages could be write at a time
|
|
* set the max dirty pages could be write at a time
|
|
* to fit into the reserved transaction credits
|
|
* to fit into the reserved transaction credits
|
|
@@ -2735,7 +2752,10 @@ static const struct address_space_operations ext4_da_aops = {
|
|
|
|
|
|
void ext4_set_aops(struct inode *inode)
|
|
void ext4_set_aops(struct inode *inode)
|
|
{
|
|
{
|
|
- if (ext4_should_order_data(inode))
|
|
|
|
|
|
+ if (ext4_should_order_data(inode) &&
|
|
|
|
+ test_opt(inode->i_sb, DELALLOC))
|
|
|
|
+ inode->i_mapping->a_ops = &ext4_da_aops;
|
|
|
|
+ else if (ext4_should_order_data(inode))
|
|
inode->i_mapping->a_ops = &ext4_ordered_aops;
|
|
inode->i_mapping->a_ops = &ext4_ordered_aops;
|
|
else if (ext4_should_writeback_data(inode) &&
|
|
else if (ext4_should_writeback_data(inode) &&
|
|
test_opt(inode->i_sb, DELALLOC))
|
|
test_opt(inode->i_sb, DELALLOC))
|