// SPDX-License-Identifier: GPL-2.0
/*
 *
 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
 *
 * TODO: try to use extents tree (instead of array)
 */

#include <linux/blkdev.h>
#include <linux/fs.h>
#include <linux/log2.h>

#include "debug.h"
#include "ntfs.h"
#include "ntfs_fs.h"

/* runs_tree is a continues memory. Try to avoid big size. */
#define NTFS3_RUN_MAX_BYTES 0x10000

struct ntfs_run {
	CLST vcn; /* Virtual cluster number. */
	CLST len; /* Length in clusters. */
	CLST lcn; /* Logical cluster number. */
};

/*
 * run_lookup - Lookup the index of a MCB entry that is first <= vcn.
 *
 * Case of success it will return non-zero value and set
 * @index parameter to index of entry been found.
 * Case of entry missing from list 'index' will be set to
 * point to insertion position for the entry question.
 */
bool run_lookup(const struct runs_tree *run, CLST vcn, size_t *index)
{
	size_t min_idx, max_idx, mid_idx;
	struct ntfs_run *r;

	if (!run->count) {
		*index = 0;
		return false;
	}

	min_idx = 0;
	max_idx = run->count - 1;

	/* Check boundary cases specially, 'cause they cover the often requests. */
	r = run->runs;
	if (vcn < r->vcn) {
		*index = 0;
		return false;
	}

	if (vcn < r->vcn + r->len) {
		*index = 0;
		return true;
	}

	r += max_idx;
	if (vcn >= r->vcn + r->len) {
		*index = run->count;
		return false;
	}

	if (vcn >= r->vcn) {
		*index = max_idx;
		return true;
	}

	do {
		mid_idx = min_idx + ((max_idx - min_idx) >> 1);
		r = run->runs + mid_idx;

		if (vcn < r->vcn) {
			max_idx = mid_idx - 1;
			if (!mid_idx)
				break;
		} else if (vcn >= r->vcn + r->len) {
			min_idx = mid_idx + 1;
		} else {
			*index = mid_idx;
			return true;
		}
	} while (min_idx <= max_idx);

	*index = max_idx + 1;
	return false;
}

/*
 * run_consolidate - Consolidate runs starting from a given one.
 */
static void run_consolidate(struct runs_tree *run, size_t index)
{
	size_t i;
	struct ntfs_run *r = run->runs + index;

	while (index + 1 < run->count) {
		/*
		 * I should merge current run with next
		 * if start of the next run lies inside one being tested.
		 */
		struct ntfs_run *n = r + 1;
		CLST end = r->vcn + r->len;
		CLST dl;

		/* Stop if runs are not aligned one to another. */
		if (n->vcn > end)
			break;

		dl = end - n->vcn;

		/*
		 * If range at index overlaps with next one
		 * then I will either adjust it's start position
		 * or (if completely matches) dust remove one from the list.
		 */
		if (dl > 0) {
			if (n->len <= dl)
				goto remove_next_range;

			n->len -= dl;
			n->vcn += dl;
			if (n->lcn != SPARSE_LCN)
				n->lcn += dl;
			dl = 0;
		}

		/*
		 * Stop if sparse mode does not match
		 * both current and next runs.
		 */
		if ((n->lcn == SPARSE_LCN) != (r->lcn == SPARSE_LCN)) {
			index += 1;
			r = n;
			continue;
		}

		/*
		 * Check if volume block
		 * of a next run lcn does not match
		 * last volume block of the current run.
		 */
		if (n->lcn != SPARSE_LCN && n->lcn != r->lcn + r->len)
			break;

		/*
		 * Next and current are siblings.
		 * Eat/join.
		 */
		r->len += n->len - dl;

remove_next_range:
		i = run->count - (index + 1);
		if (i > 1)
			memmove(n, n + 1, sizeof(*n) * (i - 1));

		run->count -= 1;
	}
}

/*
 * run_is_mapped_full
 *
 * Return: True if range [svcn - evcn] is mapped.
 */
