>yes thats a useful optimization indeed - was in my queue :). Although
>put_page(page,2) in truncate_inode_pages() is a bug if you look harder,
>the last put_page() is the 'final' one as well.
No, I don't free_page in try_to_free_buffers. Here it is my current code:
relevant part of try_to_free_buffers:
("int shared" is set if the buffer heads had the BH_Shared bitflag set)
[..]
/* And free the page */
page->buffers = NULL;
if (!shared) {
buffermem -= PAGE_SIZE;
return FREE_BUFFER_SUCCESS_LOCAL;
}
return FREE_BUFFER_SUCCESS_SHARED;
[..]
relevant part of flushpage:
[..]
if (!page->buffers)
return 1;
[..]
if (!offset)
{
int ret;
ret = try_to_free_buffers(page);
if (!(ret & (FREE_BUFFER_SUCCESS_SHARED|FREE_BUFFER_BUSY)))
goto weird;
unlock_kernel();
return ret == FREE_BUFFER_SUCCESS_SHARED;
weird:
printk(KERN_DEBUG "flushpage: free_buffers retval %d\n", ret);
}
[..]
relevant part of truncate_inode_pages:
int additional_refcount;
get_page(page);
spin_unlock(&pagecache_lock);
lock_page(page);
additional_refcount = 1;
if (inode->i_op->flushpage)
if (inode->i_op->flushpage(inode, page, 0))
{
additional_refcount = 2;
lru_pages_del(page);
}
/*
* We remove the page from the page cache
* _after_ we have destroyed all buffer-cache
* references to it. Otherwise some other process
* might think this inode page is not in the
* page cache and creates a buffer-cache alias
* to it causing all sorts of fun problems ...
*/
remove_inode_page(page);
UnlockPage(page);
put_page_refcount(additional_refcount, page);
page_cache_release(page);
Andrea Arcangeli
-
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/