fs/ubifs/shrinker.c
Source file repositories/reference/linux-study-clean/fs/ubifs/shrinker.c
File Facts
- System
- Linux kernel
- Corpus path
fs/ubifs/shrinker.c- Extension
.c- Size
- 9230 bytes
- Lines
- 320
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: implementation source
- Status
- source 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
ubifs.h
Detected Declarations
function shrink_tncfunction atomic_long_readfunction mutexfunction absfunction shrink_tnc_treesfunction kick_a_threadfunction list_for_each_entryfunction ubifs_shrink_countfunction ubifs_shrink_scan
Annotated Snippet
atomic_long_read(&c->clean_zn_cnt) > 0) {
int freed;
/*
* If the znode is clean, but it is in the 'c->cnext' list, this
* means that this znode has just been written to flash as a
* part of commit and was marked clean. They will be removed
* from the list at end commit. We cannot change the list,
* because it is not protected by any mutex (design decision to
* make commit really independent and parallel to main I/O). So
* we just skip these znodes.
*
* Note, the 'clean_zn_cnt' counters are not updated until
* after the commit, so the UBIFS shrinker does not report
* the znodes which are in the 'c->cnext' list as freeable.
*
* Also note, if the root of a sub-tree is not in 'c->cnext',
* then the whole sub-tree is not in 'c->cnext' as well, so it
* is safe to dump whole sub-tree.
*/
if (znode->cnext) {
/*
* Very soon these znodes will be removed from the list
* and become freeable.
*/
*contention = 1;
} else if (!ubifs_zn_dirty(znode) &&
abs(time - znode->time) >= age) {
if (znode->parent)
znode->parent->zbranch[znode->iip].znode = NULL;
else
c->zroot.znode = NULL;
freed = ubifs_destroy_tnc_subtree(c, znode);
atomic_long_sub(freed, &ubifs_clean_zn_cnt);
atomic_long_sub(freed, &c->clean_zn_cnt);
total_freed += freed;
znode = zprev;
}
if (unlikely(!c->zroot.znode))
break;
zprev = znode;
znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode);
cond_resched();
}
return total_freed;
}
/**
* shrink_tnc_trees - shrink UBIFS TNC trees.
* @nr: number of znodes to free
* @age: the age of znodes to free
* @contention: if any contention, this is set to %1
*
* This function walks the list of mounted UBIFS file-systems and frees clean
* znodes which are older than @age, until at least @nr znodes are freed.
* Returns the number of freed znodes.
*/
static int shrink_tnc_trees(int nr, int age, int *contention)
{
struct ubifs_info *c;
struct list_head *p;
unsigned int run_no;
int freed = 0;
spin_lock(&ubifs_infos_lock);
do {
run_no = ++shrinker_run_no;
} while (run_no == 0);
/* Iterate over all mounted UBIFS file-systems and try to shrink them */
p = ubifs_infos.next;
while (p != &ubifs_infos) {
c = list_entry(p, struct ubifs_info, infos_list);
/*
* We move the ones we do to the end of the list, so we stop
* when we see one we have already done.
*/
if (c->shrinker_run_no == run_no)
break;
if (!mutex_trylock(&c->umount_mutex)) {
/* Some un-mount is in progress, try next FS */
*contention = 1;
p = p->next;
continue;
}
/*
Annotation
- Immediate include surface: `ubifs.h`.
- Detected declarations: `function shrink_tnc`, `function atomic_long_read`, `function mutex`, `function abs`, `function shrink_tnc_trees`, `function kick_a_thread`, `function list_for_each_entry`, `function ubifs_shrink_count`, `function ubifs_shrink_scan`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: source 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.