Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o: - add GETFSMAP support - some performance improvements for very large file systems and for random write workloads into a preallocated file - bug fixes and cleanups. * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: jbd2: cleanup write flags handling from jbd2_write_superblock() ext4: mark superblock writes synchronous for nobarrier mounts ext4: inherit encryption xattr before other xattrs ext4: replace BUG_ON with WARN_ONCE in ext4_end_bio() ext4: avoid unnecessary transaction stalls during writeback ext4: preload block group descriptors ext4: make ext4_shutdown() static ext4: support GETFSMAP ioctls vfs: add common GETFSMAP ioctl definitions ext4: evict inline data when writing to memory map ext4: remove ext4_xattr_check_entry() ext4: rename ext4_xattr_check_names() to ext4_xattr_check_entries() ext4: merge ext4_xattr_list() into ext4_listxattr() ext4: constify static data that is never modified ext4: trim return value and 'dir' argument from ext4_insert_dentry() jbd2: fix dbench4 performance regression for 'nobarrier' mounts jbd2: Fix lockdep splat with generic/270 test mm: retry writepages() on ENOMEM when doing an data integrity writeback
This commit is contained in:
@@ -1643,6 +1643,7 @@ struct mpage_da_data {
|
||||
*/
|
||||
struct ext4_map_blocks map;
|
||||
struct ext4_io_submit io_submit; /* IO submission data */
|
||||
unsigned int do_map:1;
|
||||
};
|
||||
|
||||
static void mpage_release_unused_pages(struct mpage_da_data *mpd,
|
||||
@@ -2179,6 +2180,9 @@ static bool mpage_add_bh_to_extent(struct mpage_da_data *mpd, ext4_lblk_t lblk,
|
||||
|
||||
/* First block in the extent? */
|
||||
if (map->m_len == 0) {
|
||||
/* We cannot map unless handle is started... */
|
||||
if (!mpd->do_map)
|
||||
return false;
|
||||
map->m_lblk = lblk;
|
||||
map->m_len = 1;
|
||||
map->m_flags = bh->b_state & BH_FLAGS;
|
||||
@@ -2231,6 +2235,9 @@ static int mpage_process_page_bufs(struct mpage_da_data *mpd,
|
||||
/* Found extent to map? */
|
||||
if (mpd->map.m_len)
|
||||
return 0;
|
||||
/* Buffer needs mapping and handle is not started? */
|
||||
if (!mpd->do_map)
|
||||
return 0;
|
||||
/* Everything mapped so far and we hit EOF */
|
||||
break;
|
||||
}
|
||||
@@ -2747,6 +2754,29 @@ retry:
|
||||
tag_pages_for_writeback(mapping, mpd.first_page, mpd.last_page);
|
||||
done = false;
|
||||
blk_start_plug(&plug);
|
||||
|
||||
/*
|
||||
* First writeback pages that don't need mapping - we can avoid
|
||||
* starting a transaction unnecessarily and also avoid being blocked
|
||||
* in the block layer on device congestion while having transaction
|
||||
* started.
|
||||
*/
|
||||
mpd.do_map = 0;
|
||||
mpd.io_submit.io_end = ext4_init_io_end(inode, GFP_KERNEL);
|
||||
if (!mpd.io_submit.io_end) {
|
||||
ret = -ENOMEM;
|
||||
goto unplug;
|
||||
}
|
||||
ret = mpage_prepare_extent_to_map(&mpd);
|
||||
/* Submit prepared bio */
|
||||
ext4_io_submit(&mpd.io_submit);
|
||||
ext4_put_io_end_defer(mpd.io_submit.io_end);
|
||||
mpd.io_submit.io_end = NULL;
|
||||
/* Unlock pages we didn't use */
|
||||
mpage_release_unused_pages(&mpd, false);
|
||||
if (ret < 0)
|
||||
goto unplug;
|
||||
|
||||
while (!done && mpd.first_page <= mpd.last_page) {
|
||||
/* For each extent of pages we use new io_end */
|
||||
mpd.io_submit.io_end = ext4_init_io_end(inode, GFP_KERNEL);
|
||||
@@ -2775,8 +2805,10 @@ retry:
|
||||
wbc->nr_to_write, inode->i_ino, ret);
|
||||
/* Release allocated io_end */
|
||||
ext4_put_io_end(mpd.io_submit.io_end);
|
||||
mpd.io_submit.io_end = NULL;
|
||||
break;
|
||||
}
|
||||
mpd.do_map = 1;
|
||||
|
||||
trace_ext4_da_write_pages(inode, mpd.first_page, mpd.wbc);
|
||||
ret = mpage_prepare_extent_to_map(&mpd);
|
||||
@@ -2807,6 +2839,7 @@ retry:
|
||||
if (!ext4_handle_valid(handle) || handle->h_sync == 0) {
|
||||
ext4_journal_stop(handle);
|
||||
handle = NULL;
|
||||
mpd.do_map = 0;
|
||||
}
|
||||
/* Submit prepared bio */
|
||||
ext4_io_submit(&mpd.io_submit);
|
||||
@@ -2824,6 +2857,7 @@ retry:
|
||||
ext4_journal_stop(handle);
|
||||
} else
|
||||
ext4_put_io_end(mpd.io_submit.io_end);
|
||||
mpd.io_submit.io_end = NULL;
|
||||
|
||||
if (ret == -ENOSPC && sbi->s_journal) {
|
||||
/*
|
||||
@@ -2839,6 +2873,7 @@ retry:
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
unplug:
|
||||
blk_finish_plug(&plug);
|
||||
if (!ret && !cycled && wbc->nr_to_write > 0) {
|
||||
cycled = 1;
|
||||
@@ -5855,6 +5890,11 @@ int ext4_page_mkwrite(struct vm_fault *vmf)
|
||||
file_update_time(vma->vm_file);
|
||||
|
||||
down_read(&EXT4_I(inode)->i_mmap_sem);
|
||||
|
||||
ret = ext4_convert_inline_data(inode);
|
||||
if (ret)
|
||||
goto out_ret;
|
||||
|
||||
/* Delalloc case is easy... */
|
||||
if (test_opt(inode->i_sb, DELALLOC) &&
|
||||
!ext4_should_journal_data(inode) &&
|
||||
|
Reference in New Issue
Block a user