*
* For now, clean up to 4 segments at a time.
*/
- int i;
+ int i, max_segs;
u64 T = 0;
for (i = 0; i < fs->devices; i++)
/* adjust to unusable space FIXME adjust F too? */
T -= 4 * fs->max_segment;
- for (i = 0; i < 4; i++) {
+ max_segs = lafs_alloc_cleaner_segs(fs, 4);
+ if (max_segs < 1)
+ /* if we can only clean to main segment, do it
+ * but only do one segment at a time
+ */
+ max_segs = 1;
+ for (i = 0; i < max_segs; i++) {
struct toclean *tc = &fs->cleaner.seg[i];
- u64 C = fs->free_blocks + fs->cleaner.cleaning;
+ u64 C = fs->free_blocks + fs->clean_reserved
+ + fs->cleaner.cleaning;
u64 F = max(fs->total_free, fs->total_free_prev);
if (4 * fs->max_segment < C)
int lafs_get_cleanable(struct fs *fs, u16 *dev, u32 *seg);
void lafs_space_return(struct fs *fs, int credits);
+int lafs_alloc_cleaner_segs(struct fs *fs, int max);
int lafs_space_alloc(struct fs *fs, int credits, int why);
unsigned long lafs_scan_seg(struct fs *fs);
int lafs_clean_count(struct fs *fs);
check_credits(fs);
}
+int lafs_alloc_cleaner_segs(struct fs *fs, int max)
+{
+ /* cleaner is about to start.
+ * See how many segments of space can safely
+ * be reserved for its use.
+ */
+ int watermark = fs->max_segment * 4;
+ int rv = 0;
+ spin_lock(&fs->alloc_lock);
+ fs->free_blocks += fs->clean_reserved;
+ fs->clean_reserved = 0;
+ while (fs->clean_reserved < max * fs->max_segment &&
+ fs->free_blocks > fs->allocated_blocks + watermark) {
+ fs->clean_reserved += fs->max_segment;
+ fs->free_blocks -= fs->max_segment;
+ rv++;
+ }
+ spin_unlock(&fs->alloc_lock);
+ return rv;
+}
+
int lafs_space_alloc(struct fs *fs, int credits, int why)
{
/* 'why's for space reservation.