bool run_is_mapped_full(const struct runs_tree *run, CLST svcn, CLST evcn)
{
	size_t i;
	const struct ntfs_run *r, *end;
	CLST next_vcn;

	if (!run_lookup(run, svcn, &i))
		return false;

	end = run->runs + run->count;
	r = run->runs + i;

	for (;;) {
		next_vcn = r->vcn + r->len;
		if (next_vcn > evcn)
			return true;

		if (++r >= end)
			return false;

		if (r->vcn != next_vcn)
			return false;
	}
}

bool run_lookup_entry(const struct runs_tree *run, CLST vcn, CLST *lcn,
		      CLST *len, size_t *index)
{
	size_t idx;
	CLST gap;
	struct ntfs_run *r;

	/* Fail immediately if nrun was not touched yet. */
	if (!run->runs)
		return false;

	if (!run_lookup(run, vcn, &idx))
		return false;

	r = run->runs + idx;

	if (vcn >= r->vcn + r->len)
		return false;

	gap = vcn - r->vcn;
	if (r->len <= gap)
		return false;

	*lcn = r->lcn == SPARSE_LCN ? SPARSE_LCN : (r->lcn + gap);

	if (len)
		*len = r->len - gap;
	if (index)
		*index = idx;

	return true;
}

/*
 * run_truncate_head - Decommit the range before vcn.
 */
void run_truncate_head(struct runs_tree *run, CLST vcn)
{
	size_t index;
	struct ntfs_run *r;

	if (run_lookup(run, vcn, &index)) {
		r = run->runs + index;

		if (vcn > r->vcn) {
			CLST dlen = vcn - r->vcn;

			r->vcn = vcn;
			r->len -= dlen;
			if (r->lcn != SPARSE_LCN)
				r->lcn += dlen;
		}

		if (!index)
			return;
	}
	r = run->runs;
	memmove(r, r + index, sizeof(*r) * (run->count - index));

	run->count -= index;

	if (!run->count) {
		kvfree(run->runs);
		run->runs = NULL;
		run->allocated = 0;
	}
}

/*
 * run_truncate - Decommit the range after vcn.
 */
void run_truncate(struct runs_tree *run, CLST vcn)
{
	size_t index;

	/*
	 * If I hit the range then
	 * I have to truncate one.
	 * If range to be truncated is becoming empty
	 * then it will entirely be removed.
	 */
	if (run_lookup(run, vcn, &index)) {
		struct ntfs_run *r = run->runs + index;

		r->len = vcn - r->vcn;

		if (r->len > 0)
			index += 1;
	}

	/*
	 * At this point 'index' is set to position that
	 * should be thrown away (including index itself)
	 * Simple one - just set the limit.
	 */
	run->count = index;

	/* Do not reallocate array 'runs'. Only free if possible. */
	if (!index) {
		kvfree(run->runs);
		run->runs = NULL;
		run->allocated = 0;
	}
}

/*
 * run_truncate_around - Trim head and tail if necessary.
 */
void run_truncate_around(struct runs_tree *run, CLST vcn)
{
	run_truncate_head(run, vcn);

	if (run->count >= NTFS3_RUN_MAX_BYTES / sizeof(struct ntfs_run) / 2)
		run_truncate(run, (run->runs + (run->count >> 1))->vcn);
}

/*
 * run_add_entry
 *
 * Sets location to known state.
 * Run to be added may overlap with existing location.
 *
 * Return: false if of memory.
 */
