Re: [PATCH] aio: propogate post-EIOCBQUEUED errors to completionevent

From: Trond Myklebust
Date: Tue Feb 20 2007 - 11:38:50 EST


On Tue, 2007-02-20 at 11:30 -0500, Trond Myklebust wrote:
> > One option is to have invalidate_inode_pages2_range continue if it can't
> > toss a page but still return something that O_DIRECT ignores (living
> > with the race), but it looks like I can make a launder_page op that does
> > the right thing. I'll give it a shot.
>
> I already sent in a patch to do that last week.

To be more precise, here are the 2 patches that I sent to lkml last
week. One ensures that we don't stop the invalidation just because of
the existence of an unsynced dirty page. The other gets rid of the EIO
for that case.

Cheers
Trond

--- Begin Message --- Fix invalidate_inode_pages2_range() so that it does not immediately exit
just because a single page in the specified range could not be removed.

Signed-off-by: Trond Myklebust <Trond.Myklebust@xxxxxxxxxx>
---

mm/truncate.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/truncate.c b/mm/truncate.c
index ebf3fcb..0f4b6d1 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -375,10 +375,10 @@ int invalidate_inode_pages2_range(struct address_space *mapping,

pagevec_init(&pvec, 0);
next = start;
- while (next <= end && !ret && !wrapped &&
+ while (next <= end && !wrapped &&
pagevec_lookup(&pvec, mapping, next,
min(end - next, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
- for (i = 0; !ret && i < pagevec_count(&pvec); i++) {
+ for (i = 0; i < pagevec_count(&pvec); i++) {
struct page *page = pvec.pages[i];
pgoff_t page_index;


--- End Message ---
--- Begin Message --- invalidate_inode_pages2() should not try to fix races between direct_IO and
mmap(). It should only be trying to clear out pages that were dirty before
the direct_IO write (see generic_file_direct_IO()).
Skipping dirty pages should therefore not result in an error.

Signed-off-by: Trond Myklebust <Trond.Myklebust@xxxxxxxxxx>
---

mm/truncate.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/mm/truncate.c b/mm/truncate.c
index 0f4b6d1..c3ff820 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -318,6 +318,8 @@ EXPORT_SYMBOL(invalidate_mapping_pages);
* invalidation guarantees, and cannot afford to leave pages behind because
* shrink_list() has a temp ref on them, or because they're transiently sitting
* in the lru_cache_add() pagevecs.
+ * Note: this function just skips pages that are dirty without flagging
+ * an error.
*/
static int
invalidate_complete_page2(struct address_space *mapping, struct page *page)
@@ -330,7 +332,7 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)

write_lock_irq(&mapping->tree_lock);
if (PageDirty(page))
- goto failed;
+ goto dirty;

BUG_ON(PagePrivate(page));
__remove_from_page_cache(page);
@@ -338,9 +340,9 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
ClearPageUptodate(page);
page_cache_release(page); /* pagecache ref */
return 1;
-failed:
+dirty:
write_unlock_irq(&mapping->tree_lock);
- return 0;
+ return 1;
}

static int do_launder_page(struct address_space *mapping, struct page *page)

--- End Message ---