1 /* 2 * mm/truncate.c - code for taking down pages from address_spaces 3 * 4 * Copyright (C) 2002, Linus Torvalds 5 * 6 * 10Sep2002 akpm@zip.com.au 7 * Initial version. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/mm.h> 12 #include <linux/module.h> 13 #include <linux/pagemap.h> 14 #include <linux/pagevec.h> 15 #include <linux/buffer_head.h> /* grr. try_to_release_page, 16 block_invalidatepage */ 17 18 19 static int do_invalidatepage(struct page *page, unsigned long offset) 20 { 21 int (*invalidatepage)(struct page *, unsigned long); 22 invalidatepage = page->mapping->a_ops->invalidatepage; 23 if (invalidatepage == NULL) 24 invalidatepage = block_invalidatepage; 25 return (*invalidatepage)(page, offset); 26 } 27 28 static inline void truncate_partial_page(struct page *page, unsigned partial) 29 { 30 memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial); 31 if (PagePrivate(page)) 32 do_invalidatepage(page, partial); 33 } 34 35 /* 36 * If truncate cannot remove the fs-private metadata from the page, the page 37 * becomes anonymous. It will be left on the LRU and may even be mapped into 38 * user pagetables if we're racing with filemap_nopage(). 39 * 40 * We need to bale out if page->mapping is no longer equal to the original 41 * mapping. This happens a) when the VM reclaimed the page while we waited on 42 * its lock, b) when a concurrent invalidate_inode_pages got there first and 43 * c) when tmpfs swizzles a page between a tmpfs inode and swapper_space. 44 */ 45 static void 46 truncate_complete_page(struct address_space *mapping, struct page *page) 47 { 48 if (page->mapping != mapping) 49 return; 50 51 if (PagePrivate(page)) 52 do_invalidatepage(page, 0); 53 54 clear_page_dirty(page); 55 ClearPageUptodate(page); 56 ClearPageMappedToDisk(page); 57 remove_from_page_cache(page); 58 page_cache_release(page); /* pagecache ref */ 59 } 60 61 /* 62 * This is for invalidate_inode_pages(). That function can be called at 63 * any time, and is not supposed to throw away dirty pages. But pages can 64 * be marked dirty at any time too. So we re-check the dirtiness inside 65 * ->tree_lock. That provides exclusion against the __set_page_dirty 66 * functions. 67 */ 68 static int 69 invalidate_complete_page(struct address_space *mapping, struct page *page) 70 { 71 if (page->mapping != mapping) 72 return 0; 73 74 if (PagePrivate(page) && !try_to_release_page(page, 0)) 75 return 0; 76 77 spin_lock_irq(&mapping->tree_lock); 78 if (PageDirty(page)) { 79 spin_unlock_irq(&mapping->tree_lock); 80 return 0; 81 } 82 __remove_from_page_cache(page); 83 spin_unlock_irq(&mapping->tree_lock); 84 ClearPageUptodate(page); 85 page_cache_release(page); /* pagecache ref */ 86 return 1; 87 } 88 89 /** 90 * truncate_inode_pages - truncate *all* the pages from an offset 91 * @mapping: mapping to truncate 92 * @lstart: offset from which to truncate 93 * 94 * Truncate the page cache at a set offset, removing the pages that are beyond 95 * that offset (and zeroing out partial pages). 96 * 97 * Truncate takes two passes - the first pass is nonblocking. It will not 98 * block on page locks and it will not block on writeback. The second pass 99 * will wait. This is to prevent as much IO as possible in the affected region. 100 * The first pass will remove most pages, so the search cost of the second pass 101 * is low. 102 * 103 * When looking at page->index outside the page lock we need to be careful to 104 * copy it into a local to avoid races (it could change at any time). 105 * 106 * We pass down the cache-hot hint to the page freeing code. Even if the 107 * mapping is large, it is probably the case that the final pages are the most 108 * recently touched, and freeing happens in ascending file offset order. 109 * 110 * Called under (and serialised by) inode->i_sem. 111 */ 112 void truncate_inode_pages(struct address_space *mapping, loff_t lstart) 113 { 114 const pgoff_t start = (lstart + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT; 115 const unsigned partial = lstart & (PAGE_CACHE_SIZE - 1); 116 struct pagevec pvec; 117 pgoff_t next; 118 int i; 119 120 if (mapping->nrpages == 0) 121 return; 122 123 pagevec_init(&pvec, 0); 124 next = start; 125 while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { 126 for (i = 0; i < pagevec_count(&pvec); i++) { 127 struct page *page = pvec.pages[i]; 128 pgoff_t page_index = page->index; 129 130 if (page_index > next) 131 next = page_index; 132 next++; 133 if (TestSetPageLocked(page)) 134 continue; 135 if (PageWriteback(page)) { 136 unlock_page(page); 137 continue; 138 } 139 truncate_complete_page(mapping, page); 140 unlock_page(page); 141 } 142 pagevec_release(&pvec); 143 cond_resched(); 144 } 145 146 if (partial) { 147 struct page *page = find_lock_page(mapping, start - 1); 148 if (page) { 149 wait_on_page_writeback(page); 150 truncate_partial_page(page, partial); 151 unlock_page(page); 152 page_cache_release(page); 153 } 154 } 155 156 next = start; 157 for ( ; ; ) { 158 if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { 159 if (next == start) 160 break; 161 next = start; 162 continue; 163 } 164 for (i = 0; i < pagevec_count(&pvec); i++) { 165 struct page *page = pvec.pages[i]; 166 167 lock_page(page); 168 wait_on_page_writeback(page); 169 if (page->index > next) 170 next = page->index; 171 next++; 172 truncate_complete_page(mapping, page); 173 unlock_page(page); 174 } 175 pagevec_release(&pvec); 176 } 177 } 178 179 EXPORT_SYMBOL(truncate_inode_pages); 180 181 /** 182 * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode 183 * @mapping: the address_space which holds the pages to invalidate 184 * @start: the offset 'from' which to invalidate 185 * @end: the offset 'to' which to invalidate (inclusive) 186 * 187 * This function only removes the unlocked pages, if you want to 188 * remove all the pages of one inode, you must call truncate_inode_pages. 189 * 190 * invalidate_mapping_pages() will not block on IO activity. It will not 191 * invalidate pages which are dirty, locked, under writeback or mapped into 192 * pagetables. 193 */ 194 unsigned long invalidate_mapping_pages(struct address_space *mapping, 195 pgoff_t start, pgoff_t end) 196 { 197 struct pagevec pvec; 198 pgoff_t next = start; 199 unsigned long ret = 0; 200 int i; 201 202 pagevec_init(&pvec, 0); 203 while (next <= end && 204 pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { 205 for (i = 0; i < pagevec_count(&pvec); i++) { 206 struct page *page = pvec.pages[i]; 207 208 if (TestSetPageLocked(page)) { 209 next++; 210 continue; 211 } 212 if (page->index > next) 213 next = page->index; 214 next++; 215 if (PageDirty(page) || PageWriteback(page)) 216 goto unlock; 217 if (page_mapped(page)) 218 goto unlock; 219 ret += invalidate_complete_page(mapping, page); 220 unlock: 221 unlock_page(page); 222 if (next > end) 223 break; 224 } 225 pagevec_release(&pvec); 226 cond_resched(); 227 } 228 return ret; 229 } 230 231 unsigned long invalidate_inode_pages(struct address_space *mapping) 232 { 233 return invalidate_mapping_pages(mapping, 0, ~0UL); 234 } 235 236 EXPORT_SYMBOL(invalidate_inode_pages); 237 238 /** 239 * invalidate_inode_pages2 - remove all unmapped pages from an address_space 240 * @mapping - the address_space 241 * 242 * invalidate_inode_pages2() is like truncate_inode_pages(), except for the case 243 * where the page is seen to be mapped into process pagetables. In that case, 244 * the page is marked clean but is left attached to its address_space. 245 * 246 * The page is also marked not uptodate so that a subsequent pagefault will 247 * perform I/O to bringthe page's contents back into sync with its backing 248 * store. 249 * 250 * FIXME: invalidate_inode_pages2() is probably trivially livelockable. 251 */ 252 void invalidate_inode_pages2(struct address_space *mapping) 253 { 254 struct pagevec pvec; 255 pgoff_t next = 0; 256 int i; 257 258 pagevec_init(&pvec, 0); 259 while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { 260 for (i = 0; i < pagevec_count(&pvec); i++) { 261 struct page *page = pvec.pages[i]; 262 263 lock_page(page); 264 if (page->mapping == mapping) { /* truncate race? */ 265 wait_on_page_writeback(page); 266 next = page->index + 1; 267 if (page_mapped(page)) { 268 clear_page_dirty(page); 269 ClearPageUptodate(page); 270 } else { 271 invalidate_complete_page(mapping, page); 272 } 273 } 274 unlock_page(page); 275 } 276 pagevec_release(&pvec); 277 cond_resched(); 278 } 279 } 280 281 EXPORT_SYMBOL_GPL(invalidate_inode_pages2); 282
This page was automatically generated by LXR 0.3.1. • Linux is a registered trademark of Linus Torvalds