bool run_add_entry(struct runs_tree *run, CLST vcn, CLST lcn, CLST len,
		   bool is_mft)
{
	size_t used, index;
	struct ntfs_run *r;
	bool inrange;
	CLST tail_vcn = 0, tail_len = 0, tail_lcn = 0;
	bool should_add_tail = false;

	/*
	 * Lookup the insertion point.
	 *
	 * Execute bsearch for the entry containing
	 * start position question.
	 */
	inrange = run_lookup(run, vcn, &index);

	/*
	 * Shortcut here would be case of
	 * range not been found but one been added
	 * continues previous run.
	 * This case I can directly make use of
	 * existing range as my start point.
	 */
	if (!inrange && index > 0) {
		struct ntfs_run *t = run->runs + index - 1;

		if (t->vcn + t->len == vcn &&
		    (t->lcn == SPARSE_LCN) == (lcn == SPARSE_LCN) &&
		    (lcn == SPARSE_LCN || lcn == t->lcn + t->len)) {
			inrange = true;
			index -= 1;
		}
	}

	/*
	 * At this point 'index' either points to the range
	 * containing start position or to the insertion position
	 * for a new range.
	 * So first let's check if range I'm probing is here already.
	 */
	if (!inrange) {
requires_new_range:
		/*
		 * Range was not found.
		 * Insert at position 'index'
		 */
		used = run->count * sizeof(struct ntfs_run);

		/*
		 * Check allocated space.
		 * If one is not enough to get one more entry
		 * then it will be reallocated.
		 */
		if (run->allocated < used + sizeof(struct ntfs_run)) {
			size_t bytes;
			struct ntfs_run *new_ptr;

			/* Use power of 2 for 'bytes'. */
			if (!used) {
				bytes = 64;
			} else if (used <= 16 * PAGE_SIZE) {
				if (is_power_of_2(run->allocated))
					bytes = run->allocated << 1;
				else
					bytes = (size_t)1
						<< (2 + blksize_bits(used));
			} else {
				bytes = run->allocated + (16 * PAGE_SIZE);
			}

			WARN_ON(!is_mft && bytes > NTFS3_RUN_MAX_BYTES);

			new_ptr = kvmalloc(bytes, GFP_KERNEL);

			if (!new_ptr)
				return false;

			r = new_ptr + index;
			memcpy(new_ptr, run->runs,
			       index * sizeof(struct ntfs_run));
			memcpy(r + 1, run->runs + index,
			       sizeof(struct ntfs_run) * (run->count - index));

			kvfree(run->runs);
			run->runs = new_ptr;
			run->allocated = bytes;

		} else {
			size_t i = run->count - index;

			r = run->runs + index;

			/* memmove appears to be a bottle neck here... */
			if (i > 0)
				memmove(r + 1, r, sizeof(struct ntfs_run) * i);
		}

		r->vcn = vcn;
		r->lcn = lcn;
		r->len = len;
		run->count += 1;
	} else {
		r = run->runs + index;

		/*
		 * If one of ranges was not allocated then we
		 * have to split location we just matched and
		 * insert current one.
		 * A common case this requires tail to be reinserted
		 * a recursive call.
		 */
		if (((lcn == SPARSE_LCN) != (r->lcn == SPARSE_LCN)) ||
		    (lcn != SPARSE_LCN && lcn != r->lcn + (vcn - r->vcn))) {
			CLST to_eat = vcn - r->vcn;
			CLST Tovcn = to_eat + len;

			should_add_tail = Tovcn < r->len;

			if (should_add_tail) {
				tail_lcn = r->lcn == SPARSE_LCN
						   ? SPARSE_LCN
						   : (r->lcn + Tovcn);
				tail_vcn = r->vcn + Tovcn;
				tail_len = r->len - Tovcn;
			}

			if (to_eat > 0) {
				r->len = to_eat;
				inrange = false;
				index += 1;
				goto requires_new_range;
			}

			/* lcn should match one were going to add. */
			r->lcn = lcn;
		}

		/*
		 * If existing range fits then were done.
		 * Otherwise extend found one and fall back to range jocode.
		 */
		if (r->vcn + r->len < vcn + len)
			r->len += len - ((r->vcn + r->len) - vcn);
	}

	/*
	 * And normalize it starting from insertion point.
	 * It's possible that no insertion needed case if
	 * start point lies within the range of an entry
	 * that 'index' points to.
	 */
	if (inrange && index > 0)
		index -= 1;
	run_consolidate(run, index);
	run_consolidate(run, index + 1);

	/*
	 * A special case.
	 * We have to add extra range a tail.
	 */
	if (should_add_tail &&
	    !run_add_entry(run, tail_vcn, tail_lcn, tail_len, is_mft))
		return false;

	return true;
}

/* run_collapse_range
 *
 * Helper for attr_collapse_range(),
 * which is helper for fallocate(collapse_range).
 */
