[RFC,17/16] xfs_spaceman: only produce info for root of mounted xfs
diff mbox

Message ID f85deeb7-b9f3-9be2-9684-f241da880302@sandeen.net
State New
Headers show

Commit Message

Eric Sandeen March 7, 2018, 6:34 p.m. UTC
Previously, xfs_info / xfs_growfs would only operate if
pointed at the root of a mounted xfs filesystem, and not a
file within that filesystem. (Although the ioctl will allow it,
the utility does not, to avoid errors and confusion).

When the info capability was moved to xfs_spaceman, this restriction
got lost.

And now that xfs_db can print xfs_info-like info about image files
and devices, the potential exists for misdirecting the request
and running the ioctl on a file and getting the underlying fs
info, rather than using libxfs to parse the image itself, if
the wrong tool is used to point at the file.

Add a new function to (ab)use XFS_IOC_FSINUMBERS to determine
whether the thing we've been pointed at is in fact the root
directory of a mounted xfs filesystem.  If not, don't proceed.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---

I need to look, perhaps this could simplify growfs as well.
I'm not sure I've put this in the right place (libfrog?) either,
but for the sake of discsussion ...


--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/include/libfrog.h b/include/libfrog.h
index 2d8055b..f7cd00a 100644
--- a/include/libfrog.h
+++ b/include/libfrog.h
@@ -18,6 +18,9 @@ 
 #ifndef __LIBFROG_UTIL_H_
 #define __LIBFROG_UTIL_H_
 
+#include <stdbool.h>
+
 unsigned int	log2_roundup(unsigned int i);
+bool		fd_is_xfs_root(int fd);
 
 #endif /* __LIBFROG_UTIL_H_ */
diff --git a/libfrog/util.c b/libfrog/util.c
index 4896e4b..4913f38 100644
--- a/libfrog/util.c
+++ b/libfrog/util.c
@@ -16,6 +16,7 @@ 
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include "platform_defs.h"
+#include "libxfs.h"
 #include "libfrog.h"
 
 /*
@@ -34,3 +35,44 @@  log2_roundup(unsigned int i)
 	}
 	return rval;
 }
+
+/* Test whether a given fd is the root of a mounted xfs filesystem */
+bool
+fd_is_xfs_root(
+	int			fd)
+{
+	struct xfs_fsop_bulkreq	igrpreq = {0};
+	struct xfs_inogrp	inogrp;
+	__u64			igrp_ino = 0;
+	__s32			igrplen = 0;
+	__u64			first_ino;
+	struct stat		statbuf;
+
+	igrpreq.lastip  = &igrp_ino;
+	igrpreq.icount = 1;
+	igrpreq.ubuffer = &inogrp;
+	igrpreq.ocount  = &igrplen;
+
+	if (ioctl(fd, XFS_IOC_FSINUMBERS, &igrpreq))
+		return false;
+
+	/* find the first allocated inode */
+	while (!ioctl(fd, XFS_IOC_FSINUMBERS, &igrpreq)) {
+		if (inogrp.xi_alloccount)
+			break;
+        }
+
+	/* The ioctl failed ... */
+	if (!inogrp.xi_alloccount)
+		return false;
+
+	first_ino = inogrp.xi_startino + libxfs_lowbit64(inogrp.xi_allocmask);
+
+	if (fstat(fd, &statbuf))
+		return false;
+
+	if (first_ino != statbuf.st_ino)
+		return false;
+
+	return true;
+}
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index a23a28d..79a0bd7 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -25,6 +25,8 @@ 
  * it can be included in both the internal and external libxfs header files
  * without introducing any depenencies between the two.
  */
+#define xfs_lowbit32			libxfs_lowbit32
+#define xfs_lowbit64			libxfs_lowbit64
 #define xfs_highbit32			libxfs_highbit32
 #define xfs_highbit64			libxfs_highbit64
 
diff --git a/spaceman/info.c b/spaceman/info.c
index 6557b54..df088f4 100644
--- a/spaceman/info.c
+++ b/spaceman/info.c
@@ -44,6 +44,13 @@  info_f(
 	struct xfs_fsop_geom	geo;
 	int			error;
 
+	if (!fd_is_xfs_root(file->fd)) {
+		fprintf(stderr, _("%s: %s is not a mounted XFS filesystem\n"),
+			progname, file->name);
+		exitcode = 1;
+		return 0;
+	}
+
 	/* get the current filesystem size & geometry */
 	error = ioctl(file->fd, XFS_IOC_FSGEOMETRY, &geo);
 	if (error) {