static void cifs_fscache_inode_now_uncached(void *cookie_netfs_data) { struct cifsInodeInfo *cifsi = cookie_netfs_data; struct pagevec pvec; pgoff_t first; int loop, nr_pages; pagevec_init(&pvec, 0); first = 0; cFYI(1, "cifs inode 0x%p now uncached", cifsi); for (;;) { nr_pages = pagevec_lookup(&pvec, cifsi->vfs_inode.i_mapping, first, PAGEVEC_SIZE - pagevec_count(&pvec)); if (!nr_pages) break; for (loop = 0; loop < nr_pages; loop++) ClearPageFsCache(pvec.pages[loop]); first = pvec.pages[nr_pages - 1]->index + 1; pvec.nr = nr_pages; pagevec_release(&pvec); cond_resched(); } }
/* * invalidate part or all of a page * - release a page and clean up its private data if offset is 0 (indicating * the entire page) */ static void afs_invalidatepage(struct page *page, unsigned long offset) { struct afs_writeback *wb = (struct afs_writeback *) page_private(page); _enter("{%lu},%lu", page->index, offset); BUG_ON(!PageLocked(page)); /* we clean up only if the entire page is being invalidated */ if (offset == 0) { #ifdef CONFIG_AFS_FSCACHE if (PageFsCache(page)) { struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); fscache_wait_on_page_write(vnode->cache, page); fscache_uncache_page(vnode->cache, page); ClearPageFsCache(page); } #endif if (PagePrivate(page)) { if (wb && !PageWriteback(page)) { set_page_private(page, 0); afs_put_writeback(wb); } if (!page_private(page)) ClearPagePrivate(page); } } _leave(""); }
/* * indication the cookie is no longer uncached * - this function is called when the backing store currently caching a cookie * is removed * - the netfs should use this to clean up any markers indicating cached pages * - this is mandatory for any object that may have data */ static void afs_vnode_cache_now_uncached(void *cookie_netfs_data) { struct afs_vnode *vnode = cookie_netfs_data; struct pagevec pvec; pgoff_t first; int loop, nr_pages; _enter("{%x,%x,%Lx}", vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version); pagevec_init(&pvec, 0); first = 0; for (;;) { /* grab a bunch of pages to clean */ nr_pages = pagevec_lookup(&pvec, vnode->vfs_inode.i_mapping, first, PAGEVEC_SIZE - pagevec_count(&pvec)); if (!nr_pages) break; for (loop = 0; loop < nr_pages; loop++) ClearPageFsCache(pvec.pages[loop]); first = pvec.pages[nr_pages - 1]->index + 1; pvec.nr = nr_pages; pagevec_release(&pvec); cond_resched(); } _leave(""); }
/* * Indication from FS-Cache that the cookie is no longer cached * - This function is called when the backing store currently caching a cookie * is removed * - The netfs should use this to clean up any markers indicating cached pages * - This is mandatory for any object that may have data */ static void nfs_fscache_inode_now_uncached(void *cookie_netfs_data) { struct nfs_inode *nfsi = cookie_netfs_data; struct pagevec pvec; pgoff_t first; int loop, nr_pages; pagevec_init(&pvec, 0); first = 0; dprintk("NFS: nfs_inode_now_uncached: nfs_inode 0x%p\n", nfsi); for (;;) { /* grab a bunch of pages to unmark */ nr_pages = pagevec_lookup(&pvec, nfsi->vfs_inode.i_mapping, first, PAGEVEC_SIZE - pagevec_count(&pvec)); if (!nr_pages) break; for (loop = 0; loop < nr_pages; loop++) ClearPageFsCache(pvec.pages[loop]); first = pvec.pages[nr_pages - 1]->index + 1; pvec.nr = nr_pages; pagevec_release(&pvec); cond_resched(); } }
static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data) { struct v9fs_inode *v9inode = cookie_netfs_data; struct pagevec pvec; pgoff_t first; int loop, nr_pages; pagevec_init(&pvec, 0); first = 0; for (;;) { nr_pages = pagevec_lookup(&pvec, v9inode->vfs_inode.i_mapping, first, PAGEVEC_SIZE - pagevec_count(&pvec)); if (!nr_pages) break; for (loop = 0; loop < nr_pages; loop++) ClearPageFsCache(pvec.pages[loop]); first = pvec.pages[nr_pages - 1]->index + 1; pvec.nr = nr_pages; pagevec_release(&pvec); cond_resched(); } }
/* * release a page and clean up its private state if it's not busy * - return true if the page can now be released, false if not */ static int afs_releasepage(struct page *page, gfp_t gfp_flags) { struct afs_writeback *wb = (struct afs_writeback *) page_private(page); struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); _enter("{{%x:%u}[%lu],%lx},%x", vnode->fid.vid, vnode->fid.vnode, page->index, page->flags, gfp_flags); /* deny if page is being written to the cache and the caller hasn't * elected to wait */ #ifdef CONFIG_AFS_FSCACHE if (PageFsCache(page)) { if (fscache_check_page_write(vnode->cache, page)) { if (!(gfp_flags & __GFP_WAIT)) { _leave(" = F [cache busy]"); return 0; } fscache_wait_on_page_write(vnode->cache, page); } fscache_uncache_page(vnode->cache, page); ClearPageFsCache(page); } #endif if (PagePrivate(page)) { if (wb) { set_page_private(page, 0); afs_put_writeback(wb); } ClearPagePrivate(page); } /* indicate that the page can be released */ _leave(" = T"); return 1; }