linux/mm/truncate.c
<<
>>
Prefs
   1/*
   2 * mm/truncate.c - code for taking down pages from address_spaces
   3 *
   4 * Copyright (C) 2002, Linus Torvalds
   5 *
   6 * 10Sep2002    Andrew Morton
   7 *              Initial version.
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/backing-dev.h>
  12#include <linux/gfp.h>
  13#include <linux/mm.h>
  14#include <linux/swap.h>
  15#include <linux/export.h>
  16#include <linux/pagemap.h>
  17#include <linux/highmem.h>
  18#include <linux/pagevec.h>
  19#include <linux/task_io_accounting_ops.h>
  20#include <linux/buffer_head.h>  /* grr. try_to_release_page,
  21                                   do_invalidatepage */
  22#include <linux/cleancache.h>
  23#include "internal.h"
  24
  25
  26/**
  27 * do_invalidatepage - invalidate part or all of a page
  28 * @page: the page which is affected
  29 * @offset: the index of the truncation point
  30 *
  31 * do_invalidatepage() is called when all or part of the page has become
  32 * invalidated by a truncate operation.
  33 *
  34 * do_invalidatepage() does not have to release all buffers, but it must
  35 * ensure that no dirty buffer is left outside @offset and that no I/O
  36 * is underway against any of the blocks which are outside the truncation
  37 * point.  Because the caller is about to free (and possibly reuse) those
  38 * blocks on-disk.
  39 */
  40void do_invalidatepage(struct page *page, unsigned long offset)
  41{
  42        void (*invalidatepage)(struct page *, unsigned long);
  43        invalidatepage = page->mapping->a_ops->invalidatepage;
  44#ifdef CONFIG_BLOCK
  45        if (!invalidatepage)
  46                invalidatepage = block_invalidatepage;
  47#endif
  48        if (invalidatepage)
  49                (*invalidatepage)(page, offset);
  50}
  51
  52static inline void truncate_partial_page(struct page *page, unsigned partial)
  53{
  54        zero_user_segment(page, partial, PAGE_CACHE_SIZE);
  55        cleancache_invalidate_page(page->mapping, page);
  56        if (page_has_private(page))
  57                do_invalidatepage(page, partial);
  58}
  59
  60/*
  61 * This cancels just the dirty bit on the kernel page itself, it
  62 * does NOT actually remove dirty bits on any mmap's that may be
  63 * around. It also leaves the page tagged dirty, so any sync
  64 * activity will still find it on the dirty lists, and in particular,
  65 * clear_page_dirty_for_io() will still look at the dirty bits in
  66 * the VM.
  67 *
  68 * Doing this should *normally* only ever be done when a page
  69 * is truncated, and is not actually mapped anywhere at all. However,
  70 * fs/buffer.c does this when it notices that somebody has cleaned
  71 * out all the buffers on a page without actually doing it through
  72 * the VM. Can you say "ext3 is horribly ugly"? Tought you could.
  73 */
  74void cancel_dirty_page(struct page *page, unsigned int account_size)
  75{
  76        if (TestClearPageDirty(page)) {
  77                struct address_space *mapping = page->mapping;
  78                if (mapping && mapping_cap_account_dirty(mapping)) {
  79                        dec_zone_page_state(page, NR_FILE_DIRTY);
  80                        dec_bdi_stat(mapping->backing_dev_info,
  81                                        BDI_RECLAIMABLE);
  82                        if (account_size)
  83                                task_io_account_cancelled_write(account_size);
  84                }
  85        }
  86}
  87EXPORT_SYMBOL(cancel_dirty_page);
  88
  89/*
  90 * If truncate cannot remove the fs-private metadata from the page, the page
  91 * becomes orphaned.  It will be left on the LRU and may even be mapped into
  92 * user pagetables if we're racing with filemap_fault().
  93 *
  94 * We need to bale out if page->mapping is no longer equal to the original
  95 * mapping.  This happens a) when the VM reclaimed the page while we waited on
  96 * its lock, b) when a concurrent invalidate_mapping_pages got there first and
  97 * c) when tmpfs swizzles a page between a tmpfs inode and swapper_space.
  98 */
  99static int
 100truncate_complete_page(struct address_space *mapping, struct page *page)
 101{
 102        if (page->mapping != mapping)
 103                return -EIO;
 104
 105        if (page_has_private(page))
 106                do_invalidatepage(page, 0);
 107
 108        cancel_dirty_page(page, PAGE_CACHE_SIZE);
 109
 110        ClearPageMappedToDisk(page);
 111        delete_from_page_cache(page);
 112        return 0;
 113}
 114
 115/*
 116 * This is for invalidate_mapping_pages().  That function can be called at
 117 * any time, and is not supposed to throw away dirty pages.  But pages can
 118 * be marked dirty at any time too, so use remove_mapping which safely
 119 * discards clean, unused pages.
 120 *
 121 * Returns non-zero if the page was successfully invalidated.
 122 */
 123static int
 124invalidate_complete_page(struct address_space *mapping, struct page *page)
 125{
 126        int ret;
 127
 128        if (page->mapping != mapping)
 129                return 0;
 130
 131        if (page_has_private(page) && !try_to_release_page(page, 0))
 132                return 0;
 133
 134        ret = remove_mapping(mapping, page);
 135
 136        return ret;
 137}
 138
 139int truncate_inode_page(struct address_space *mapping, struct page *page)
 140{
 141        if (page_mapped(page)) {
 142                unmap_mapping_range(mapping,
 143                                   (loff_t)page->index << PAGE_CACHE_SHIFT,
 144                                   PAGE_CACHE_SIZE, 0);
 145        }
 146        return truncate_complete_page(mapping, page);
 147}
 148
 149/*
 150 * Used to get rid of pages on hardware memory corruption.
 151 */
 152int generic_error_remove_page(struct address_space *mapping, struct page *page)
 153{
 154        if (!mapping)
 155                return -EINVAL;
 156        /*
 157         * Only punch for normal data pages for now.
 158         * Handling other types like directories would need more auditing.
 159         */
 160        if (!S_ISREG(mapping->host->i_mode))
 161                return -EIO;
 162        return truncate_inode_page(mapping, page);
 163}
 164EXPORT_SYMBOL(generic_error_remove_page);
 165
 166/*
 167 * Safely invalidate one page from its pagecache mapping.
 168 * It only drops clean, unused pages. The page must be locked.
 169 *
 170 * Returns 1 if the page is successfully invalidated, otherwise 0.
 171 */
 172int invalidate_inode_page(struct page *page)
 173{
 174        struct address_space *mapping = page_mapping(page);
 175        if (!mapping)
 176                return 0;
 177        if (PageDirty(page) || PageWriteback(page))
 178                return 0;
 179        if (page_mapped(page))
 180                return 0;
 181        return invalidate_complete_page(mapping, page);
 182}
 183
 184/**
 185 * truncate_inode_pages_range - truncate range of pages specified by start & end byte offsets
 186 * @mapping: mapping to truncate
 187 * @lstart: offset from which to truncate
 188 * @lend: offset to which to truncate
 189 *
 190 * Truncate the page cache, removing the pages that are between
 191 * specified offsets (and zeroing out partial page
 192 * (if lstart is not page aligned)).
 193 *
 194 * Truncate takes two passes - the first pass is nonblocking.  It will not
 195 * block on page locks and it will not block on writeback.  The second pass
 196 * will wait.  This is to prevent as much IO as possible in the affected region.
 197 * The first pass will remove most pages, so the search cost of the second pass
 198 * is low.
 199 *
 200 * We pass down the cache-hot hint to the page freeing code.  Even if the
 201 * mapping is large, it is probably the case that the final pages are the most
 202 * recently touched, and freeing happens in ascending file offset order.
 203 */
 204void truncate_inode_pages_range(struct address_space *mapping,
 205                                loff_t lstart, loff_t lend)
 206{
 207        const pgoff_t start = (lstart + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
 208        const unsigned partial = lstart & (PAGE_CACHE_SIZE - 1);
 209        struct pagevec pvec;
 210        pgoff_t index;
 211        pgoff_t end;
 212        int i;
 213
 214        cleancache_invalidate_inode(mapping);
 215        if (mapping->nrpages == 0)
 216                return;
 217
 218        BUG_ON((lend & (PAGE_CACHE_SIZE - 1)) != (PAGE_CACHE_SIZE - 1));
 219        end = (lend >> PAGE_CACHE_SHIFT);
 220
 221        pagevec_init(&pvec, 0);
 222        index = start;
 223        while (index <= end && pagevec_lookup(&pvec, mapping, index,
 224                        min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
 225                mem_cgroup_uncharge_start();
 226                for (i = 0; i < pagevec_count(&pvec); i++) {
 227                        struct page *page = pvec.pages[i];
 228
 229                        /* We rely upon deletion not changing page->index */
 230                        index = page->index;
 231                        if (index > end)
 232                                break;
 233
 234                        if (!trylock_page(page))
 235                                continue;
 236                        WARN_ON(page->index != index);
 237                        if (PageWriteback(page)) {
 238                                unlock_page(page);
 239                                continue;
 240                        }
 241                        truncate_inode_page(mapping, page);
 242                        unlock_page(page);
 243                }
 244                pagevec_release(&pvec);
 245                mem_cgroup_uncharge_end();
 246                /*);

edtrum/tru11 nam" id=2i 149
PageWritebget rid o2 pages on hardware memor2 corr25           }
 227                        struct truncate_a>        const  151page);
PageWritebgpage(* 111                        unlocke.c#L153"2id="L153" class="line" n2me="L25">index,
  name="L"line" name="L241"> 241  name="L"line                        do_invalidatepage(page<2if (!mapping)
 242                        unlocketurn - 214="L244" class="line" name=<"> 214="L244"                        unlocke"+code=co6         152pvec;
 222        ind>->i_mode))
"mm/t ; ; back" class="sref">PageWriteb     retu2n - 246                ,2end && pagevec_lookup(&pvec, mappe.c#L163"2id="L163" class="line" n2me="L26">index,
 224                        min(end - index, (pgoff_t)generic_err2r_rem26mapping)
 ="line" name="L222"> 222        trylockte.c#L1652 id="L165" class="line" 2ame="26   continue;
 166index);
 222        ind>   * Onl2 one page from its pagec2che m26page)) {
page);
 169 ="line" name="L222"> 222        indes="sref">page *page = loff_t)) 244                pagevec_release" name="L271"> 171page);
page2*page);
 225                 226                for (i = 0; i < pagevec_count(&mapping)
 227                        struct page *page = pvec. 176     2     27     return;
page))
 229                        /* We res="line" 2ame="L178"> 178     2     2728"> 228
 230                        index = pageapped2page))
 231                        if (ins="line" 2ame="L180"> 180     2     28           }
,2pagd="L232" class="line" nameppage2id="L182" class="line" n2me="L28mapping,
 242                        unlockte.c#L1832 id="L183" class="line" 2ame="28">index,
 236                        WARN_ON(page->index" name="L284"> 184)
 111 111                        unlockpages spe2ified by start & end2byte 28   continue;
 241                        truncate_inode_page(maplass="com2ent"> * @mapping: mappin2 to t28>index);
 242                        unlockment"> * 2lstart: offset from whic2 to t28">page))
 228
 244                pagevec_releasee" name="2189"> 189page))
 245                /*);
page);
"mm/truncate.c#L243" id="L2="comment2> * (if lstart is not pa2e ali29mapping,
"mm/truncate.c#Lcate.c#L214" id="L214" class="line" name="L214"> 214        cleancache_invalidate_inode 193 *"mm/truncate.c#L243" id="L2= name="L2rst pass is nonblocking.2 It w2ll not 164truncate.c#L204" id="L204" class="line" name="L204"> 204void  204vs="line" nam*all*" name="L19L187"panspan cate.c#L184" id="L184" class="lin2scomment"28 * 2s low.
 186 199 *
 187 187  s clas) "> 20      _mutexcomment"> * recently touched, and3freeing h3ppens in ascending file 3ffset3order.
 * recently touched, and3f4eeing h3p93"> 193 *
 * recently touched, and3f5eeing h3pst pass is nonblocking.3"sref30l not
 111  ()) c id="Late.c#L191id  * The first pass will remove m3loff_t
 167 * Safely3e=PAGE_CA3HE_SHIFT" class="sref">P3GE_CA30 pass
/* We r3AGE_CACHE3SIZE" class="sref">PAGE_3ACHE_3IZE
 204vne" nef="+code=generic_error_remove_page" class="sref">generic_error_remove_page(struct  205                                i3agevecpage)
index;
 204void truncate_                   143   -t & (page);
 164truncate.c#L204" id= class="line" name="L204"> 204vne"  & ( a> & (
nrp31 pass
 216   3     31ncate
PAGE_C3CHE_S31 low.
PA3E_CAC32t"> *
.c#L1" class clas"L242"ss="line,=catyou waline"ree.c#L184" id="L184" class="lin3=pgoff_t<3href="+code=pvec" class=3sref"32 most
an 67"   1cass cme="L204"> 204va> * Safely3ex = 3a href="+code=start" cla3s="sr32rder.
 * recently touched, and3ing, 3a href="+code=index" cla3s="sr32t"> *
 * Truncate takes two pass3GEVEC_SIZ3" class="sref">PAGEVEC_S3ZE
 classass=dne" ,mem_cgroup_u3charg32 pass
va> * Safely3e7ff_t/* We r3sref">pag3s[f="mm/trulongf="mm/truncate.c#L181" id="> 142ve" nie" na22an cl181" id="> 142vne" nef="+code=generic_error_remove_page" class="sref">generic_error_remove_page(struct /* We r3sGE_CACHE3 id="L228" class="line" 3ame="3228"> 228
 207        const truncate_icate.c#L211" id="L211" class="line" name="L211"> 211        i3ly upon d3letion not changing page3>i33f">page)
index;
 209        struct 3dex &3t;  210         222        in3="L232"> 332                  3     33mapping,
f="mm/trulongf="mm/truncate.cre22        in3=ng, 3 id="L233" class="line" 3ame="3233"> 233
f="mm/trulongf="mm/truncate.cef">i = 0; in3=EVEC_SIZ3page))
 23235"> 2353/a>                     3     33 passeancache_invalidate_inode3 != <3 href="+code=index" clas3="sre3">index);
165

 167
 20n="mm/trunclasmam/t"lin(becaus"  mment"> * Truncate takes two pass3239"> 2393/a>                     3     34t"> *
an swap mm/L158); but  m's="linlinworthnworryspacent"> * Truncate takes two pass32/a>->3ame="L240"> 240     3     34f the
 * Truncate takes two pass32ex &3avsr1any=dnfficulti>va> * Safely3_page3/* We r343" class3"line" name="L243"> 243<3a>   3413"> a> & (pvec);
cate.c#L241" idL244" idL221" id="L221" class="line" name="L221"> 221        pagevec_initmem_cgroup3uncha3ge_end();
 223        while (index <= end && pagevec_lookup(&pvec, map3="+code=c3nd_reschedtruncate.c#L223" id=3L220" class="line" na"c);
cate.c#L241" id="L224" class="line" name="L224"> 224                        min(end - index, (pgoff_t)page))
 225                 228
 226                for (i = 0; i < pagevec_count(& 149page))
 227                        struct page *page = pvec. &351"> 151page);
 229                        /* We r3gpage3* 230                        index = pag3e.c#L153"3id="L153" class="line" n3me="L35">index,
 231                        if (i3if (!mapping)
         234                        if (!tryloc3    * Onl3 punch for normal data p3ges f35">page))
 228
 236                        WARN_ON(page->inde3L159"> 153         230               181                      unloc3>-> 242                        unloc3     retu3n -
 201170" c4"> ulonger> * The first pass will remove m3e.c#L163"3id="L163" class="line" n3me="L36t"> *
 2186"spe="cup itscatelaima> * Safely3ove_page"3class="sref">generic_err3r_rem36l not
/* We r3te.c#L1653 id="L165" class="line" 3ame="36   continue;
tryloc3e" name="3166"> 166index);
                        unloc3    * Onl3 one page from its pagec3che m36page)) {
i = 0;  230      re22        in3s clean, 3nused pages. The page mu3t be 36">page);
 169 244                pagevec_releas3 page is 3uccessfully invalidated,3other37           }
 245                 171page);
 246                page3*page);
page->/*);
<3e.c#L173"3id="L173" class="line" n3me="L37           }
am" id=2ii = 0; /*);
<3ee.c#L1653ef="+code=mapping" class3"sref3>mappiam" id=2i 176     3     37     ="mm/truncate.c="mm/truncate.c#L164" id="L164" class="line" name="L164"> 164#L181" id="> 142ve" nie" na22an cl181" id="> 142vne" 6                   * Onl3i];
 178     3     37ting.
 *
       ef=pme="L(), except201" gnores" name="L'scate.c#L166" id="L166" class="li3apage is 3ame="L180"> 180     3     38f the
 181          s2() ne="s=catonger> * The first pass will remove m3ping,3 22afford186"> 2v ""line>be="ld1becaus"> * The first pass will remove m3ppage3id="L182" class="line" n3me="L38rder.
 242_list() has astempc idc/a> nam, or becaus"  nay'ss="raasi.c#L2> * The first pass will remove m3p.c#L173"3 id="L183" class="line" 3ame="38t"> *
 214add() ame="L2va> * Safely3" name="L384"> 184
/* We r3pages spe3ified by start & end3byte 38   cost="2c
/* We r3p" name="3ent"> * @mapping: mappin3 to t38     ="mm/truncate.c       ef=pme="L2e" nie" na22an cl181" id="ef=pme="L2ne" nef="+code=generic_error_remove_page" class="sref">generic_error_remove_page(struct  227                        struct tryloc3ment"> * 3lstart: offset from whic3 to t38">pagef="+code=pvec" clp_unchar3"comment"3 * @lend: offset to whic3 to t3828"> 228
cf="+code=pvec" clp_unchar3e" name="3189"> 189page))
page);
                         244s="line" name="L234"> 2_to44"> 244s="li                        tryloc3="comment3> * (if lstart is not pa3e ali39">page);
 193 a> & (pvec);
cate.c#L241" ids="s_L242"irq.c#L164" id="L1s="s_L242"irq                 215tree_L242ne" name="L234"> ee_L242ne" 6                page);
, (tryloc3eass="com3O as possible in the aff3cted 39>index);
/*);
<3st pages,3so the search cost of th3 seco39ref">i];
 * 39E - 1));
                         199pvec;
 111       111                          unloc4hot hint 4o the page freeing code.4 Even40">index;
irq.c#L164" id="L1s="s_"L242">irq                 215tree_L242ne" name="L234"> ee_L242ne" 6                , 0);
 245         "> 214         245         "> 214                            unloc4h3t hint 4o * (if lstart is not pa4ffset40      break;
 193page);
 215a_opve" nie" na22an a_opvne" name="L215"> 215clas        cf="+code=pvec" clp_unchar4f5eeing h4pst pass is nonblocking.4"sref40">pvec);
 215a_opve" nie" na22an a_opvne" name="L215"> 215clas                                unloc4h6eeing h4pblock on writeback.  Th4ss="s40 passeancache_invalidate_inode4l7ff_t  4="L244" class="line" name=<"> 214="L244"                        /* We r4e=PAGE_CA4HE_SHIFT" class="sref">P4GE_CA40page)) {
"mm/tru1k_page" class="sref">unloc4h9PAGE_CA4Hunloc4agevecpvec;
irq.c#L164" id="L1s="s_"L242">irq                 215tree_L242ne" name="L234"> ee_L242ne" 6                 4a href="+code=index" cla4s="sr4f">index;
"mm/trun                pgoff_t<4a> page);
 st="2c
generic_error_remove_page(struct  227                        struct tryloc4>5eeing h4f="+code=mapping" class=4sref"41l notef="+code=pvec" clp_unchar4nrp416>page);
, (tryloc4<7ff_t 216   4     41>index);
 ||="mm/truncate.c#L.c#L215" id="L215" class="line" name="L215"> 215a_opve" nie" na22an a_opvne" name="L215"> 215laulasrass="line" name="L18laulasrass="ne"  ="line" name="L222NULe.c#L164" id="L1NULe hre_page" class="sref">tryloc4>9PAGE_CA4IZE" class="sref">PAGE_C4CHE_S41">page);
PA4E_CAC420>index;
"mm/tru"mm/truncate.c#L.c#L215" id="L215" class="line" name="L215"> 215a_opve" nie" na22an a_opvne" name="L215"> 215laulasrass="line" name="L18laulasrass="ne"                         unloc4=f_t 4 id="L220" class="line" 4ame="42f thee);
pagd="L232" class="line" nam4ex = 4a href="+code=start" cla4s="sr42rder.
 *
PAGEVEC_S4ZE
mem_cgroup_u4charg42 pass
pag4s[
 classass=found186"be " name
vsass=un" name
priorne"ree.c#L184" id="L184" class="lin4ly upon d4letion not changing page4>i43t"> *
 * Safely4->4a href="+code=index" cla4s="sr43f the
 187couldne" na"  "> 181 * Safely4 = 432                  4     43rder.
/* We r4=ng, 4 id="L233" class="line" 4ame="4233"> generic_error_remove_page(struct /* We r4=5eeing h4pvec);
 207        const truncate_icate.c#L211" id="L211" class="line" name="L211"> 211        i4235"> 2354/a>                     4     43 passef="+code=pvec" clp_unchar4 != <4 href="+code=index" clas4="sre4">index);
 209        struct 4ack(<4 href="+code=page" class4"sref438>page);
sref">truncate_icate.c#L211" id="L211" class="line" name="L211">sref">index = pag4aGE_CACHE4 228
 24239"> 2394/a>                     4     4408"> 228
                ->4ame="L240"> 240     4     4418"> 228
                 &4 228
                 = 4 243<4a>   444>page);
sref">truncate_Lcate.c#L214" id="L214" class="line" name="L214"> 214        cleancache_invalidate_inode4(&4pvec);
cate.c#L241" idL244" idL221" id="L221" class="line" name="L221"> 221        pagevec_initmem_cgroup4uncha4ge_end();
e" name="L211">sref">index =  222        in4="+code=c4nd_reschedtruncate.c#L224" id=4L220" class="l 223        while (index <= end && pagevec_lookup(&pvec, map4=ck(<4y pages.  But pages can<4span>44">page))
();
e" name="L211">="L224" class="line" name="L224"> 224                        min(end - index, (pgoff_t) 228
 245         s="line" name="L225"> 225                 149page))
 226                for (i = 0; i < pagevec_count(&->4 pages on hardware memor4 corr45           }
 227                        struct page *page = pvec. &451"> 151pagd="L232" class="line" nam4gpage4* 229                        /* We r4e.c#L153"4id="L153" class="line" n4me="L45">index,
sref">index = index = pag4if (!mapping)
 231                        if (i4eturn -        page))
 215l242" class="line" name=242"> 242                        unloc4ypes like4directories would need m4re au4528"> 228
 236                        WARN_ON(page->inde4L159"> 154href="+code=pvec" clp_unchar4>-> 242                        unloc4     retu4n -);
index,
#L19_on> 111 111                        unloc4ove_page"4class="sref">generic_err4r_rem46mapping)
turn -"+code=c4166"> 166index);

 * Safely4s clean, 4nused pages. The page mu4t be 46ting.
/* We r4e" name="4169"> 169 142 142=mapping" class="sref">map4 page is 4uccessfully invalidated,4other47           }
 143   ="mm/truncate.c#L223" id="L223" class="line" name(, (=mapping" class="sref">map4     retu471"> 171page);
 143   (1 +"L223"> 223        while (min(i4>page4*page);
, (=mapping" class="sref">map4 .c#L163"4id="L173" class="line" n4me="L47">index,
pagevec_initpvec);
unloc4ee.c#L1654ef="+code=mapping" class4"sref47   continue;
 176     4     47>index);

 1zapL nis e=trylte.c#L166" id="L166" class="li4> clean, 4ame="L178"> 178     4     47ting.
/* We r4apped4 142 142=mapping" class="sref">map4apage is 4ame="L180"> 180     4     48           }
 143   ="mm/truncate.c#L223" id="L223" class="line" name(, (=mapping" class="sref">map4ping,4page);
, (pagevec_init4id="L182" class="line" n4me="L48">page);
);
index,
 184pvec);
pagevec_initpagevec_lookup(&unloc4p" name="4ent"> * @mapping: mappin4 to t48220" class="line" na""mm/truncateref="mm/truncatre22e" nie" na22an re22="+c30=" cref="+code=pvec" clp_unchar4ment"> * 4lstart: offset from whic4 to t48">page))
2e" nie" na22an cl181" id="ef=pme="L2ne" nlass="sref">pagevec_lookup(&i4"comment"4 * @lend: offset to whic4 to t4828"> 228
pag4e" name="4189"> 189page))
);
i4specified4offsets (and zeroing out4parti49">page);
pag4epage4> * (if lstart is not pa4e ali49">page);
 242                        unloc4p.c#L173"4193"> 193index,
);
pvec);
 244                pagevec_releas4eages spe4 block on writeback.  Th4 seco49   continue;
 245         s="line" name="L245"> 245                index);
 246                page))
page->/*);
<4scomment"48 * 49E - 1));
e);
 199pvec;
 214        cleancache_invalidate_inode5hot hint 5o the page freeing code.5 Even50">index;
"mm/truref="mm/truncatre2e" nie" na22an re2="+cleancache_invalidate_inode5h2t hint 5offsets (and zeroing out5are t50">page);
                 s2oid  193 a> & (


P5GE_CA50ncate

 classass=found186"be " name
vsass=un" name
priorne"ree.c#L184" id="L184" class="lin5agevec *
 * Safely5ff_t 5a href="+code=index" cla5s="sr51f the
 187couldne" na"  "> 181 * Safely52    5   int 
/* We r5>4eeing h5 id="L213" class="line" 5ame="5133"> generic_error_remove_page(struct i5>5eeing h5f="+code=mapping" class=5sref"51l notef="+code=pvec" clp_unchar5nrp516>page);
"mm/truref="mm/truncate/a>                 s2oid pagevec_lookup(& 216   5     51>indee);
                 s2e" nie" na22an cl181" id="          s2ref=cleancache_invalidate_inode5<9PAGE_CA5IZE" class="sref">PAGE_C5CHE_S51">pageancache_invalidate_inode5=PAGE_CAC5E_SHIFT" class="sref">PA5E_CAC52t"> *
 21c-=un" n=02" atclassode="> 21ce01">has beenc" class=date.c#L184" id="L184" class="lin5=pgoff_t<5href="+code=pvec" class=5sref"52 most
 *
PAGEVEC_S5ZE
mem_cgroup_u5charg52 pass
 1already a" wlastencbefoss="rclass=_ode="> 21ree.c#L184" id="L184" class="lin5=7ff_t * Safely5sref">pag5s[
shouldntypicassy a" cass="cbefoss="lasf hrsystemree.c#L184" id="L184" class="lin5ly upon d5letion not changing page5>i53t"> *
 244scatsourc>vsassociss=d with="lasfre="cid  21cwiss always=caay logicassy cohere" clte.c#L166" id="L166" class="li5has alreadyclte.c#L166" id="L166" class="li5<4eeing h5 id="L233" class="line" 5ame="53t"> *
 * Safely5=5eeing h5/* We r5235"> 2355/a>                     5     53 passvoiduref="mm/truncat"rclass=_ode="> 21e" nie" na22an "rclass=_ode="> 21ref="ef="+code=generic_erro" class="line" name= (stru" class="line" name=  143  e=pvec" class="soldsiz e" name="L143">oldsiz ref=de=pvec" class="ss="line" name="L143"> 143  e=pvec" class="snewsiz e" name="L143">newsiz ce" code=index" class="sref">i5 != <5 href="+code=index" clas5="sre5">indeef="+code=pvec" clp_unchar5ack(<5 href="+code=page" class5"sref538>page);
ef="+code=generic_error_remove_page" class="sref">generic_error_remove_page(struct  230       143  e=pvec" class="sholebeg"L224" class="linholebeg"L="+c30"ref="mm/truncatround_ newsiz ce" de=pvec" class="sode=_S, ( 2395/a>                     5     5408"> eancache_invalidate_inode52/a>->5ame="L240"> 240     5     5418"> 228
e/span>
 142 rclass=_          s doL19Lewer> * The first pass will remove m543" class5"line" name="L243"> 243<5a>   54t"> *
 1cass,=02"> * The first pass will remove m545eeing h5 2355 class="sref">mem_cgroup5uncha54 pass
86"be COWed,> classremain/aftemcate.c#L166" id="L166" class="li52/a> != <5nd_reschedtruncate.c#L225" id=54ncate
 142 1be " de "mm correctnrica> * Safely5=GE_CACHE5 id="L148" class="line" 5ame="54ting.
/* We r5e" name="5149"> 149pvec;
 142 142=e=pvec" class="sholebeg"L224" class="linholebeg"L="+cde0, 1cleancache_invalidate_inode5e/a>->5 pages on hardware memor5 corr55">index;
=e=pvec" class="snewsiz e" name="L143">newsiz ce" cleancache_invalidate_inode5eex &551"> 151, 0);
 142 142=e=pvec" class="sholebeg"L224" class="linholebeg"L="+cde0, 1cleancache_invalidate_inode5e    5*indref="mm/truncatE4" class="li.c#L164" id="L164" class="liref="+code=cleancach"rclass=_ode="> 21e" nie" na22an "rclass=_ode="> 21ref=cleancache_invalidate_inode5e5eeing h5ef="+code=mapping" class5"sref5>mappieancache_invalidate_inode5e35"> 2355href="+code=EINVAL" clas5="sre55 pass
        
 155 *

86"@newsiz . Itcwiss be typicassy a" cass="cL187""lasf hrsystem'scate.c#L166" id="L166" class="li5ping,5when ATTR_S * Safely5e.c#L163"5id="L163" class="line" n5me="L56t"> *
 * Safely5e5eeing h5class="sref">generic_err5r_rem56l not
 1be cass="cwith=      mutex=held 02" befoss=ass f hrsystem specific> * Safely5e35"> 2355 id="L165" class="line" 5ame="56 pass
has beencoer"mmm="a> * Safely5>"+code=c5166"> 166
/* We r5    * Onl5 one page from its pagec5che m56 now.voiduref="mm/truncat"rclass=_setsiz e" nie" na22an "rclass=_setsiz ref="ef="+code=generic_erro" class="line" name= (stru" class="line" name=  143  e=pvec" class="snewsiz e" name="L143">newsiz ce" code=index" class="sref">i5s clean, 5nused pages. The page mu5t be 56ting.ef="+code=pvec" clp_unchar5e" name="5169"> 169pvec;
 143  e=pvec" class="soldsiz e" name="L143">oldsiz ref=leancache_invalidate_inode5 page is 5uccessfully invalidated,5other57     href="+code=pages" class=5     retu571"> 171, 0);
oldsiz ref=30"> 230      s_siz ref=leancache_invalidate_inode5 ing,5*page);
ARN_ON" class="s_siz s_siz newsiz ce" cleancache_invalidate_inode5 .c#L163"5id="L173" class="line" n5me="L5713"> a> & (pvec);
ref="mm/truncat"rclass=_ode="> 21e" nie" na22an "rclass=_ode="> 21ref="+code=cleancache/class="line" name= oldsiz ref=de=pvec" class="snewsiz e" name="L143">newsiz ce" cleancache_invalidate_inode5 35"> 2355ef="+code=mapping" class5"sref57   coe);
 176     5     57     ="mm/truncate.cE4" class="li.c#L164" id="L164" class="liref="+code=cleancach"rclass=_setsiz e" nie" na22an "rclass=_setsiz ref=cleancache_invalidate_inode5    * Onl5i];
 178     5     57ting.
 *
 21oid  s hole-p    =date.c#L184" id="L184" class="lin5apage is 5ame="L180"> 180     5     58f the
 *
 * Safely5pve_page"584"> 184
 244scatsourc>vsassociss=d with="lasfre="cid  * @mapping: mappin5 to t58ncate
 21cwiss always=caay logicassy cohere" clte.c#L166" id="L166" class="li5ment"> * 5lstart: offset from whic5 to t58ncate

has alreadyclte.c#L166" id="L166" class="li5e" name="5189"> 189 *
 * Safely5page cach5, removing the pages tha5 are 59f the
/* We r5specified5offsets (and zeroing out5parti59">pagvoiduref="mm/truncat"rclass=_ode="> 21aid  21aid (stru" class="line" name=  143  e=pvec" class="sls="line" name="L225"lref="+cod="sref">truncate_s="line" name="L143"> 143  e=pvec" class="sls="line" name="L24lhref="+code=index" class="sref">i5epage5> * (if lstart is not pa5e ali59">pagef="+code=pvec" clp_unchar5p.c#L173"5193"> 193index,
ef="+code=generic_error_remove_page" class="sref">generic_error_remove_page(struct  230      pvec);
ref="mm/truncats="line" name="L143"> 143  e=pvec" class="s="" n"s="line" name="L225"="" n"s="li="+c30"ref="mm/truncatround_ truncate_ode=_S, (s="line" name="L143"> 143  e=pvec" class="s="" n"s="line" name="L24="" n"s="="+c30"ref="mm/truncatround_dowL224" class="linround_dowLref="1 +"L223"> 223 ls="line" name="L24lhref="+="sref">truncate_ode=_S, ( 1"mm/exa=pme: ="" n"> 142 * 59ting.
 199 *
 21oid 
 ;=02" "rclass=_          said handl>vspf="ialcate.c#L166" id="L166" class="li6h3t hint 6o * (if lstart is not pa6ffset60rder.
ref=" of hole, but e" n  ="ial 170" 1">hre of hole).c No  ree.c#L184" id="L184" class="lin6h4t hint 6o93"> 193 *
 142 * Safely6f5eeing h6pst pass is nonblocking.6"sref60l not
/* We r6h6eeing h6pblock on writeback.  Th6ss="s60 passn class="comment">/* We r6h7eeing h6p as possible in the aff6me="L60>index);
e/span>
P6GE_CA60ncate
 21, ="" n"> 142
 21),=02" without "even_cows" flag:clte.c#L166" id="L166" class="li6agevec *
 * Safely6ff_t 6a href="+code=index" cla6s="sr61f the
/* We r6>pgoff_t<6a>  228
 * ="mm/truncate.c="" n"s="line" name="L24="" n"s="="+c3231 * ="mm/truncate.c="" n"s="line" name="L225"="" n"s="li="+ccode=index" class="sref">i62    6   int page);
 142 142=e=pvec" class="s="" n"s="line" name="L225"="" n"s="li="+c=mapping" class="sref">map6>4eeing h6 id="L213" class="line" 6ame="61">index,
 223 ="" n"s="line" name="L24="" n"s="="+c3 href="+code=min"="" n"s="line" name="L225"="" n"s="li="+c=" class="sref">pagevec_init5eeing h6f="+code=mapping" class=6sref"61">pvec);
ref="mm/truncat"rclass=_          said =e=pvec" class="sls="line" name="L225"lref="+cod="sref">truncate_ss="line" name="L24lhref="+class="sref">pagevec_init6eeing h6code=nrpages" class="sre6">nrp61   coe);
 216   6     61     ="mm/truncate.cE4" class="li.c#L164" id="L164" class="liref="+code=cleancach"rclass=_ode="> 21aid  21aid pagevec_init=PAGE_CA6 id="L217" class="line" 6ame="618>pagr/pregr/div>


r/div>


Tlasoriginal LXR software by""lasss="sref"http://sourc>fosge.net/projects/lxr">LXR ef="unity+cod=" nis exseri"mm/al vemsby"ss="sref">ailto:lxr@claux.no24lxr@claux.no+cod.
r/div>

lxr.claux.no kindlyshoss=d by"ss="sref"http://www.redpill-clapro.no24Redpill Llapro AS+cod="provider of Llauxc239suls    02" oser="229s=cervic>vssincs=1995.
r/div>