bool run_collapse_range(struct runs_tree *run, CLST vcn, CLST len)
{
	size_t index, eat;
	struct ntfs_run *r, *e, *eat_start, *eat_end;
	CLST end;

	if (WARN_ON(!run_lookup(run, vcn, &index)))
		return true; /* Should never be here. */

	e = run->runs + run->count;
	r = run->runs + index;
	end = vcn + len;

	if (vcn > r->vcn) {
		if (r->vcn + r->len <= end) {
			/* Collapse tail of run .*/
			r->len = vcn - r->vcn;
		} else if (r->lcn == SPARSE_LCN) {
			/* Collapse a middle part of sparsed run. */
			r->len -= len;
		} else {
			/* Collapse a middle part of normal run, split. */
			if (!run_add_entry(run, vcn, SPARSE_LCN, len, false))
				return false;
			return run_collapse_range(run, vcn, len);
		}

		r += 1;
	}

	eat_start = r;
	eat_end = r;

	for (; r < e; r++) {
		CLST d;

		if (r->vcn >= end) {
			r->vcn -= len;
			continue;
		}

		if (r->vcn + r->len <= end) {
			/* Eat this run. */
			eat_end = r + 1;
			continue;
		}

		d = end - r->vcn;
		if (r->lcn != SPARSE_LCN)
			r->lcn += d;
		r->len -= d;
		r->vcn -= len - d;
	}

	eat = eat_end - eat_start;
	memmove(eat_start, eat_end, (e - eat_end) * sizeof(*r));
	run->count -= eat;

	return true;
}

/*
 * run_get_entry - Return index-th mapped region.
 */
bool run_get_entry(const struct runs_tree *run, size_t index, CLST *vcn,
		   CLST *lcn, CLST *len)
{
	const struct ntfs_run *r;

	if (index >= run->count)
		return false;

	r = run->runs + index;

	if (!r->len)
		return false;

	if (vcn)
		*vcn = r->vcn;
	if (lcn)
		*lcn = r->lcn;
	if (len)
		*len = r->len;
	return true;
}

/*
 * run_packed_size - Calculate the size of packed int64.
 */
#ifdef __BIG_ENDIAN
static inline int run_packed_size(const s64 n)
{
	const u8 *p = (const u8 *)&n + sizeof(n) - 1;

	if (n >= 0) {
		if (p[-7] || p[-6] || p[-5] || p[-4])
			p -= 4;
		if (p[-3] || p[-2])
			p -= 2;
		if (p[-1])
			p -= 1;
		if (p[0] & 0x80)
			p -= 1;
	} else {
		if (p[-7] != 0xff || p[-6] != 0xff || p[-5] != 0xff ||
		    p[-4] != 0xff)
			p -= 4;
		if (p[-3] != 0xff || p[-2] != 0xff)
			p -= 2;
		if (p[-1] != 0xff)
			p -= 1;
		if (!(p[0] & 0x80))
			p -= 1;
	}
	return (const u8 *)&n + sizeof(n) - p;
}

/* Full trusted function. It does not check 'size' for errors. */
static inline void run_pack_s64(u8 *run_buf, u8 size, s64 v)
{
	const u8 *p = (u8 *)&v;

	switch (size) {
	case 8:
		run_buf[7] = p[0];
		fallthrough;
	case 7:
		run_buf[6] = p[1];
		fallthrough;
	case 6:
		run_buf[5] = p[2];
		fallthrough;
	case 5:
		run_buf[4] = p[3];
		fallthrough;
	case 4:
		run_buf[3] = p[4];
		fallthrough;
	case 3:
		run_buf[2] = p[5];
		fallthrough;
	case 2:
		run_buf[1] = p[6];
		fallthrough;
	case 1:
		run_buf[0] = p[7];
	}
}

/* Full trusted function. It does not check 'size' for errors. */
static inline s64 run_unpack_s64(const u8 *run_buf, u8 size, s64 v)
{
	u8 *p = (u8 *)&v;

	switch (size) {
	case 8:
		p[0] = run_buf[7];
		fallthrough;
	case 7:
		p[1] = run_buf[6];
		fallthrough;
	case 6:
		p[2] = run_buf[5];
		fallthrough;
	case 5:
		p[3] = run_buf[4];
		fallthrough;
	case 4:
		p[4] = run_buf[3];
		fallthrough;
	case 3:
		p[5] = run_buf[2];
		fallthrough;
	case 2:
		p[6] = run_buf[1];
		fallthrough;
	case 1:
		p[7] = run_buf[0];
	}
	return v;
}

