]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - libfrog/fsgeom.c
libfrog: convert fsgeom.c functions to negative error codes
[thirdparty/xfsprogs-dev.git] / libfrog / fsgeom.c
index 8879d161cce46319b720bf9030d33cd912f1420d..19a4911fcf085890f210a02a08a7f4123e0f30c5 100644 (file)
@@ -4,6 +4,7 @@
  */
 #include "libxfs.h"
 #include "fsgeom.h"
+#include "util.h"
 
 void
 xfs_report_geom(
@@ -67,3 +68,110 @@ 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;
+}