static long add_reservation_in_range(struct resv_map *resv, long f, long t,
				     struct hugetlb_cgroup *h_cg,
				     struct hstate *h, long *regions_needed,
				     bool count_only)
{
	long add = 0;
	struct list_head *head = &resv->regions;
	long last_accounted_offset = f;
	struct file_region *rg = NULL, *trg = NULL, *nrg = NULL;

	if (regions_needed)
		*regions_needed = 0;

	/* In this loop, we essentially handle an entry for the range
	 * [last_accounted_offset, rg->from), at every iteration, with some
	 * bounds checking.
	 */
	list_for_each_entry_safe(rg, trg, head, link) {
		/* Skip irrelevant regions that start before our range. */
		if (rg->from < f) {
			/* If this region ends after the last accounted offset,
			 * then we need to update last_accounted_offset.
			 */
			if (rg->to > last_accounted_offset)
				last_accounted_offset = rg->to;
			continue;
		}

		/* When we find a region that starts beyond our range, we've
		 * finished.
		 */
		if (rg->from > t)
			break;

		/* Add an entry for last_accounted_offset -> rg->from, and
		 * update last_accounted_offset.
		 */
		if (rg->from > last_accounted_offset) {
			add += rg->from - last_accounted_offset;
			if (!count_only) {
				nrg = get_file_region_entry_from_cache(
					resv, last_accounted_offset, rg->from);
				record_hugetlb_cgroup_uncharge_info(h_cg, h,
								    resv, nrg);
				list_add(&nrg->link, rg->link.prev);
				coalesce_file_region(resv, nrg);
			} else if (regions_needed)
				*regions_needed += 1;
		}

		last_accounted_offset = rg->to;
	}

	/* Handle the case where our range extends beyond
	 * last_accounted_offset.
	 */
	if (last_accounted_offset < t) {
		add += t - last_accounted_offset;
		if (!count_only) {
			nrg = get_file_region_entry_from_cache(
				resv, last_accounted_offset, t);
			record_hugetlb_cgroup_uncharge_info(h_cg, h, resv, nrg);
			list_add(&nrg->link, rg->link.prev);
			coalesce_file_region(resv, nrg);
		} else if (regions_needed)
			*regions_needed += 1;
	}

	VM_BUG_ON(add < 0);
	return add;
}
static long add_reservation_in_range(struct resv_map *resv, long f, long t,
				     struct hugetlb_cgroup *h_cg,
				     struct hstate *h, long *regions_needed,
				     bool count_only)
{
	long add = 0;
	struct list_head *head = &resv->regions;
	long last_accounted_offset = f;
	struct file_region *rg = NULL, *trg = NULL, *nrg = NULL;

	if (regions_needed)
		*regions_needed = 0;

	 
	list_for_each_entry_safe(rg, trg, head, link) {
		 
		if (rg->from < f) {
			 
			if (rg->to > last_accounted_offset)
				last_accounted_offset = rg->to;
			continue;
		}

		 
		if (rg->from > t)
			break;

		 
		if (rg->from > last_accounted_offset) {
			add += rg->from - last_accounted_offset;
			if (!count_only) {
				nrg = get_file_region_entry_from_cache(
					resv, last_accounted_offset, rg->from);
				record_hugetlb_cgroup_uncharge_info(h_cg, h,
								    resv, nrg);
				list_add(&nrg->link, rg->link.prev);
				coalesce_file_region(resv, nrg);
			} else if (regions_needed)
				*regions_needed += 1;
		}

		last_accounted_offset = rg->to;
	}

	 
	if (last_accounted_offset < t) {
		add += t - last_accounted_offset;
		if (!count_only) {
			nrg = get_file_region_entry_from_cache(
				resv, last_accounted_offset, t);
			record_hugetlb_cgroup_uncharge_info(h_cg, h, resv, nrg);
			list_add(&nrg->link, rg->link.prev);
			coalesce_file_region(resv, nrg);
		} else if (regions_needed)
			*regions_needed += 1;
	}

	VM_BUG_ON(add < 0);
	return add;
}