diff --git a/kmod/src/alloc.c b/kmod/src/alloc.c index 76bff395..0284150e 100644 --- a/kmod/src/alloc.c +++ b/kmod/src/alloc.c @@ -1351,6 +1351,27 @@ void scoutfs_alloc_meta_remaining(struct scoutfs_alloc *alloc, u32 *avail_total, } while (read_seqretry(&alloc->seqlock, seq)); } +/* + * Returns true if the caller's consumption of nr from either avail or + * freed would end up exceeding their budget relative to the starting + * remaining snapshot they took. + */ +bool scoutfs_alloc_meta_low_since(struct scoutfs_alloc *alloc, u32 avail_start, u32 freed_start, + u32 budget, u32 nr) +{ + u32 avail_use; + u32 freed_use; + u32 avail; + u32 freed; + + scoutfs_alloc_meta_remaining(alloc, &avail, &freed); + + avail_use = avail_start - avail; + freed_use = freed_start - freed; + + return ((avail_use + nr) > budget) || ((freed_use + nr) > budget); +} + bool scoutfs_alloc_test_flag(struct super_block *sb, struct scoutfs_alloc *alloc, u32 flag) { diff --git a/kmod/src/alloc.h b/kmod/src/alloc.h index b3a7e3c6..5e0d4ff3 100644 --- a/kmod/src/alloc.h +++ b/kmod/src/alloc.h @@ -159,6 +159,8 @@ int scoutfs_alloc_splice_list(struct super_block *sb, bool scoutfs_alloc_meta_low(struct super_block *sb, struct scoutfs_alloc *alloc, u32 nr); void scoutfs_alloc_meta_remaining(struct scoutfs_alloc *alloc, u32 *avail_total, u32 *freed_space); +bool scoutfs_alloc_meta_low_since(struct scoutfs_alloc *alloc, u32 avail_start, u32 freed_start, + u32 budget, u32 nr); bool scoutfs_alloc_test_flag(struct super_block *sb, struct scoutfs_alloc *alloc, u32 flag);