Discussion:
[PATCH] ext4: move_extent explicitly invalidate page buffers
Dmitry Monakhov
2014-10-23 11:48:58 UTC
Permalink
In hard core test-cases such as ext4/301, ext4/302 some bh may
becomes dirty so try_to_release_page() will fail and result in
false positive EBUSY failures. We can easily fix that by
explicit ->invalidatepage() after we holds page which is locked
and uptodate.

Tested-by: Xiaoguang Wang<***@cn.fujitsu.com>
Signed-off-by: Dmitry Monakhov <***@openvz.org>
---
fs/ext4/move_extent.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index c2b2b02..76c45b6 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -348,8 +348,9 @@ again:
!try_to_release_page(pagep[0], 0)) ||
(page_has_private(pagep[1]) &&
!try_to_release_page(pagep[1], 0))) {
- *err = -EBUSY;
- goto drop_data_sem;
+ /* One of buffers is busy, fall back data copy */
+ ext4_double_up_write_data_sem(orig_inode, donor_inode);
+ goto data_copy;
}
replaced_count = ext4_swap_extents(handle, orig_inode,
donor_inode, orig_blk_offset,
@@ -360,12 +361,15 @@ again:
goto unlock_pages;
}
data_copy:
- *err = mext_page_mkuptodate(pagep[0], from, from + replaced_size);
+ /* In order to drop all buffers we have to make page fully uptodate */
+ *err = mext_page_mkuptodate(pagep[0], 0, PAGE_CACHE_SIZE);
if (*err)
goto unlock_pages;

/* At this point all buffers in range are uptodate, old mapping layout
* is no longer required, try to drop it now. */
+ do_invalidatepage(pagep[0], 0, PAGE_CACHE_SIZE);
+ do_invalidatepage(pagep[1], 0, PAGE_CACHE_SIZE);
if ((page_has_private(pagep[0]) && !try_to_release_page(pagep[0], 0)) ||
(page_has_private(pagep[1]) && !try_to_release_page(pagep[1], 0))) {
*err = -EBUSY;
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Monakhov
2014-10-23 13:03:31 UTC
Permalink
Post by Dmitry Monakhov
In hard core test-cases such as ext4/301, ext4/302 some bh may
becomes dirty so try_to_release_page() will fail and result in
false positive EBUSY failures. We can easily fix that by
explicit ->invalidatepage() after we holds page which is locked
and uptodate.
Sorry. This patch is not correct. Please ignore it.
Post by Dmitry Monakhov
---
fs/ext4/move_extent.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index c2b2b02..76c45b6 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
!try_to_release_page(pagep[0], 0)) ||
(page_has_private(pagep[1]) &&
!try_to_release_page(pagep[1], 0))) {
- *err = -EBUSY;
- goto drop_data_sem;
+ /* One of buffers is busy, fall back data copy */
+ ext4_double_up_write_data_sem(orig_inode, donor_inode);
+ goto data_copy;
}
replaced_count = ext4_swap_extents(handle, orig_inode,
donor_inode, orig_blk_offset,
goto unlock_pages;
}
- *err = mext_page_mkuptodate(pagep[0], from, from + replaced_size);
+ /* In order to drop all buffers we have to make page fully uptodate */
+ *err = mext_page_mkuptodate(pagep[0], 0, PAGE_CACHE_SIZE);
if (*err)
goto unlock_pages;
/* At this point all buffers in range are uptodate, old mapping layout
* is no longer required, try to drop it now. */
+ do_invalidatepage(pagep[0], 0, PAGE_CACHE_SIZE);
+ do_invalidatepage(pagep[1], 0, PAGE_CACHE_SIZE);
if ((page_has_private(pagep[0]) && !try_to_release_page(pagep[0], 0)) ||
(page_has_private(pagep[1]) && !try_to_release_page(pagep[1], 0))) {
*err = -EBUSY;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...