// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2018-2024 Oracle.  All Rights Reserved.
 * Author: Darrick J. Wong <djwong@kernel.org>
 */
#include "xfs.h"
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/statvfs.h>
#include "libfrog/paths.h"
#include "xfs_scrub.h"
#include "common.h"
#include "filemap.h"

/*
 * These routines provide a simple interface to query the block
 * mappings of the fork of a given inode via GETBMAPX and call a
 * function to iterate each mapping result.
 */

#define BMAP_NR		2048

/*
 * Iterate all the extent block mappings between the key and fork end.
 * Returns 0 or a positive error number.
 */
int
scrub_iterate_filemaps(
	struct scrub_ctx	*ctx,
	int			fd,
	int			whichfork,
	struct file_bmap	*key,
	scrub_bmap_iter_fn	fn,
	void			*arg)
{
	struct fsxattr		fsx;
	struct getbmapx		*map;
	struct getbmapx		*p;
	struct file_bmap	bmap;
	xfs_off_t		new_off;
	int			getxattr_type;
	int			i;
	int			ret;

	map = calloc(BMAP_NR, sizeof(struct getbmapx));
	if (!map)
		return errno;

	map->bmv_offset = BTOBB(key->bm_offset);
	map->bmv_block = BTOBB(key->bm_physical);
	if (key->bm_length == 0)
		map->bmv_length = ULLONG_MAX;
	else
		map->bmv_length = BTOBB(key->bm_length);
	map->bmv_iflags = BMV_IF_PREALLOC | BMV_IF_NO_HOLES;
	switch (whichfork) {
	case XFS_ATTR_FORK:
		getxattr_type = XFS_IOC_FSGETXATTRA;
		map->bmv_iflags |= BMV_IF_ATTRFORK;
		break;
	case XFS_COW_FORK:
		map->bmv_iflags |= BMV_IF_COWFORK;
		getxattr_type = FS_IOC_FSGETXATTR;
		break;
	case XFS_DATA_FORK:
		getxattr_type = FS_IOC_FSGETXATTR;
		break;
	default:
		abort();
	}

	ret = ioctl(fd, getxattr_type, &fsx);
	if (ret < 0) {
		ret = errno;
		goto out;
	}

	if (fsx.fsx_nextents == 0)
		goto out;

	map->bmv_count = min(fsx.fsx_nextents + 1, BMAP_NR);

	while ((ret = ioctl(fd, XFS_IOC_GETBMAPX, map)) == 0) {
		for (i = 0, p = &map[i + 1]; i < map->bmv_entries; i++, p++) {
			bmap.bm_offset = BBTOB(p->bmv_offset);
			bmap.bm_physical = BBTOB(p->bmv_block);
			bmap.bm_length = BBTOB(p->bmv_length);
			bmap.bm_flags = p->bmv_oflags;
			ret = fn(ctx, fd, whichfork, &fsx, &bmap, arg);
			if (ret)
				goto out;
			if (scrub_excessive_errors(ctx))
				goto out;
		}

		if (map->bmv_entries == 0)
			break;
		p = map + map->bmv_entries;
		if (p->bmv_oflags & BMV_OF_LAST)
			break;

		new_off = p->bmv_offset + p->bmv_length;
		map->bmv_length -= new_off - map->bmv_offset;
		map->bmv_offset = new_off;
	}
	if (ret < 0)
		ret = errno;

	/*
	 * Pre-reflink filesystems don't know about CoW forks, so don't
	 * be too surprised if it fails.
	 */
	if (whichfork == XFS_COW_FORK && ret == EINVAL)
		ret = 0;
out:
	free(map);
	return ret;
}