#else

static inline int run_packed_size(const s64 n)
{
	const u8 *p = (const u8 *)&n;

	if (n >= 0) {
		if (p[7] || p[6] || p[5] || p[4])
			p += 4;
		if (p[3] || p[2])
			p += 2;
		if (p[1])
			p += 1;
		if (p[0] & 0x80)
			p += 1;
	} else {
		if (p[7] != 0xff || p[6] != 0xff || p[5] != 0xff ||
		    p[4] != 0xff)
			p += 4;
		if (p[3] != 0xff || p[2] != 0xff)
			p += 2;
		if (p[1] != 0xff)
			p += 1;
		if (!(p[0] & 0x80))
			p += 1;
	}

	return 1 + p - (const u8 *)&n;
}

/* Full trusted function. It does not check 'size' for errors. */
static inline void run_pack_s64(u8 *run_buf, u8 size, s64 v)
{
	const u8 *p = (u8 *)&v;

	/* memcpy( run_buf, &v, size); Is it faster? */
	switch (size) {
	case 8:
		run_buf[7] = p[7];
		fallthrough;
	case 7:
		run_buf[6] = p[6];
		fallthrough;
	case 6:
		run_buf[5] = p[5];
		fallthrough;
	case 5:
		run_buf[4] = p[4];
		fallthrough;
	case 4:
		run_buf[3] = p[3];
		fallthrough;
	case 3:
		run_buf[2] = p[2];
		fallthrough;
	case 2:
		run_buf[1] = p[1];
		fallthrough;
	case 1:
		run_buf[0] = p[0];
	}
}

/* full trusted function. It does not check 'size' for errors */
static inline s64 run_unpack_s64(const u8 *run_buf, u8 size, s64 v)
{
	u8 *p = (u8 *)&v;

	/* memcpy( &v, run_buf, size); Is it faster? */
	switch (size) {
	case 8:
		p[7] = run_buf[7];
		fallthrough;
	case 7:
		p[6] = run_buf[6];
		fallthrough;
	case 6:
		p[5] = run_buf[5];
		fallthrough;
	case 5:
		p[4] = run_buf[4];
		fallthrough;
	case 4:
		p[3] = run_buf[3];
		fallthrough;
	case 3:
		p[2] = run_buf[2];
		fallthrough;
	case 2:
		p[1] = run_buf[1];
		fallthrough;
	case 1:
		p[0] = run_buf[0];
	}
	return v;
}
#endif

/*
 * run_pack - Pack runs into buffer.
 *
 * packed_vcns - How much runs we have packed.
 * packed_size - How much bytes we have used run_buf.
 */
int run_pack(const struct runs_tree *run, CLST svcn, CLST len, u8 *run_buf,
	     u32 run_buf_size, CLST *packed_vcns)
{
	CLST next_vcn, vcn, lcn;
	CLST prev_lcn = 0;
	CLST evcn1 = svcn + len;
	int packed_size = 0;
	size_t i;
	bool ok;
	s64 dlcn;
	int offset_size, size_size, tmp;

	next_vcn = vcn = svcn;

	*packed_vcns = 0;

	if (!len)
		goto out;

	ok = run_lookup_entry(run, vcn, &lcn, &len, &i);

	if (!ok)
		goto error;

	if (next_vcn != vcn)
		goto error;

	for (;;) {
		next_vcn = vcn + len;
		if (next_vcn > evcn1)
			len = evcn1 - vcn;

		/* How much bytes required to pack len. */
		size_size = run_packed_size(len);

		/* offset_size - How much bytes is packed dlcn. */
		if (lcn == SPARSE_LCN) {
			offset_size = 0;
			dlcn = 0;
		} else {
			/* NOTE: lcn can be less than prev_lcn! */
			dlcn = (s64)lcn - prev_lcn;
			offset_size = run_packed_size(dlcn);
			prev_lcn = lcn;
		}

		tmp = run_buf_size - packed_size - 2 - offset_size;
		if (tmp <= 0)
			goto out;

		/* Can we store this entire run. */
		if (tmp < size_size)
			goto out;

		if (run_buf) {
			/* Pack run header. */
			run_buf[0] = ((u8)(size_size | (offset_size << 4)));
			run_buf += 1;

			/* Pack the length of run. */
			run_pack_s64(run_buf, size_size, len);

			run_buf += size_size;
			/* Pack the offset from previous LCN. */
			run_pack_s64(run_buf, offset_size, dlcn);
			run_buf += offset_size;
		}

		packed_size += 1 + offset_size + size_size;
		*packed_vcns += len;

		if (packed_size + 1 >= run_buf_size || next_vcn >= evcn1)
			goto out;

		ok = run_get_entry(run, ++i, &vcn, &lcn, &len);
		if (!ok)
			goto error;

		if (next_vcn != vcn)
			goto error;
	}

out:
	/* Store last zero. */
	if (run_buf)
		run_buf[0] = 0;

	return packed_size + 1;

error:
	return -EOPNOTSUPP;
}

