]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfsprogs: make fsr use mntinfo when there is no mntent
authorJan Tulak <jtulak@redhat.com>
Tue, 10 Nov 2015 04:45:02 +0000 (15:45 +1100)
committerDave Chinner <david@fromorbit.com>
Tue, 10 Nov 2015 04:45:02 +0000 (15:45 +1100)
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@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fsr/Makefile
fsr/xfs_fsr.c
include/darwin.h
include/freebsd.h
include/gnukfreebsd.h
include/irix.h
include/linux.h

index a9d1bf68a46ac2f71c4fb1aba8d97330347a4ab6..d3521b23642e1041c6a48a48d8338e2490387a61 100644 (file)
@@ -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)
index c8ef18fca3e9c6cebd1616ef36f9c676044c0dcc..b902acc3c9da4a779a88339e0e72b90c8ab92e64 100644 (file)
 #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
@@ -180,54 +176,61 @@ aborter(int unused)
  * here - the code that handles defragmentation of invidual files takes care
  * of that.
  */
+
+static char *
+find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 *ms)
+{
+       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;
+
+               /*
+                       * Make sure the mountpoint given by mtab is accessible
+                       * before using it.
+                       */
+               if (stat64(t->mnt_dir, &sb2) < 0)
+                       return NULL;
+       }
+
+       return t->mnt_dir;
+
+}
+
 static char *
 find_mountpoint(char *mtab, char *argname, struct stat64 *sb)
 {
-       struct mntent *t;
+       struct mntent_cursor cursor;
        struct stat64 ms;
-       FILE *mtabp;
+       struct mntent *t = NULL;
        char *mntp = NULL;
 
-       mtabp = setmntent(mtab, "r");
-       if (!mtabp) {
-               fprintf(stderr, _("%s: cannot read %s\n"),
-                       progname, mtab);
+       if (platform_mntent_open(&cursor, mtab) != 0){
+               fprintf(stderr, "Error: can't get mntent entries.\n");
                exit(1);
        }
 
-       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;
-
-                       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;
-               }
-
-               mntp = t->mnt_dir;
+       while ( (t = platform_mntent_next(&cursor)) != NULL) {
+               mntp = find_mountpoint_check(sb, t, &ms);
+               if (mntp == NULL)
+                       continue;
                break;
        }
-
-       endmntent(mtabp);
+       platform_mntent_close(&cursor);
        return mntp;
 }
 
@@ -405,17 +408,13 @@ usage(int ret)
 static void
 initallfs(char *mtab)
 {
-       FILE *fp;
-       struct mntent *mp;
+       struct mntent_cursor cursor;
+       char *mntp = NULL;
+       struct mntent *mp = NULL;
        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);
-       }
+       struct stat64 ms;
 
        /* malloc a number of descriptors, increased later if needed */
        if (!(fsbase = (fsdesc_t *)malloc(fsbufsize * sizeof(fsdesc_t)))) {
@@ -427,7 +426,18 @@ initallfs(char *mtab)
        /* find all rw xfs file systems */
        mi = 0;
        fs = fsbase;
-       while ((mp = getmntent(fp))) {
+
+       if (platform_mntent_open(&cursor, mtab) != 0){
+               fprintf(stderr, "Error: can't get mntent entries.\n");
+               exit(1);
+       }
+
+       while ( (mp = platform_mntent_next(&cursor)) != NULL) {
+               mntp = find_mountpoint_check(&sb, mp, &ms);
+               if (mntp == NULL)
+                       continue;
+               break;
+
                int rw = 0;
 
                if (strcmp(mp->mnt_type, MNTTYPE_XFS ) != 0 ||
@@ -477,9 +487,10 @@ initallfs(char *mtab)
                mi++;
                fs++;
        }
+       platform_mntent_close(&cursor);
+
        numfs = mi;
        fsend = (fsbase + numfs);
-       endmntent(fp);
        if (numfs == 0) {
                fsrprintf(_("no rw xfs file systems in mtab: %s\n"), mtab);
                exit(0);
index 6c6e547eb7c8cddfbb3051e70b50a288cf9b6f33..dd6132fd69e05a1ccf30484a93a814ea3653e219 100644 (file)
@@ -219,8 +219,70 @@ 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 lstat64 lstat
 #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 struct mntent * platform_mntent_next(struct mntent_cursor * cursor)
+{
+       struct mntent * t = NULL;
+       if (cursor->i >= cursor->count){
+               return NULL;
+       }
+       mntinfo2mntent(&cursor->stats[cursor->i], t);
+       cursor->i++;
+       return t;
+}
+
+static inline void platform_mntent_close(struct mntent_cursor * cursor)
+{
+       cursor->count = 0;
+       cursor->i = 0;
+}
+
 #endif /* __XFS_DARWIN_H__ */
index 902b940296d572927ef926aa161ce3b4c22432ba..65bd60a50927cf7db15a976803fcc037e6659e4d 100644 (file)
@@ -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,32 @@ 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  struct mntent * platform_mntent_next(struct mntent_cursor * cursor)
+{
+       return getmntent(cursor->mtabp);
+}
+
+static inline void platform_mntent_close(struct mntent_cursor * cursor)
+{
+       endmntent(cursor->mtabp);
+}
+
+
 #endif /* __XFS_FREEBSD_H__ */
index 95c4c13790d7f345b124d7024797b6b81c6fd6c0..64167b247a4038bb430f3f1c5d52f41aac073211 100644 (file)
@@ -31,6 +31,7 @@
 #include <ctype.h>
 #include <libgen.h>
 #include <paths.h>
+#include <mntent.h>
 
 #define constpp        char * const *
 
@@ -126,4 +127,31 @@ 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 struct mntent * platform_mntent_next(struct mntent_cursor * cursor)
+{
+       return getmntent(cursor->mtabp);
+}
+
+static inline void platform_mntent_close(struct mntent_cursor * cursor)
+{
+       endmntent(cursor->mtabp);
+}
+
 #endif /* __XFS_KFREEBSD_H__ */
index 28564c8262847d2c5216bc38d2eddebc721ca1cc..293f869c6f2e2653402ef307c124444ac078d1dd 100644 (file)
@@ -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,32 @@ 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 struct mntent * platform_mntent_next(struct mntent_cursor * cursor)
+{
+       return getmntent(cursor->mtabp);
+}
+
+static inline void platform_mntent_close(struct mntent_cursor * cursor)
+{
+       endmntent(cursor->mtabp);
+}
+
+
 #endif /* __XFS_IRIX_H__ */
index 8804c2d41dda3e3b8c602a023879f7c927d2dd7b..674717cf16d21316d82a08fa2b02a9fe21044813 100644 (file)
@@ -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,31 @@ 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 struct mntent * platform_mntent_next(struct mntent_cursor * cursor)
+{
+       return getmntent(cursor->mtabp);
+}
+
+static inline void platform_mntent_close(struct mntent_cursor * cursor)
+{
+       endmntent(cursor->mtabp);
+}
+
 #endif /* __XFS_LINUX_H__ */