Patch for 2.3.22: revert invalidate_inode_pages() to 2.2.x-behaviour

Trond Myklebust (trond.myklebust@fys.uio.no)
Thu, 21 Oct 1999 23:37:43 +0200 (CEST)


Hi Linus,

The invalidate_inode_pages() code seems to have been modified during
the 2.3.x rewrite to wait on unlocked pages. This seriously breaks NFS
since page invalidation can occur in the rpciod process context in the
cases of page reading/writing. Since the rpciod may be holding locks
for several other pages from the same inode, but in different
requests, this causes a deadlock.

I'd therefore like to revert to the behaviour under 2.2.x. Processes
which need to invalidate all pages, and which are able to wait on them
may in any case call 'truncate_inode_pages(inode,0)' to obtain the
exact same behaviour as the stock 2.3.21 invalidate_inode_pages().

The following patch will reimplement the 2.2.x behaviour. I've added
in a 'ClearageUptodate()' that should provide a less intrusive way of
invalidating those pages that are locked. This means that in the NFS
read callback we will be able to do something like:

nfs_refresh_inode(inode, fattr); /* May call invalidate_inode_pages() */
SetPageUptodate(&page); /* Mark page valid */
UnlockPage(page); /* Unlock it */

to invalidate all pages except for the one we just read in...

Cheers,
Trond

--- mm/filemap.c.orig Mon Oct 11 19:44:11 1999
+++ mm/filemap.c Thu Oct 21 23:21:53 1999
@@ -110,6 +110,11 @@
spin_unlock(&pagecache_lock);
}

+/*
+ * This function should not call wait_on_page!
+ * It is for invalidating those pages that are
+ * not in the process of being updated.
+ */
void invalidate_inode_pages(struct inode * inode)
{
struct page ** p;
@@ -119,24 +124,17 @@
spin_lock(&pagecache_lock);
p = &inode->i_pages;
while ((page = *p) != NULL) {
- get_page(page);
- if (TryLockPage(page)) {
- spin_unlock(&pagecache_lock);
- wait_on_page(page);
- page_cache_release(page);
- goto repeat;
+ if (PageLocked(page)) {
+ ClearPageUptodate(page);
+ p = &page->next;
+ continue;
}
- if (page_count(page) != 2)
- printk("hm, busy page invalidated? (not necessarily a bug)\n");
lru_cache_del(page);

remove_page_from_inode_queue(page);
remove_page_from_hash_queue(page);
page->inode = NULL;
- UnlockPage(page);
page_cache_release(page);
- page_cache_release(page);
-
}
spin_unlock(&pagecache_lock);
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/