// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
 */
#ifndef __LIBFROG_FSGEOM_H__
#define __LIBFROG_FSGEOM_H__

void xfs_report_geom(struct xfs_fsop_geom *geo, const char *mntpoint,
		const char *logname, const char *rtname);
int xfrog_geometry(int fd, struct xfs_fsop_geom *fsgeo);
int xfrog_ag_geometry(int fd, unsigned int agno, struct xfs_ag_geometry *ageo);

/*
 * Structure for recording whatever observations we want about the level of
 * xfs runtime support for this fd.  Right now we only store the fd and fs
 * geometry.
 */
struct xfs_fd {
	/* ioctl file descriptor */
	int			fd;

	/* filesystem geometry */
	struct xfs_fsop_geom	fsgeom;

	/* log2 of sb_agblocks (rounded up) */
	unsigned int		agblklog;

	/* log2 of sb_blocksize */
	unsigned int		blocklog;

	/* log2 of sb_inodesize */
	unsigned int		inodelog;

	/* log2 of sb_inopblock */
	unsigned int		inopblog;

	/* bits for agino in inum */
	unsigned int		aginolog;

	/* log2 of sb_blocksize / sb_sectsize */
	unsigned int		blkbb_log;

	/* XFROG_FLAG_* state flags */
	unsigned int		flags;
};

/* Only use v1 bulkstat/inumbers ioctls. */
#define XFROG_FLAG_BULKSTAT_FORCE_V1	(1 << 0)

/* Only use v5 bulkstat/inumbers ioctls. */
#define XFROG_FLAG_BULKSTAT_FORCE_V5	(1 << 1)

/* Only use the older one-at-a-time scrub ioctl. */
#define XFROG_FLAG_SCRUB_FORCE_SINGLE	(1 << 2)

/* Only use the vectored scrub ioctl. */
#define XFROG_FLAG_SCRUB_FORCE_VECTOR	(1 << 3)

/* Static initializers */
#define XFS_FD_INIT(_fd)	{ .fd = (_fd), }
#define XFS_FD_INIT_EMPTY	XFS_FD_INIT(-1)

int xfd_prepare_geometry(struct xfs_fd *xfd);
void xfd_install_geometry(struct xfs_fd *xfd, struct xfs_fsop_geom *fsgeom);
int xfd_open(struct xfs_fd *xfd, const char *pathname, int flags);
int xfd_close(struct xfs_fd *xfd);

/* Convert AG number and AG inode number into fs inode number. */
static inline uint64_t
cvt_agino_to_ino(
	const struct xfs_fd	*xfd,
	uint32_t		agno,
	uint32_t		agino)
{
	return ((uint64_t)agno << xfd->aginolog) + agino;
}

/* Convert fs inode number into AG number. */
static inline uint32_t
cvt_ino_to_agno(
	const struct xfs_fd	*xfd,
	uint64_t		ino)
{
	return ino >> xfd->aginolog;
}

/* Convert fs inode number into AG inode number. */
static inline uint32_t
cvt_ino_to_agino(
	const struct xfs_fd	*xfd,
	uint64_t		ino)
{
	return ino & ((1ULL << xfd->aginolog) - 1);
}

/*
 * Convert a linear fs block offset number into bytes.  This is the runtime
 * equivalent of XFS_FSB_TO_B, which means that it is /not/ for segmented fsbno
 * format (= agno | agbno) that we use internally for the data device.
 */
static inline uint64_t
cvt_off_fsb_to_b(
	const struct xfs_fd	*xfd,
	uint64_t		fsb)
{
	return fsb << xfd->blocklog;
}

/*
 * Convert bytes into a (rounded down) linear fs block offset number.  This is
 * the runtime equivalent of XFS_B_TO_FSBT.  It does not produce segmented
 * fsbno numbers (= agno | agbno).
 */
static inline uint64_t
cvt_b_to_off_fsbt(
	const struct xfs_fd	*xfd,
	uint64_t		bytes)
{
	return bytes >> xfd->blocklog;
}

/* Convert sector number to bytes. */
static inline uint64_t
cvt_bbtob(
	uint64_t		daddr)
{
	return daddr << BBSHIFT;
}

/* Convert bytes to sector number, rounding down. */
static inline uint64_t
cvt_btobbt(
	uint64_t		bytes)
{
	return bytes >> BBSHIFT;
}

/* Convert fs block number to sector number. */
static inline uint64_t
cvt_off_fsb_to_bb(
	struct xfs_fd		*xfd,
	uint64_t		fsbno)
{
	return fsbno << xfd->blkbb_log;
}

/* Convert sector number to fs block number, rounded down. */
static inline uint64_t
cvt_bb_to_off_fsbt(
	struct xfs_fd		*xfd,
	uint64_t		daddr)
{
	return daddr >> xfd->blkbb_log;
}

/* Convert AG number and AG block to fs block number */
static inline uint64_t
cvt_agb_to_daddr(
	struct xfs_fd		*xfd,
	uint32_t		agno,
	uint32_t		agbno)
{
	return cvt_off_fsb_to_bb(xfd,
			(uint64_t)agno * xfd->fsgeom.agblocks + agbno);
}

/* Convert sector number to AG number. */
static inline uint32_t
cvt_daddr_to_agno(
	struct xfs_fd		*xfd,
	uint64_t		daddr)
{
	return cvt_bb_to_off_fsbt(xfd, daddr) / xfd->fsgeom.agblocks;
}

/* Convert sector number to AG block number. */
static inline uint32_t
cvt_daddr_to_agbno(
	struct xfs_fd		*xfd,
	uint64_t		daddr)
{
	return cvt_bb_to_off_fsbt(xfd, daddr) % xfd->fsgeom.agblocks;
}

/* Convert AG number and AG block to a byte location on disk. */
static inline uint64_t
cvt_agbno_to_b(
	struct xfs_fd		*xfd,
	xfs_agnumber_t		agno,
	xfs_agblock_t		agbno)
{
	return cvt_bbtob(cvt_agb_to_daddr(xfd, agno, agbno));
}

/* Convert byte location on disk to AG block. */
static inline xfs_agblock_t
cvt_b_to_agbno(
	struct xfs_fd		*xfd,
	uint64_t		byteno)
{
	return cvt_daddr_to_agbno(xfd, cvt_btobbt(byteno));
}

#endif /* __LIBFROG_FSGEOM_H__ */
