Re: Request for export of truncate_complete_page

From: Oleg Drokin
Date: Tue Feb 21 2006 - 06:28:51 EST


Hello!

On Mon, Feb 20, 2006 at 09:54:10PM -0800, Andrew Morton wrote:
> > Can I ask for truncate_complete_page() to be exported?
> > For Lustre filesystem it is necessary to poke out pages in the middle of
> > a file, but truncate_inode_pages() is not very suitable, because we
> > poke those pages one at a time when locks on those pages are cancelled, but
> > we cannot kill entire set of pages as a group, because there might be some
> > other lock that covers a subset of those pages, so we still need to iterate
> > through all of them, and while we are at it, it is easier to kill pages
> > as we check them one by one.
> Isn't truncate_inode_pages_range() suitable?

No, for the reason I specified above. We still walk entire region on page by
page basis, checking that page is not covered by other locks that might warrant
its exclusion from truncating, pushing writing of the page if it is still dirty
and needs to be written (or clearing its dirty flag if it needs to be
discarded).
So we have sort of reimplemented truncate_inode_pages_range() with extra logic
specific to Lustre and calling truncate_inode_pages_range() for every page
we want to get rid of is overkill.

> > +EXPORT_SYMBOL(truncate_complete_page);
> _GPL would be nicer. Plus a comment to keep people from "cleaning it up".

Not that I mind if it is GPL or not, but currently truncate_complete_page()
can be reimplemented with EXPORT_SYMBOL stuff only. Here's how:

static inline void ll_remove_from_page_cache(struct page *page)
{
struct address_space *mapping = page->mapping;

BUG_ON(!PageLocked(page));

write_lock_irq(&mapping->tree_lock);
radix_tree_delete(&mapping->page_tree, page->index);
page->mapping = NULL;
mapping->nrpages--;
atomic_add(-1, &nr_pagecache); // XXX pagecache_acct(-1);
write_unlock_irq(&mapping->tree_lock);
}

static inline void
truncate_complete_page(struct address_space *mapping, struct page *page)
{
if (page->mapping != mapping)
return;

if (PagePrivate(page))
page->mapping->a_ops->invalidatepage(page, 0);

clear_page_dirty(page);
ClearPageUptodate(page);
ClearPageMappedToDisk(page);
ll_remove_from_page_cache(page);
page_cache_release(page); /* pagecache ref */
}

Bye,
Oleg
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/