/*
 * run_unpack - Unpack packed runs from @run_buf.
 *
 * Return: Error if negative, or real used bytes.
 */
int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
	       CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf,
	       u32 run_buf_size)
{
	u64 prev_lcn, vcn64, lcn, next_vcn;
	const u8 *run_last, *run_0;
	bool is_mft = ino == MFT_REC_MFT;

	/* Check for empty. */
	if (evcn + 1 == svcn)
		return 0;

	if (evcn < svcn)
		return -EINVAL;

	run_0 = run_buf;
	run_last = run_buf + run_buf_size;
	prev_lcn = 0;
	vcn64 = svcn;

	/* Read all runs the chain. */
	/* size_size - How much bytes is packed len. */
	while (run_buf < run_last) {
		/* size_size - How much bytes is packed len. */
		u8 size_size = *run_buf & 0xF;
		/* offset_size - How much bytes is packed dlcn. */
		u8 offset_size = *run_buf++ >> 4;
		u64 len;

		if (!size_size)
			break;

		/*
		 * Unpack runs.
		 * NOTE: Runs are stored little endian order
		 * "len" is unsigned value, "dlcn" is signed.
		 * Large positive number requires to store 5 bytes
		 * e.g.: 05 FF 7E FF FF 00 00 00
		 */
		if (size_size > 8)
			return -EINVAL;

		len = run_unpack_s64(run_buf, size_size, 0);
		/* Skip size_size. */
		run_buf += size_size;

		if (!len)
			return -EINVAL;

		if (!offset_size)
			lcn = SPARSE_LCN64;
		else if (offset_size <= 8) {
			s64 dlcn;

			/* Initial value of dlcn is -1 or 0. */
			dlcn = (run_buf[offset_size - 1] & 0x80) ? (s64)-1 : 0;
			dlcn = run_unpack_s64(run_buf, offset_size, dlcn);
			/* Skip offset_size. */
			run_buf += offset_size;

			if (!dlcn)
				return -EINVAL;
			lcn = prev_lcn + dlcn;
			prev_lcn = lcn;
		} else
			return -EINVAL;

		next_vcn = vcn64 + len;
		/* Check boundary. */
		if (next_vcn > evcn + 1)
			return -EINVAL;

#ifndef CONFIG_NTFS3_64BIT_CLUSTER
		if (next_vcn > 0x100000000ull || (lcn + len) > 0x100000000ull) {
			ntfs_err(
				sbi->sb,
				"This driver is compiled without CONFIG_NTFS3_64BIT_CLUSTER (like windows driver).\n"
				"Volume contains 64 bits run: vcn %llx, lcn %llx, len %llx.\n"
				"Activate CONFIG_NTFS3_64BIT_CLUSTER to process this case",
				vcn64, lcn, len);
			return -EOPNOTSUPP;
		}
#endif
		if (lcn != SPARSE_LCN64 && lcn + len > sbi->used.bitmap.nbits) {
			/* LCN range is out of volume. */
			return -EINVAL;
		}

		if (!run)
			; /* Called from check_attr(fslog.c) to check run. */
		else if (run == RUN_DEALLOCATE) {
			/*
			 * Called from ni_delete_all to free clusters
			 * without storing in run.
			 */
			if (lcn != SPARSE_LCN64)
				mark_as_free_ex(sbi, lcn, len, true);
		} else if (vcn64 >= vcn) {
			if (!run_add_entry(run, vcn64, lcn, len, is_mft))
				return -ENOMEM;
		} else if (next_vcn > vcn) {
			u64 dlen = vcn - vcn64;

			if (!run_add_entry(run, vcn, lcn + dlen, len - dlen,
					   is_mft))
				return -ENOMEM;
		}

		vcn64 = next_vcn;
	}

	if (vcn64 != evcn + 1) {
		/* Not expected length of unpacked runs. */
		return -EINVAL;
	}

	return run_buf - run_0;
}

