/* Clear all shadow entries from start to max */
xas_for_each(&xas, folio, max) { if (xa_is_value(folio))
xas_store(&xas, NULL);
}
xas_unlock_irq(&xas); if (mapping_shrinkable(mapping))
inode_add_lru(mapping->host);
spin_unlock(&mapping->host->i_lock);
}
/* *Unconditionallyremoveexceptionalentries.Usuallycalledfromtruncate *path.Notethatthefolio_batchmaybealteredbythisfunctionbyremoving *exceptionalentriessimilartowhatfolio_batch_remove_exceptionals()does. *Pleasenotethatindices[]hasentriesinascendingorderasguaranteedby *eitherfind_get_entries()orfind_lock_entries().
*/ staticvoid truncate_folio_batch_exceptionals(struct address_space *mapping, struct folio_batch *fbatch, pgoff_t *indices)
{
XA_STATE(xas, &mapping->i_pages, indices[0]); int nr = folio_batch_count(fbatch); struct folio *folio; int i, j;
/* Handled by shmem itself */ if (shmem_mapping(mapping)) return;
for (j = 0; j < nr; j++) if (xa_is_value(fbatch->folios[j])) break;
if (j == nr) return;
if (dax_mapping(mapping)) { for (i = j; i < nr; i++) { if (xa_is_value(fbatch->folios[i])) { /* *Filesystemsshouldalreadyhavecalled *dax_break_layout_entry()toremoveallDAX *entrieswhileholdingalocktoprevent *establishingnewentries.Thereforewe *shouldn'tfindanyhere.
*/
WARN_ON_ONCE(1);
/* *Usedtogetridofpagesonhardwarememorycorruption.
*/ int generic_error_remove_folio(struct address_space *mapping, struct folio *folio)
{ if (!mapping) return -EINVAL; /* *Onlypunchfornormaldatapagesfornow. *Handlingothertypeslikedirectorieswouldneedmoreauditing.
*/ if (!S_ISREG(mapping->host->i_mode)) return -EIO; return truncate_inode_folio(mapping, folio);
}
EXPORT_SYMBOL(generic_error_remove_folio);
/** *mapping_evict_folio()-Removeanunusedfoliofromthepage-cache. *@mapping:Themappingthisfoliobelongsto. *@folio:Thefoliotoremove. * *Safelyremoveonefoliofromthepagecache. *Itonlydropsclean,unusedfolios. * *Context:Foliomustbelocked. *Return:Thenumberofpagessuccessfullyremoved.
*/ long mapping_evict_folio(struct address_space *mapping, struct folio *folio)
{ /* The page may have been truncated before it was locked */ if (!mapping) return0; if (folio_test_dirty(folio) || folio_test_writeback(folio)) return0; /* The refcount will be elevated if any page in the folio is mapped */ if (folio_ref_count(folio) >
folio_nr_pages(folio) + folio_has_private(folio) + 1) return0; if (!filemap_release_folio(folio, 0)) return0;
folio_batch_init(&fbatch);
index = start; while (index < end && find_lock_entries(mapping, &index, end - 1,
&fbatch, indices)) {
truncate_folio_batch_exceptionals(mapping, &fbatch, indices); for (i = 0; i < folio_batch_count(&fbatch); i++)
truncate_cleanup_folio(fbatch.folios[i]);
delete_from_page_cache_batch(mapping, &fbatch); for (i = 0; i < folio_batch_count(&fbatch); i++)
folio_unlock(fbatch.folios[i]);
folio_batch_release(&fbatch);
cond_resched();
}
if (!same_folio) {
folio = __filemap_get_folio(mapping, lend >> PAGE_SHIFT,
FGP_LOCK, 0); if (!IS_ERR(folio)) { if (!truncate_inode_partial_folio(folio, lstart, lend))
end = folio->index;
folio_unlock(folio);
folio_put(folio);
}
}
index = start; while (index < end) {
cond_resched(); if (!find_get_entries(mapping, &index, end - 1, &fbatch,
indices)) { /* If all gone from start onwards, we're done */ if (index == start) break; /* Otherwise restart to make sure all gone */
index = start; continue;
}
for (i = 0; i < folio_batch_count(&fbatch); i++) { struct folio *folio = fbatch.folios[i];
/* We rely upon deletion not changing folio->index */
folio_batch_init(&fbatch); while (find_lock_entries(mapping, &index, end, &fbatch, indices)) { bool xa_has_values = false; int nr = folio_batch_count(&fbatch);
for (i = 0; i < nr; i++) { struct folio *folio = fbatch.folios[i];
/* We rely upon deletion not changing folio->index */
if (xa_is_value(folio)) {
xa_has_values = true;
count++; continue;
}
ret = mapping_evict_folio(mapping, folio);
folio_unlock(folio); /* *Invalidationisahintthatthefolioisnolonger *ofinterestandtrytospeedupitsreclaim.
*/ if (!ret) {
deactivate_file_folio(folio); /* Likely in the lru cache of a remote CPU */ if (nr_failed)
(*nr_failed)++;
}
count += ret;
}
if (xa_has_values)
clear_shadow_entries(mapping, indices[0], indices[nr-1]);
if (folio_mapped(folio))
unmap_mapping_folio(folio);
BUG_ON(folio_mapped(folio));
ret = folio_launder(mapping, folio); if (ret) return ret; if (folio->mapping != mapping) return -EBUSY; if (!filemap_release_folio(folio, gfp)) return -EBUSY;
spin_lock(&mapping->host->i_lock);
xa_lock_irq(&mapping->i_pages); if (folio_test_dirty(folio)) goto failed;
BUG_ON(folio_has_private(folio));
__filemap_remove_folio(folio, NULL);
xa_unlock_irq(&mapping->i_pages); if (mapping_shrinkable(mapping))
inode_add_lru(mapping->host);
spin_unlock(&mapping->host->i_lock);
/** *invalidate_inode_pages2_range-removerangeofpagesfromanaddress_space *@mapping:theaddress_space *@start:thepageoffset'from'whichtoinvalidate *@end:thepageoffset'to'whichtoinvalidate(inclusive) * *Anypageswhicharefoundtobemappedintopagetablesareunmappedpriorto *invalidation. * *Return:-EBUSYifanypagescouldnotbeinvalidated.
*/ int invalidate_inode_pages2_range(struct address_space *mapping,
pgoff_t start, pgoff_t end)
{
pgoff_t indices[PAGEVEC_SIZE]; struct folio_batch fbatch;
pgoff_t index; int i; int ret = 0; int ret2 = 0; int did_range_unmap = 0;
if (mapping_empty(mapping)) return0;
folio_batch_init(&fbatch);
index = start; while (find_get_entries(mapping, &index, end, &fbatch, indices)) { bool xa_has_values = false; int nr = folio_batch_count(&fbatch);
for (i = 0; i < nr; i++) { struct folio *folio = fbatch.folios[i];
/* We rely upon deletion not changing folio->index */
if (xa_is_value(folio)) {
xa_has_values = true; if (dax_mapping(mapping) &&
!dax_invalidate_mapping_entry_sync(mapping, indices[i]))
ret = -EBUSY; continue;
}
if (from >= to || bsize >= PAGE_SIZE) return; /* Page straddling @from will not have any hole block created? */
rounded_from = round_up(from, bsize); if (to <= rounded_from || !(rounded_from & (PAGE_SIZE - 1))) return;
folio = filemap_lock_folio(inode->i_mapping, from / PAGE_SIZE); /* Folio not cached? Nothing to do */ if (IS_ERR(folio)) return; /* *Seefolio_clear_dirty_for_io()fordetailswhyfolio_mark_dirty() *isneeded.
*/ if (folio_mkclean(folio))
folio_mark_dirty(folio);
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.24Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.