[PATCH 12/14 v2] xfsprogs: make fsr use mntinfo when there is no mntent

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



UPDATE:
- refactor ifdefs to platform_ functions

For what fsr needs, mntinfo can be used instead of mntent on some
platforms. Exctract the platform-specific code to platform headers.

Signed-off-by: Jan Tulak <jtulak@xxxxxxxxxx>
---
 fsr/Makefile          |   8 ++++
 fsr/xfs_fsr.c         | 127 +++++++++++++++++++++++++++++++-------------------
 include/darwin.h      |  64 +++++++++++++++++++++++++
 include/freebsd.h     |  32 +++++++++++++
 include/gnukfreebsd.h |  31 ++++++++++++
 include/irix.h        |  32 +++++++++++++
 include/linux.h       |  31 ++++++++++++
 7 files changed, 276 insertions(+), 49 deletions(-)

diff --git a/fsr/Makefile b/fsr/Makefile
index a9d1bf6..d3521b2 100644
--- a/fsr/Makefile
+++ b/fsr/Makefile
@@ -9,6 +9,14 @@ LTCOMMAND = xfs_fsr
 CFILES = xfs_fsr.c
 LLDLIBS = $(LIBHANDLE)
 
+ifeq ($(HAVE_GETMNTENT),yes)
+LCFLAGS += -DHAVE_GETMNTENT
+endif
+
+ifeq ($(HAVE_GETMNTINFO),yes)
+LCFLAGS += -DHAVE_GETMNTINFO
+endif
+
 default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
index c8ef18f..d7087d4 100644
--- a/fsr/xfs_fsr.c
+++ b/fsr/xfs_fsr.c
@@ -32,10 +32,6 @@
 #include <sys/statvfs.h>
 #include <sys/xattr.h>
 
-#ifdef HAVE_MNTENT
-#  include <mntent.h>
-#endif
-
 #ifndef XFS_XFLAG_NODEFRAG
 #define XFS_XFLAG_NODEFRAG 0x00002000 /* src dependancy, remove later */
 #endif
@@ -174,60 +170,69 @@ aborter(int unused)
 	exit(1);
 }
 
+
+
 /*
  * Check if the argument is either the device name or mountpoint of an XFS
  * filesystem.  Note that we do not care about bind mounted regular files
  * here - the code that handles defragmentation of invidual files takes care
  * of that.
  */
+
 static char *
-find_mountpoint(char *mtab, char *argname, struct stat64 *sb)
+find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 ms)
 {
-	struct mntent *t;
-	struct stat64 ms;
-	FILE *mtabp;
-	char *mntp = NULL;
+	if (S_ISDIR(sb->st_mode)) {		/* mount point */
+		if (stat64(t->mnt_dir, &ms) < 0)
+			return NULL;
+		if (sb->st_ino != ms.st_ino)
+			return NULL;
+		if (sb->st_dev != ms.st_dev)
+			return NULL;
+		if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0)
+			return NULL;
+	} else {				/* device */
+		struct stat64 sb2;
+
+		if (stat64(t->mnt_fsname, &ms) < 0)
+			return NULL;
+		if (sb->st_rdev != ms.st_rdev)
+			return NULL;
+		if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0)
+			return NULL;
 
-	mtabp = setmntent(mtab, "r");
-	if (!mtabp) {
-		fprintf(stderr, _("%s: cannot read %s\n"),
-			progname, mtab);
-		exit(1);
+		/*
+			* Make sure the mountpoint given by mtab is accessible
+			* before using it.
+			*/
+		if (stat64(t->mnt_dir, &sb2) < 0)
+			return NULL;
 	}
 
-	while ((t = getmntent(mtabp))) {
-		if (S_ISDIR(sb->st_mode)) {		/* mount point */
-			if (stat64(t->mnt_dir, &ms) < 0)
-				continue;
-			if (sb->st_ino != ms.st_ino)
-				continue;
-			if (sb->st_dev != ms.st_dev)
-				continue;
-			if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0)
-				continue;
-		} else {				/* device */
-			struct stat64 sb2;
+	return t->mnt_dir;
 
-			if (stat64(t->mnt_fsname, &ms) < 0)
-				continue;
-			if (sb->st_rdev != ms.st_rdev)
-				continue;
-			if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0)
-				continue;
+}
 
-			/*
-			 * Make sure the mountpoint given by mtab is accessible
-			 * before using it.
-			 */
-			if (stat64(t->mnt_dir, &sb2) < 0)
-				continue;
-		}
+static char *
+find_mountpoint(char *mtab, char *argname, struct stat64 *sb)
+{
+	struct mntent_cursor cursor;
+	struct stat64 ms;
+	struct mntent t = {};
+	char *mntp = NULL;
 
-		mntp = t->mnt_dir;
+	if (platform_mntent_open(&cursor, mtab) != 0){
+		fprintf(stderr, "Error: can't get mntent entries.\n");
+		exit(1);
+	}
+		
+	while (platform_mntent_next(&cursor, &t) == 0) {
+		mntp = find_mountpoint_check(sb, &t, ms);
+		if (mntp == NULL)
+			continue;
 		break;
 	}
-
-	endmntent(mtabp);
+	platform_mntent_close(&cursor);
 	return mntp;
 }
 
