*/
#include "libxfs.h"
#include "fsgeom.h"
+#include "util.h"
void
xfs_report_geom(
geo->rtextsize * geo->blocksize, (unsigned long long)geo->rtblocks,
(unsigned long long)geo->rtextents);
}
+
+/* Try to obtain the xfs geometry. On error returns a negative error code. */
+int
+xfrog_geometry(
+ int fd,
+ struct xfs_fsop_geom *fsgeo)
+{
+ int ret;
+
+ memset(fsgeo, 0, sizeof(*fsgeo));
+
+ ret = ioctl(fd, XFS_IOC_FSGEOMETRY, fsgeo);
+ if (!ret)
+ return 0;
+
+ ret = ioctl(fd, XFS_IOC_FSGEOMETRY_V4, fsgeo);
+ if (!ret)
+ return 0;
+
+ ret = ioctl(fd, XFS_IOC_FSGEOMETRY_V1, fsgeo);
+ if (!ret)
+ return 0;
+
+ return -errno;
+}
+
+/*
+ * Prepare xfs_fd structure for future ioctl operations by computing the xfs
+ * geometry for @xfd->fd. Returns zero or a negative error code.
+ */
+int
+xfd_prepare_geometry(
+ struct xfs_fd *xfd)
+{
+ int ret;
+
+ ret = xfrog_geometry(xfd->fd, &xfd->fsgeom);
+ if (ret)
+ return ret;
+
+ xfd->agblklog = log2_roundup(xfd->fsgeom.agblocks);
+ xfd->blocklog = highbit32(xfd->fsgeom.blocksize);
+ xfd->inodelog = highbit32(xfd->fsgeom.inodesize);
+ xfd->inopblog = xfd->blocklog - xfd->inodelog;
+ xfd->aginolog = xfd->agblklog + xfd->inopblog;
+ xfd->blkbb_log = xfd->blocklog - BBSHIFT;
+ return 0;
+}
+
+/* Open a file on an XFS filesystem. Returns zero or a negative error code. */
+int
+xfd_open(
+ struct xfs_fd *xfd,
+ const char *pathname,
+ int flags)
+{
+ int ret;
+
+ xfd->fd = open(pathname, flags);
+ if (xfd->fd < 0)
+ return -errno;
+
+ ret = xfd_prepare_geometry(xfd);
+ if (ret) {
+ xfd_close(xfd);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Release any resources associated with this xfs_fd structure. Returns zero
+ * or a negative error code.
+ */
+int
+xfd_close(
+ struct xfs_fd *xfd)
+{
+ int ret = 0;
+
+ if (xfd->fd < 0)
+ return 0;
+
+ ret = close(xfd->fd);
+ xfd->fd = -1;
+ if (ret < 0)
+ return -errno;
+
+ return 0;
+}
+
+/* Try to obtain an AG's geometry. Returns zero or a negative error code. */
+int
+xfrog_ag_geometry(
+ int fd,
+ unsigned int agno,
+ struct xfs_ag_geometry *ageo)
+{
+ int ret;
+
+ ageo->ag_number = agno;
+ ret = ioctl(fd, XFS_IOC_AG_GEOMETRY, ageo);
+ if (ret)
+ return -errno;
+ return 0;
+}