if (!test_bit(FinalCheckpoint, &fs->fsstate))
lafs_seg_apply_all(fs);
lafs_clean_free(fs);
- if (test_bit(EmergencyPending, &fs->fsstate))
+ if (test_bit(EmergencyPending, &fs->fsstate)) {
set_bit(EmergencyClean, &fs->fsstate);
+ clear_bit(EmergencyPending, &fs->fsstate);
+ }
lafs_write_state(fs);
dprintk("State written, all done %d\n", fs->seq);
if (!tc->have_addr) {
dprintk("CLEANER: Nothing found to clean at %d :-(\n",
i);
- if (i == 0 && test_bit(EmergencyPending, &fs->fsstate)
- && !test_bit(EmergencyClean, &fs->fsstate))
+ if (i == 0 && (test_bit(EmergencyPending, &fs->fsstate) ||
+ test_bit(CleanerBlocks, &fs->fsstate)))
lafs_checkpoint_start(fs);
break;
}
if (test_bit(CleanerBlocks, &fs->fsstate)) {
int any_clean;
int clean = lafs_clean_count(fs, &any_clean);
- dprintk("clean=%d max_seg=%d need=%d\n", (int)clean,
- (int)fs->max_segment, (int)fs->cleaner.need);
- if (any_clean &&
- clean * fs->max_segment >=
- fs->allocated_blocks + fs->cleaner.need)
+ dprintk("clean=%d max_seg=%d need=%d act=%d any=%d\n", (int)clean,
+ (int)fs->max_segment, (int)fs->cleaner.need, fs->cleaner.active, any_clean);
+ if (any_clean) {
+ /* If there is enough clean space for everything to move
+ * forward, or the cleaner has done all it can, then
+ * push out a checkpoint so threads waiting on the cleaner
+ * can proceed
+ */
+ if (clean * fs->max_segment >=
+ fs->allocated_blocks + fs->cleaner.need
+ ||
+ !fs->cleaner.active)
lafs_checkpoint_start(fs);
+ }
}
return MAX_SCHEDULE_TIMEOUT;
}
}
if (credits == 0) {
- if (why == NewSpace)
+ if (why == NewSpace && !test_bit(EmergencyClean, &fs->fsstate))
set_bit(EmergencyPending, &fs->fsstate);
- if (!test_bit(CleanerBlocks, &fs->fsstate) ||
- fs->cleaner.need > watermark + fs->max_segment) {
- fs->cleaner.need = watermark + fs->max_segment;
- set_bit(CleanerBlocks, &fs->fsstate);
- lafs_wake_thread(fs);
- }
+ if (why >= ReleaseSpace || !test_bit(EmergencyClean, &fs->fsstate))
+ if (!test_bit(CleanerBlocks, &fs->fsstate) ||
+ fs->cleaner.need > watermark + fs->max_segment) {
+ fs->cleaner.need = watermark + fs->max_segment;
+ set_bit(CleanerBlocks, &fs->fsstate);
+ lafs_wake_thread(fs);
+ }
} else if (why == NewSpace)
if (test_bit(EmergencyClean, &fs->fsstate) ||
test_bit(EmergencyPending, &fs->fsstate)) {