@@ -405,18 +410,11 @@ usage(int ret)
 static void
 initallfs(char *mtab)
 {
-	FILE *fp;
 	struct mntent *mp;
 	int mi;
 	char *cp;
 	struct stat64 sb;
 
-	fp = setmntent(mtab, "r");
-	if (fp == NULL) {
-		fsrprintf(_("could not open mtab file: %s\n"), mtab);
-		exit(1);
-	}
-
 	/* malloc a number of descriptors, increased later if needed */
 	if (!(fsbase = (fsdesc_t *)malloc(fsbufsize * sizeof(fsdesc_t)))) {
 		fsrprintf(_("out of memory: %s\n"), strerror(errno));
@@ -427,7 +425,36 @@ initallfs(char *mtab)
 	/* find all rw xfs file systems */
 	mi = 0;
 	fs = fsbase;
+
+#if defined(HAVE_GETMNTENT)
+	FILE *fp;
+	fp = setmntent(mtab, "r");
+	if (fp == NULL) {
+		fsrprintf(_("could not open mtab file: %s\n"), mtab);
+		exit(1);
+	}
+
 	while ((mp = getmntent(fp))) {
+#elif defined(HAVE_GETMNTINFO)
+	struct statfs	*stats;
+	int error, i, count;
+	// because "t" is a pointer, but we don't need to use
+	// malloc for this usage
+	struct mntent mp_tmp;
+	mp = &mp_tmp;
+	error = 0;
+	if ((count = getmntinfo(&stats, 0)) < 0) {
+		fprintf(stderr, _("%s: getmntinfo() failed: %s\n"),
+				progname, strerror(errno));
+		exit(1);
+	}
+
+	for (i = 0; i < count; i++) {
+		mntinfo2mntent(&stats[i], mp);
+#else
+# error "How do I extract info about mounted filesystems on this platform?"
+#endif
+
 		int rw = 0;
 
 		if (strcmp(mp->mnt_type, MNTTYPE_XFS ) != 0 ||
@@ -479,7 +506,9 @@ initallfs(char *mtab)
 	}
 	numfs = mi;
 	fsend = (fsbase + numfs);
+#if defined(HAVE_GETMNTENT)
 	endmntent(fp);
+#endif
 	if (numfs == 0) {
 		fsrprintf(_("no rw xfs file systems in mtab: %s\n"), mtab);
 		exit(0);
diff --git a/include/darwin.h b/include/darwin.h
index 288ad1f..fd9384d 100644
--- a/include/darwin.h
+++ b/include/darwin.h
@@ -33,6 +33,8 @@
 #include <mach/mach_time.h>
 #include <inttypes.h>
 #include <stdio.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
 
 #include <machine/endian.h>
 #define __BYTE_ORDER	BYTE_ORDER
@@ -218,7 +220,69 @@ static inline int timer_gettime (timer_t timerid, struct itimerspec *value)
 
 /* FSR */
 
+#  include <sys/mount.h>
+#  include <sys/param.h>
+#include <sys/ucred.h>
+#include <errno.h>
 #define statvfs64 statfs
 #define		_PATH_MOUNTED   "/etc/mtab"
 
+struct mntent
+{
+	char *mnt_fsname;
+	char *mnt_dir;
+	char *mnt_type;
+	char *mnt_opts;
+	int mnt_freq;
+	int mnt_passno;
+};
+
+static inline void mntinfo2mntent (struct statfs * stats, struct mntent * mnt) {
+	mnt->mnt_fsname = stats->f_mntfromname;
+	mnt->mnt_dir = stats->f_mntonname;
+	mnt->mnt_type = stats->f_fstypename;
+}
+
+
+
+/**
+ * Abstraction of mountpoints.
+ */
+struct mntent_cursor {
+	FILE *mtabp;
+	struct statfs *stats;
+	int count;
+	int i;
+};
+
+/**
+ * OS X uses getmntinfo, which doesn't use a mtab file. So we just ignore it.
+ */
+static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab)
+{	
+	if ((cursor->count = getmntinfo(&cursor->stats, 0)) < 0) {
+		fprintf(stderr, "Error: getmntinfo() failed: %s\n", strerror(errno));
+		return 1;
+	}
+	cursor->i = 0;
+	return 0;
+}
+
+static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t)
+{
+	if (cursor->i >= cursor->count){
+		return 1;
+	}
+	mntinfo2mntent(&cursor->stats[cursor->i], t);
+	cursor->i++;
+	return 0;
+
+}
+
+static inline void platform_mntent_close(struct mntent_cursor * cursor)
+{
+	cursor->count = 0;
+	cursor->i = 0;
+}
+
 #endif	/* __XFS_DARWIN_H__ */
diff --git a/include/freebsd.h b/include/freebsd.h
index 902b940..6bc9e61 100644
--- a/include/freebsd.h
+++ b/include/freebsd.h
@@ -26,6 +26,7 @@
 #include <libgen.h>
 #include <paths.h>
 #include <uuid.h>
+#include <mntent.h>
 
 #include <sys/endian.h>
 #define __BYTE_ORDER	BYTE_ORDER
@@ -147,4 +148,35 @@ platform_discard_blocks(int fd, uint64_t start, uint64_t len)
 	return 0;
 }
 
+/**
+ * Abstraction of mountpoints.
+ */
+struct mntent_cursor {
+	FILE *mtabp;
+};
+
+static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab)
+{
+	cursor->mtabp = setmntent(mtab, "r");
+	if (!cursor->mtabp) {
+		fprintf(stderr, "Error: cannot read %s\n", mtab);
+		return 1;
+	}
+	return 0;
+}
+
+static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t)
+{
+	t = getmntent(cursor->mtabp);
+	if (t == NULL)
+		return 1;
+	return 0;
+}
+
+static inline void platform_mntent_close(struct mntent_cursor * cursor)
+{
+	endmntent(cursor->mtabp);
+}
+
+
 #endif	/* __XFS_FREEBSD_H__ */
