// check_clus_chain [c]
static int check_clus_chain(struct exfat *exfat, struct exfat_inode *node)
{
	struct exfat_dentry *stream_de;
	clus_t clus, prev, next;
	clus_t count, max_count;

	clus = node->first_clus;
	prev = EXFAT_EOF_CLUSTER;
	count = 0;
	max_count = DIV_ROUND_UP(node->size, exfat->clus_size);

	if (node->size == 0 && node->first_clus == EXFAT_FREE_CLUSTER)
		return 0;

	/* the first cluster is wrong */
	if ((node->size == 0 && node->first_clus != EXFAT_FREE_CLUSTER) ||
		(node->size > 0 && !heap_clus(exfat, node->first_clus))) {
		if (repair_file_ask(&exfat->de_iter, node,
			ER_FILE_FIRST_CLUS, "first cluster is wrong"))
			goto truncate_file;
		else
			return -EINVAL;
	}

	while (clus != EXFAT_EOF_CLUSTER) {
		if (count >= max_count) {
			if (node->is_contiguous)
				break;
			if (repair_file_ask(&exfat->de_iter, node,
					ER_FILE_SMALLER_SIZE,
					"more clusters are allocated. "
					"truncate to %u bytes",
					count * exfat->clus_size))
				goto truncate_file;
			else
				return -EINVAL;
		}

		/*
		 * This cluster is already allocated. it may be shared with
		 * the other file, or there is a loop in cluster chain.
		 */
		if (EXFAT_BITMAP_GET(exfat->alloc_bitmap,
				clus - EXFAT_FIRST_CLUSTER)) {
			if (repair_file_ask(&exfat->de_iter, node,
					ER_FILE_DUPLICATED_CLUS,
					"cluster is already allocated for "
					"the other file. truncated to %u bytes",
					count * exfat->clus_size))
				goto truncate_file;
			else
				return -EINVAL;
		}

		/* This cluster is allocated or not */
		if (get_next_clus(exfat, node, clus, &next))
			goto truncate_file;
		if (!node->is_contiguous) {
			if (!heap_clus(exfat, next) &&
					next != EXFAT_EOF_CLUSTER) {
				if (repair_file_ask(&exfat->de_iter, node,
						ER_FILE_INVALID_CLUS,
						"broken cluster chain. "
						"truncate to %u bytes",
						count *
						exfat->clus_size))
					goto truncate_file;

				else
					return -EINVAL;
			}
		} else {
			if (!EXFAT_BITMAP_GET(exfat->disk_bitmap,
					clus - EXFAT_FIRST_CLUSTER)) {
				if (repair_file_ask(&exfat->de_iter, node,
						ER_FILE_INVALID_CLUS,
						"cluster is marked as free. "
						"truncate to %u bytes",
						count *
						exfat->clus_size))
					goto truncate_file;

				else
					return -EINVAL;
			}
		}

		count++;
		EXFAT_BITMAP_SET(exfat->alloc_bitmap,
				clus - EXFAT_FIRST_CLUSTER);
		prev = clus;
		clus = next;
	}

	if (count < max_count) {
		if (repair_file_ask(&exfat->de_iter, node,
			ER_FILE_LARGER_SIZE, "less clusters are allocated. "
			"truncates to %u bytes",
			count * exfat->clus_size))
			goto truncate_file;
		else
			return -EINVAL;
	}

	return 0;
truncate_file:
	node->size = count * exfat->clus_size;
	if (!heap_clus(exfat, prev))
		node->first_clus = EXFAT_FREE_CLUSTER;

	exfat_de_iter_get_dirty(&exfat->de_iter, 1, &stream_de);
	if (count * exfat->clus_size <
			le64_to_cpu(stream_de->stream_valid_size))
		stream_de->stream_valid_size = cpu_to_le64(
				count * exfat->clus_size);
	if (!heap_clus(exfat, prev))
		stream_de->stream_start_clu = EXFAT_FREE_CLUSTER;
	stream_de->stream_size = cpu_to_le64(
			count * exfat->clus_size);

	/* remaining clusters will be freed while FAT is compared with
	 * alloc_bitmap.
	 */
	if (!node->is_contiguous && heap_clus(exfat, prev))
		return set_fat(exfat, prev, EXFAT_EOF_CLUSTER);
	return 0;
}