* [PATCH] ext4: Don't release page refs in ext4_end_bio()
@ 2012-03-02 16:19 Curt Wohlgemuth
2012-03-05 15:42 ` Ted Ts'o
0 siblings, 1 reply; 2+ messages in thread
From: Curt Wohlgemuth @ 2012-03-02 16:19 UTC (permalink / raw)
To: tytso, adilger.kernel; +Cc: linux-ext4, Curt Wohlgemuth
We can clear PageWriteback on each page when the IO
completes, but we can't release the references on the page
until we convert any uninitialized extents.
Without this patch, the use of the dioread_nolock mount
option can break buffered writes, because extents may
not be converted by the time a subsequent buffered read
comes in; if the page is not in the page cache, a read
will return zeros if the extent is still uninitialized.
I tested this with a (temporary) patch that adds a call
to msleep(1000) at the start of ext4_end_io_work(), to delay
processing of each DIO-unwritten work queue item. With this
msleep(), a simple workload of
fallocate
write
fadvise
read
will fail without this patch, succeeds with it.
Signed-off-by: Curt Wohlgemuth <curtw@google.com>
---
fs/ext4/page-io.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index e6271fe..0991c22 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -63,7 +63,6 @@ void ext4_ioend_wait(struct inode *inode)
static void put_io_page(struct ext4_io_page *io_page)
{
if (atomic_dec_and_test(&io_page->p_count)) {
- end_page_writeback(io_page->p_page);
put_page(io_page->p_page);
kmem_cache_free(io_page_cachep, io_page);
}
@@ -235,9 +234,9 @@ static void ext4_end_bio(struct bio *bio, int error)
} while (bh != head);
}
- put_io_page(io_end->pages[i]);
+ if (atomic_read(&io_end->pages[i]->p_count) == 1)
+ end_page_writeback(io_end->pages[i]->p_page);
}
- io_end->num_io_pages = 0;
inode = io_end->inode;
if (error) {
@@ -429,6 +428,8 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
* PageWriteback bit from the page to prevent the system from
* wedging later on.
*/
+ if (atomic_read(&io_page->p_count) == 1)
+ end_page_writeback(page);
put_io_page(io_page);
return ret;
}
--
1.7.7.3
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] ext4: Don't release page refs in ext4_end_bio()
2012-03-02 16:19 [PATCH] ext4: Don't release page refs in ext4_end_bio() Curt Wohlgemuth
@ 2012-03-05 15:42 ` Ted Ts'o
0 siblings, 0 replies; 2+ messages in thread
From: Ted Ts'o @ 2012-03-05 15:42 UTC (permalink / raw)
To: Curt Wohlgemuth; +Cc: adilger.kernel, linux-ext4
On Fri, Mar 02, 2012 at 08:19:59AM -0800, Curt Wohlgemuth wrote:
> We can clear PageWriteback on each page when the IO
> completes, but we can't release the references on the page
> until we convert any uninitialized extents.
>
> Without this patch, the use of the dioread_nolock mount
> option can break buffered writes, because extents may
> not be converted by the time a subsequent buffered read
> comes in; if the page is not in the page cache, a read
> will return zeros if the extent is still uninitialized.
>
> I tested this with a (temporary) patch that adds a call
> to msleep(1000) at the start of ext4_end_io_work(), to delay
> processing of each DIO-unwritten work queue item. With this
> msleep(), a simple workload of
>
> fallocate
> write
> fadvise
> read
>
> will fail without this patch, succeeds with it.
>
> Signed-off-by: Curt Wohlgemuth <curtw@google.com>
Thanks, applied.
- Ted
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-03-05 15:42 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-02 16:19 [PATCH] ext4: Don't release page refs in ext4_end_bio() Curt Wohlgemuth
2012-03-05 15:42 ` Ted Ts'o
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).