diff --git a/include/gnukfreebsd.h b/include/gnukfreebsd.h
index 95c4c13..2740cae 100644
--- a/include/gnukfreebsd.h
+++ b/include/gnukfreebsd.h
@@ -31,6 +31,7 @@
 #include <ctype.h>
 #include <libgen.h>
 #include <paths.h>
+#include <mntent.h>
 
 #define constpp	char * const *
 
@@ -126,4 +127,34 @@ platform_discard_blocks(int fd, uint64_t start, uint64_t len)
 	return 0;
 }
 
+/**
+ * Abstraction of mountpoints.
+ */
+struct mntent_cursor {
+	FILE *mtabp;
+};
+
+static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab)
+{
+	cursor->mtabp = setmntent(mtab, "r");
+	if (!cursor->mtabp) {
+		fprintf(stderr, "Error: cannot read %s\n", mtab);
+		return 1;
+	}
+	return 0;
+}
+
+static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t)
+{
+	t = getmntent(cursor->mtabp);
+	if (t == NULL)
+		return 1;
+	return 0;
+}
+
+static inline void platform_mntent_close(struct mntent_cursor * cursor)
+{
+	endmntent(cursor->mtabp);
+}
+
 #endif	/* __XFS_KFREEBSD_H__ */
diff --git a/include/irix.h b/include/irix.h
index 28564c8..cb9cce0 100644
--- a/include/irix.h
+++ b/include/irix.h
@@ -37,6 +37,7 @@
 #include <sys/sysmacros.h>
 #include <sys/fs/xfs_fsops.h>
 #include <sys/fs/xfs_itable.h>
+#include <mntent.h>
 
 #define __int8_t	char
 #define __int16_t	short
@@ -423,4 +424,35 @@ static __inline__ char * strsep(char **s, const char *ct)
 
 #define	XFS_XFLAG_NODEFRAG		0x00002000
 
+/**
+ * Abstraction of mountpoints.
+ */
+struct mntent_cursor {
+	FILE *mtabp;
+};
+
+static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab)
+{
+	cursor->mtabp = setmntent(mtab, "r");
+	if (!cursor->mtabp) {
+		fprintf(stderr, "Error: cannot read %s\n", mtab);
+		return 1;
+	}
+	return 0;
+}
+
+static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t)
+{
+	t = getmntent(cursor->mtabp);
+	if (t == NULL)
+		return 1;
+	return 0;
+}
+
+static inline void platform_mntent_close(struct mntent_cursor * cursor)
+{
+	endmntent(cursor->mtabp);
+}
+
+
 #endif	/* __XFS_IRIX_H__ */
diff --git a/include/linux.h b/include/linux.h
index 8804c2d..437970b 100644
--- a/include/linux.h
+++ b/include/linux.h
@@ -30,6 +30,7 @@
 #include <endian.h>
 #include <stdbool.h>
 #include <asm/types.h>
+#include <mntent.h>
 
 static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p)
 {
@@ -145,4 +146,34 @@ typedef __uint64_t	xfs_ino_t;
 typedef __uint32_t	xfs_dev_t;
 typedef __int64_t	xfs_daddr_t;
 
+/**
+ * Abstraction of mountpoints.
+ */
+struct mntent_cursor {
+	FILE *mtabp;
+};
+
+static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab)
+{
+	cursor->mtabp = setmntent(mtab, "r");
+	if (!cursor->mtabp) {
+		fprintf(stderr, "Error: cannot read %s\n", mtab);
+		return 1;
+	}
+	return 0;
+}
+
+static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t)
+{
+	t = getmntent(cursor->mtabp);
+	if (t == NULL)
+		return 1;
+	return 0;
+}
+
+static inline void platform_mntent_close(struct mntent_cursor * cursor)
+{
+	endmntent(cursor->mtabp);
+}
+
 #endif	/* __XFS_LINUX_H__ */
-- 
2.4.3

_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs



[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux