sbin/cleanerd: cap segments per clean by available free segments

If the file system is low on free segments, the number of segments
requested for cleaning ('nsegs_per_step') may exceed the number of
actual free segments ('ncleansegs').

Cap 'nsegs_per_step' to 'ncleansegs' in nilfs_cleanerd_select_segments().
This serves as an entry-level guard to prevent invalid requests and
helps prevent filesystem operations from getting stuck when free space
is running out.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
This commit is contained in:
Ryusuke Konishi 2026-01-24 22:13:32 +09:00
parent 4a733f7ff0
commit 48b71515fc

View File

@ -686,6 +686,20 @@ nilfs_cleanerd_select_segments(struct nilfs_cleanerd *cleanerd,
int i;
nsegs_per_step = nilfs_cleanerd_nsegs_per_step(cleanerd);
if (nsegs_per_step > sustat->ss_ncleansegs) {
syslog(LOG_DEBUG,
"reducing segments per cleaning step from %u to %u "
"(ncleansegs)",
nsegs_per_step, (unsigned int)sustat->ss_ncleansegs);
nsegs_per_step = (unsigned int)sustat->ss_ncleansegs;
/*
* Even if nsegs_per_step becomes 0, fall through to update
* timestamps. This ensures nilfs_cleanerd_recalc_interval()
* sets a short retry interval.
*/
}
nilfs = cleanerd->nilfs;
smv = nilfs_vector_create(sizeof(struct nilfs_segimp));