From 558870c26406c43ae88362371a3236c9cd74caa2 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 19 Feb 2010 00:10:11 +0000 Subject: [PATCH] --- yaml --- r: 188724 b: refs/heads/master c: c9af9fb68e01eb2c2165e1bc45cfeeed510c64e6 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/ceph/inode.c | 46 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index ef2757f86feb..73daf5e5b40a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e63dc5c780ba32d6d8b3662eecce2b8d96489b41 +refs/heads/master: c9af9fb68e01eb2c2165e1bc45cfeeed510c64e6 diff --git a/trunk/fs/ceph/inode.c b/trunk/fs/ceph/inode.c index d7d5d4923772..7abe1aed819b 100644 --- a/trunk/fs/ceph/inode.c +++ b/trunk/fs/ceph/inode.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "super.h" #include "decode.h" @@ -1279,6 +1280,49 @@ void ceph_queue_invalidate(struct inode *inode) } } +/* + * invalidate any pages that are not dirty or under writeback. this + * includes pages that are clean and mapped. + */ +static void ceph_invalidate_nondirty_pages(struct address_space *mapping) +{ + struct pagevec pvec; + pgoff_t next = 0; + int i; + + pagevec_init(&pvec, 0); + while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { + for (i = 0; i < pagevec_count(&pvec); i++) { + struct page *page = pvec.pages[i]; + pgoff_t index; + int skip_page = + (PageDirty(page) || PageWriteback(page)); + + if (!skip_page) + skip_page = !trylock_page(page); + + /* + * We really shouldn't be looking at the ->index of an + * unlocked page. But we're not allowed to lock these + * pages. So we rely upon nobody altering the ->index + * of this (pinned-by-us) page. + */ + index = page->index; + if (index > next) + next = index; + next++; + + if (skip_page) + continue; + + generic_error_remove_page(mapping, page); + unlock_page(page); + } + pagevec_release(&pvec); + cond_resched(); + } +} + /* * Invalidate inode pages in a worker thread. (This can't be done * in the message handler context.) @@ -1305,7 +1349,7 @@ static void ceph_invalidate_work(struct work_struct *work) orig_gen = ci->i_rdcache_gen; spin_unlock(&inode->i_lock); - truncate_inode_pages(&inode->i_data, 0); + ceph_invalidate_nondirty_pages(inode->i_mapping); spin_lock(&inode->i_lock); if (orig_gen == ci->i_rdcache_gen) {