#ifdef NTFS3_CHECK_FREE_CLST
/*
 * run_unpack_ex - Unpack packed runs from "run_buf".
 *
 * Checks unpacked runs to be used in bitmap.
 *
 * Return: Error if negative, or real used bytes.
 */
int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
		  CLST svcn, CLST evcn, CLST vcn, const u8 *run_buf,
		  u32 run_buf_size)
{
	int ret, err;
	CLST next_vcn, lcn, len;
	size_t index;
	bool ok;
	struct wnd_bitmap *wnd;

	ret = run_unpack(run, sbi, ino, svcn, evcn, vcn, run_buf, run_buf_size);
	if (ret <= 0)
		return ret;

	if (!sbi->used.bitmap.sb || !run || run == RUN_DEALLOCATE)
		return ret;

	if (ino == MFT_REC_BADCLUST)
		return ret;

	next_vcn = vcn = svcn;
	wnd = &sbi->used.bitmap;

	for (ok = run_lookup_entry(run, vcn, &lcn, &len, &index);
	     next_vcn <= evcn;
	     ok = run_get_entry(run, ++index, &vcn, &lcn, &len)) {
		if (!ok || next_vcn != vcn)
			return -EINVAL;

		next_vcn = vcn + len;

		if (lcn == SPARSE_LCN)
			continue;

		if (sbi->flags & NTFS_FLAGS_NEED_REPLAY)
			continue;

		down_read_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS);
		/* Check for free blocks. */
		ok = wnd_is_used(wnd, lcn, len);
		up_read(&wnd->rw_lock);
		if (ok)
			continue;

		/* Looks like volume is corrupted. */
		ntfs_set_state(sbi, NTFS_DIRTY_ERROR);

		if (down_write_trylock(&wnd->rw_lock)) {
			/* Mark all zero bits as used in range [lcn, lcn+len). */
			CLST i, lcn_f = 0, len_f = 0;

			err = 0;
			for (i = 0; i < len; i++) {
				if (wnd_is_free(wnd, lcn + i, 1)) {
					if (!len_f)
						lcn_f = lcn + i;
					len_f += 1;
				} else if (len_f) {
					err = wnd_set_used(wnd, lcn_f, len_f);
					len_f = 0;
					if (err)
						break;
				}
			}

			if (len_f)
				err = wnd_set_used(wnd, lcn_f, len_f);

			up_write(&wnd->rw_lock);
			if (err)
				return err;
		}
	}

	return ret;
}
#endif

/*
 * run_get_highest_vcn
 *
 * Return the highest vcn from a mapping pairs array
 * it used while replaying log file.
 */
int run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn)
{
	u64 vcn64 = vcn;
	u8 size_size;

	while ((size_size = *run_buf & 0xF)) {
		u8 offset_size = *run_buf++ >> 4;
		u64 len;

		if (size_size > 8 || offset_size > 8)
			return -EINVAL;

		len = run_unpack_s64(run_buf, size_size, 0);
		if (!len)
			return -EINVAL;

		run_buf += size_size + offset_size;
		vcn64 += len;

#ifndef CONFIG_NTFS3_64BIT_CLUSTER
		if (vcn64 > 0x100000000ull)
			return -EINVAL;
#endif
	}

	*highest_vcn = vcn64 - 1;
	return 0;
}
