mm/truncate.c
Source file repositories/reference/linux-study-clean/mm/truncate.c
File Facts
- System
- Linux kernel
- Corpus path
mm/truncate.c- Extension
.c- Size
- 28103 bytes
- Lines
- 928
- Domain
- Core OS
- Bucket
- Memory Management
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/backing-dev.hlinux/dax.hlinux/gfp.hlinux/mm.hlinux/swap.hlinux/export.hlinux/pagemap.hlinux/highmem.hlinux/folio_batch.hlinux/task_io_accounting_ops.hlinux/shmem_fs.hlinux/rmap.hinternal.h
Detected Declarations
function Copyrightfunction folio_batch_remove_exceptionalsfunction xas_for_eachfunction folio_invalidatefunction truncate_cleanup_foliofunction truncate_inode_foliofunction try_folio_split_or_unmapfunction truncate_inode_partial_foliofunction generic_error_remove_foliofunction mapping_evict_foliofunction offsetsfunction underfunction underfunction invalidate_mapping_pagesfunction invalidate_mapping_pagesfunction folio_launderfunction mapping_evict_foliofunction invalidate_inode_pages2_rangefunction invalidate_inode_pages2function rangefunction truncationfunction page_mkwritefunction rangeexport folio_invalidateexport generic_error_remove_folioexport truncate_inode_pages_rangeexport truncate_inode_pagesexport truncate_inode_pages_finalexport invalidate_mapping_pagesexport invalidate_inode_pages2_rangeexport invalidate_inode_pages2export truncate_pagecacheexport truncate_setsizeexport pagecache_isize_extendedexport truncate_pagecache_range
Annotated Snippet
if (xa_is_value(fbatch->folios[i])) {
/*
* File systems should already have called
* dax_break_layout_entry() to remove all DAX
* entries while holding a lock to prevent
* establishing new entries. Therefore we
* shouldn't find any here.
*/
WARN_ON_ONCE(1);
/*
* Delete the mapping so truncate_pagecache()
* doesn't loop forever.
*/
dax_delete_mapping_entry(mapping, indices[i]);
}
}
goto out;
}
xas_set(&xas, indices[j]);
xas_set_update(&xas, workingset_update_node);
spin_lock(&mapping->host->i_lock);
xas_lock_irq(&xas);
xas_for_each(&xas, folio, indices[nr-1]) {
if (xa_is_value(folio))
xas_store(&xas, NULL);
}
xas_unlock_irq(&xas);
if (mapping_shrinkable(mapping))
inode_lru_list_add(mapping->host);
spin_unlock(&mapping->host->i_lock);
out:
folio_batch_remove_exceptionals(fbatch);
}
/**
* folio_invalidate - Invalidate part or all of a folio.
* @folio: The folio which is affected.
* @offset: start of the range to invalidate
* @length: length of the range to invalidate
*
* folio_invalidate() is called when all or part of the folio has become
* invalidated by a truncate operation.
*
* folio_invalidate() does not have to release all buffers, but it must
* ensure that no dirty buffer is left outside @offset and that no I/O
* is underway against any of the blocks which are outside the truncation
* point. Because the caller is about to free (and possibly reuse) those
* blocks on-disk.
*/
void folio_invalidate(struct folio *folio, size_t offset, size_t length)
{
const struct address_space_operations *aops = folio->mapping->a_ops;
if (aops->invalidate_folio)
aops->invalidate_folio(folio, offset, length);
}
EXPORT_SYMBOL_GPL(folio_invalidate);
/*
* If truncate cannot remove the fs-private metadata from the page, the page
* becomes orphaned. It will be left on the LRU and may even be mapped into
* user pagetables if we're racing with filemap_fault().
*
* We need to bail out if page->mapping is no longer equal to the original
* mapping. This happens a) when the VM reclaimed the page while we waited on
* its lock, b) when a concurrent invalidate_mapping_pages got there first and
* c) when tmpfs swizzles a page between a tmpfs inode and swapper_space.
*/
static void truncate_cleanup_folio(struct folio *folio)
{
if (folio_mapped(folio))
unmap_mapping_folio(folio);
if (folio_needs_release(folio))
folio_invalidate(folio, 0, folio_size(folio));
/*
* Some filesystems seem to re-dirty the page even after
* the VM has canceled the dirty bit (eg ext3 journaling).
* Hence dirty accounting check is placed after invalidation.
*/
folio_cancel_dirty(folio);
}
int truncate_inode_folio(struct address_space *mapping, struct folio *folio)
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/backing-dev.h`, `linux/dax.h`, `linux/gfp.h`, `linux/mm.h`, `linux/swap.h`, `linux/export.h`, `linux/pagemap.h`.
- Detected declarations: `function Copyright`, `function folio_batch_remove_exceptionals`, `function xas_for_each`, `function folio_invalidate`, `function truncate_cleanup_folio`, `function truncate_inode_folio`, `function try_folio_split_or_unmap`, `function truncate_inode_partial_folio`, `function generic_error_remove_folio`, `function mapping_evict_folio`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.