]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fix broken Linux fflags code since kernel 3.7 (Dec 2012)
authorMartin Matuska <martin@matuska.org>
Fri, 24 Feb 2017 00:56:50 +0000 (01:56 +0100)
committerMartin Matuska <martin@matuska.org>
Fri, 24 Feb 2017 01:04:16 +0000 (02:04 +0100)
CMakeLists.txt
build/cmake/config.h.in
configure.ac
libarchive/archive_entry.c
libarchive/archive_read_disk_entry_from_file.c
libarchive/archive_read_disk_posix.c
libarchive/archive_write_disk_posix.c
test_utils/test_main.c

index 9a1132cc72871884f407e7e122036f055a4bfb52..baedfcc8652458f7f723176a6df8b41992671059 100644 (file)
@@ -570,6 +570,11 @@ LA_CHECK_INCLUDE_FILE("limits.h" HAVE_LIMITS_H)
 LA_CHECK_INCLUDE_FILE("linux/types.h" HAVE_LINUX_TYPES_H)
 LA_CHECK_INCLUDE_FILE("linux/fiemap.h" HAVE_LINUX_FIEMAP_H)
 LA_CHECK_INCLUDE_FILE("linux/fs.h" HAVE_LINUX_FS_H)
+
+CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
+#include <linux/fs.h>
+int main(void) { return FS_IOC_GETFLAGS; }" HAVE_WORKING_FS_IOC_GETFLAGS)
+
 LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H)
 LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H)
 LA_CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H)
index ec64d9937fab3caaf67f4c78bdbdf8fd06609db8..923a78e5173873282fe27b3fd394185ec7f00aac 100644 (file)
@@ -1099,6 +1099,9 @@ typedef uint64_t uintmax_t;
 /* Define to 1 if you have a working EXT2_IOC_GETFLAGS */
 #cmakedefine HAVE_WORKING_EXT2_IOC_GETFLAGS 1
 
+/* Define to 1 if you have a working FS_IOC_GETFLAGS */
+#cmakedefine HAVE_WORKING_FS_IOC_GETFLAGS 1
+
 /* Define to 1 if you have the <zlib.h> header file. */
 #cmakedefine HAVE_ZLIB_H 1
 
index 0c054cc54e8c6cccbb32bd07e8ec6dce44778779..b29917e80c458eb968252ce6ee586a54db53a7be 100644 (file)
@@ -270,6 +270,19 @@ AS_VAR_IF([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes],
 
 AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h])
 AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h linux/types.h])
+
+AC_CACHE_CHECK([whether FS_IOC_GETFLAGS is usable],
+    [ac_cv_have_decl_FS_IOC_GETFLAGS],
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <sys/ioctl.h>
+@%:@include <linux/fs.h>],
+                                   [int x = FS_IOC_GETFLAGS])],
+                  [AS_VAR_SET([ac_cv_have_decl_FS_IOC_GETFLAGS], [yes])],
+                  [AS_VAR_SET([ac_cv_have_decl_FS_IOC_GETFLAGS], [no])])])
+
+AS_VAR_IF([ac_cv_have_decl_FS_IOC_GETFLAGS], [yes],
+    [AC_DEFINE_UNQUOTED([HAVE_WORKING_FS_IOC_GETFLAGS], [1],
+                    [Define to 1 if you have a working FS_IOC_GETFLAGS])])
+
 AC_CHECK_HEADERS([locale.h paths.h poll.h pthread.h pwd.h])
 AC_CHECK_HEADERS([readpassphrase.h signal.h spawn.h])
 AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h])
index d4f061b5b9d0a91434abecf298a52b8dc6870086..10eff11b287fed0b22ff43a43555a91cbcf1ee91 100644 (file)
@@ -1649,7 +1649,10 @@ static struct flag {
        { "nosappnd",   L"nosappnd",            SF_APPEND,      0 },
        { "nosappend",  L"nosappend",           SF_APPEND,      0 },
 #endif
-#ifdef  EXT2_APPEND_FL                         /* 'a' */
+#if defined(FS_APPEND_FL)                      /* 'a' */
+       { "nosappnd",   L"nosappnd",            FS_APPEND_FL,   0 },
+       { "nosappend",  L"nosappend",           FS_APPEND_FL,   0 },
+#elif defined(EXT2_APPEND_FL)                  /* 'a' */
        { "nosappnd",   L"nosappnd",            EXT2_APPEND_FL, 0 },
        { "nosappend",  L"nosappend",           EXT2_APPEND_FL, 0 },
 #endif
@@ -1662,7 +1665,11 @@ static struct flag {
        { "noschange",  L"noschange",           SF_IMMUTABLE,   0 },
        { "nosimmutable",       L"nosimmutable",        SF_IMMUTABLE,   0 },
 #endif
-#ifdef EXT2_IMMUTABLE_FL                       /* 'i' */
+#if defined(FS_IMMUTABLE_FL)                   /* 'i' */
+       { "noschg",     L"noschg",              FS_IMMUTABLE_FL,        0 },
+       { "noschange",  L"noschange",           FS_IMMUTABLE_FL,        0 },
+       { "nosimmutable",       L"nosimmutable",        FS_IMMUTABLE_FL,        0 },
+#elif defined(EXT2_IMMUTABLE_FL)               /* 'i' */
        { "noschg",     L"noschg",              EXT2_IMMUTABLE_FL,      0 },
        { "noschange",  L"noschange",           EXT2_IMMUTABLE_FL,      0 },
        { "nosimmutable",       L"nosimmutable",        EXT2_IMMUTABLE_FL,      0 },
@@ -1686,7 +1693,9 @@ static struct flag {
 #ifdef UF_NODUMP
        { "nodump",     L"nodump",              0,              UF_NODUMP},
 #endif
-#ifdef EXT2_NODUMP_FL                          /* 'd' */
+#if defined(FS_NODUMP_FL)      /* 'd' */
+       { "nodump",     L"nodump",              0,              FS_NODUMP_FL},
+#elif defined(EXT2_NODUMP_FL)  /* 'd' */
        { "nodump",     L"nodump",              0,              EXT2_NODUMP_FL},
 #endif
 #ifdef UF_OPAQUE
@@ -1699,65 +1708,124 @@ static struct flag {
 #ifdef UF_COMPRESSED
        { "nocompressed",L"nocompressed",       UF_COMPRESSED,  0 },
 #endif
-#ifdef EXT2_UNRM_FL
+#if defined(FS_UNRM_FL)
+        { "nouunlink", L"nouunlink",           FS_UNRM_FL,     0},
+#elif defined(EXT2_UNRM_FL)
         { "nouunlink", L"nouunlink",           EXT2_UNRM_FL,   0},
 #endif
 
-#ifdef EXT2_BTREE_FL
+#if defined(FS_BTREE_FL)
+        { "nobtree",   L"nobtree",             FS_BTREE_FL,    0 },
+#elif defined(EXT2_BTREE_FL)
         { "nobtree",   L"nobtree",             EXT2_BTREE_FL,  0 },
 #endif
 
-#ifdef EXT2_ECOMPR_FL
+#if defined(FS_ECOMPR_FL)
+        { "nocomperr", L"nocomperr",           FS_ECOMPR_FL,   0 },
+#elif defined(EXT2_ECOMPR_FL)
         { "nocomperr", L"nocomperr",           EXT2_ECOMPR_FL, 0 },
 #endif
 
-#ifdef EXT2_COMPR_FL                           /* 'c' */
+#if defined(FS_COMPR_FL)                       /* 'c' */
+        { "nocompress",        L"nocompress",          FS_COMPR_FL,    0 },
+#elif defined(EXT2_COMPR_FL)                   /* 'c' */
         { "nocompress",        L"nocompress",          EXT2_COMPR_FL,  0 },
 #endif
 
-#ifdef EXT2_NOATIME_FL                         /* 'A' */
+#if defined(FS_NOATIME_FL)                     /* 'A' */
+        { "noatime",   L"noatime",             0,              FS_NOATIME_FL},
+#elif defined(EXT2_NOATIME_FL)                 /* 'A' */
         { "noatime",   L"noatime",             0,              EXT2_NOATIME_FL},
 #endif
 
-#ifdef EXT2_DIRTY_FL
+#if defined(FS_DIRTY_FL)
+        { "nocompdirty",L"nocompdirty",                FS_DIRTY_FL,            0},
+#elif defined(EXT2_DIRTY_FL)
         { "nocompdirty",L"nocompdirty",                EXT2_DIRTY_FL,          0},
 #endif
 
-#ifdef EXT2_COMPRBLK_FL
-#ifdef EXT2_NOCOMPR_FL
+#if defined(FS_COMPRBLK_FL)
+#if defined(FS_NOCOMPR_FL)
+        { "nocomprblk",        L"nocomprblk",          FS_COMPRBLK_FL, FS_NOCOMPR_FL},
+#else
+        { "nocomprblk",        L"nocomprblk",          FS_COMPRBLK_FL, 0},
+#endif
+#elif defined(EXT2_COMPRBLK_FL)
+#if defined(EXT2_NOCOMPR_FL)
         { "nocomprblk",        L"nocomprblk",          EXT2_COMPRBLK_FL, EXT2_NOCOMPR_FL},
 #else
         { "nocomprblk",        L"nocomprblk",          EXT2_COMPRBLK_FL,       0},
 #endif
 #endif
-#ifdef EXT2_DIRSYNC_FL
+#if defined(FS_DIRSYNC_FL)
+        { "nodirsync", L"nodirsync",           FS_DIRSYNC_FL,  0},
+#elif defined(EXT2_DIRSYNC_FL)
         { "nodirsync", L"nodirsync",           EXT2_DIRSYNC_FL,        0},
 #endif
-#ifdef EXT2_INDEX_FL
+#if defined(FS_INDEX_FL)
+        { "nohashidx", L"nohashidx",           FS_INDEX_FL,            0},
+#elif defined(EXT2_INDEX_FL)
         { "nohashidx", L"nohashidx",           EXT2_INDEX_FL,          0},
 #endif
-#ifdef EXT2_IMAGIC_FL
+#if defined(FS_IMAGIC_FL)
+        { "noimagic",  L"noimagic",            FS_IMAGIC_FL,           0},
+#elif defined(EXT2_IMAGIC_FL)
         { "noimagic",  L"noimagic",            EXT2_IMAGIC_FL,         0},
 #endif
-#ifdef EXT3_JOURNAL_DATA_FL
+#if defined(FS_JOURNAL_DATA_FL)
+        { "nojournal", L"nojournal",           FS_JOURNAL_DATA_FL,     0},
+#elif defined(EXT3_JOURNAL_DATA_FL)
         { "nojournal", L"nojournal",           EXT3_JOURNAL_DATA_FL,   0},
 #endif
-#ifdef EXT2_SECRM_FL
+#if defined(FS_SECRM_FL)
+        { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL,          0},
+#elif defined(EXT2_SECRM_FL)
         { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL,                0},
 #endif
-#ifdef EXT2_SYNC_FL
+#if defined(FS_SYNC_FL)
+        { "nosync",    L"nosync",              FS_SYNC_FL,             0},
+#elif defined(EXT2_SYNC_FL)
         { "nosync",    L"nosync",              EXT2_SYNC_FL,           0},
 #endif
-#ifdef EXT2_NOTAIL_FL
+#if defined(FS_NOTAIL_FL)
+        { "notail",    L"notail",              0,              FS_NOTAIL_FL},
+#elif defined(EXT2_NOTAIL_FL)
         { "notail",    L"notail",              0,              EXT2_NOTAIL_FL},
 #endif
-#ifdef EXT2_TOPDIR_FL
+#if defined(FS_TOPDIR_FL)
+        { "notopdir",  L"notopdir",            FS_TOPDIR_FL,           0},
+#elif defined(EXT2_TOPDIR_FL)
         { "notopdir",  L"notopdir",            EXT2_TOPDIR_FL,         0},
 #endif
-#ifdef EXT2_RESERVED_FL
+#ifdef FS_ENCRYPT_FL
+        { "noencrypt", L"noencrypt",           FS_ENCRYPT_FL,  0},
+#endif
+#ifdef FS_HUGE_FILE_FL
+        { "nohugefile",        L"nohugefile",          FS_HUGE_FILE_FL,        0},
+#endif
+#ifdef FS_EXTENT_FL
+        { "noextent",  L"noextent",            FS_EXTENT_FL,   0},
+#endif
+#ifdef FS_EA_INODE_FL
+        { "noeainode", L"noeainode",           FS_EA_INODE_FL, 0},
+#endif
+#ifdef FS_EOFBLOCKS_FL
+        { "noeofblocks",L"noeofblocks",                FS_EOFBLOCKS_FL,        0},
+#endif
+#ifdef FS_NOCOW_FL
+        { "nocow",     L"nocow",               FS_NOCOW_FL,    0},
+#endif
+#ifdef FS_INLINE_DATA_FL
+        { "noinlinedata",L"noinlinedata",      FS_INLINE_DATA_FL,      0},
+#endif
+#ifdef FS_PROJINHERIT_FL
+        { "noprojinherit",L"noprojinherit",    FS_PROJINHERIT_FL,      0},
+#endif
+#if defined(FS_RESERVED_FL)
+        { "noreserved",        L"noreserved",          FS_RESERVED_FL, 0},
+#elif defined(EXT2_RESERVED_FL)
         { "noreserved",        L"noreserved",          EXT2_RESERVED_FL,       0},
 #endif
-
        { NULL,         NULL,                   0,              0 }
 };
 
index 1e20bea8414ee73dd4dbbe6c58736ab319ae14da..603b70763b3d17cb101f3166279d6deb560c24e4 100644 (file)
@@ -207,7 +207,8 @@ archive_read_disk_entry_from_file(struct archive *_a,
                archive_entry_set_fflags(entry, st->st_flags, 0);
 #endif
 
-#if defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+#if (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+    (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
        /* Linux requires an extra ioctl to pull the flags.  Although
         * this is an extra step, it has a nice side-effect: We get an
         * open file descriptor which we can use in the subsequent lookups. */
@@ -223,7 +224,13 @@ archive_read_disk_entry_from_file(struct archive *_a,
                }
                if (fd >= 0) {
                        int stflags;
-                       r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
+                       r = ioctl(fd,
+#if defined(FS_IOC_GETFLAGS)
+                           FS_IOC_GETFLAGS,
+#else
+                           EXT2_IOC_GETFLAGS,
+#endif
+                           &stflags);
                        if (r == 0 && stflags != 0)
                                archive_entry_set_fflags(entry, stflags, 0);
                }
index 7f7823afdbe8bf2cbc489c44f6c34e6bf59b353f..6961ae6a42fe67df71115ab546ed175a01b513e2 100644 (file)
@@ -981,8 +981,10 @@ next_entry(struct archive_read_disk *a, struct tree *t,
 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
                if (st->st_flags & UF_NODUMP)
                        return (ARCHIVE_RETRY);
-#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) &&\
-      defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+#elif (defined(FS_IOC_GETFLAGS) && defined(FS_NODUMP_FL) && \
+       defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+      (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) && \
+       defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
                if (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) {
                        int stflags;
 
@@ -991,9 +993,18 @@ next_entry(struct archive_read_disk *a, struct tree *t,
                            O_RDONLY | O_NONBLOCK | O_CLOEXEC);
                        __archive_ensure_cloexec_flag(t->entry_fd);
                        if (t->entry_fd >= 0) {
-                               r = ioctl(t->entry_fd, EXT2_IOC_GETFLAGS,
+                               r = ioctl(t->entry_fd,
+#ifdef FS_IOC_GETFLAGS
+                               FS_IOC_GETFLAGS,
+#else
+                               EXT2_IOC_GETFLAGS,
+#endif
                                        &stflags);
+#ifdef FS_NODUMP_FL
+                               if (r == 0 && (stflags & FS_NODUMP_FL) != 0)
+#else
                                if (r == 0 && (stflags & EXT2_NODUMP_FL) != 0)
+#endif
                                        return (ARCHIVE_RETRY);
                        }
                }
index 20450bafcb0fed7c52df6c7f4577759b9a4b9b10..3dfdb546d574e9ebc4ce21a433640fdcf399914f 100644 (file)
@@ -3465,12 +3465,19 @@ set_fflags(struct archive_write_disk *a)
 #ifdef UF_APPEND
        critical_flags |= UF_APPEND;
 #endif
-#ifdef EXT2_APPEND_FL
+#if defined(FS_APPEND_FL)
+       critical_flags |= FS_APPEND_FL;
+#elif defined(EXT2_APPEND_FL)
        critical_flags |= EXT2_APPEND_FL;
 #endif
-#ifdef EXT2_IMMUTABLE_FL
+#if defined(FS_IMMUTABLE_FL)
+       critical_flags |= FS_IMMUTABLE_FL;
+#elif defined(EXT2_IMMUTABLE_FL)
        critical_flags |= EXT2_IMMUTABLE_FL;
 #endif
+#ifdef FS_JOURNAL_DATA_FL
+       critical_flags |= FS_JOURNAL_DATA_FL;
+#endif
 
        if (a->todo & TODO_FFLAGS) {
                archive_entry_fflags(a->entry, &set, &clear);
@@ -3582,7 +3589,10 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
        return (ARCHIVE_WARN);
 }
 
-#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+#elif (defined(FS_IOC_GETFLAGS) && defined(FS_IOC_SETFLAGS) && \
+       defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+      (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && \
+       defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
 /*
  * Linux uses ioctl() to read and write file flags.
  */
@@ -3595,7 +3605,7 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
        int newflags, oldflags;
        int sf_mask = 0;
 
-       if (set == 0  && clear == 0)
+       if (set == 0 && clear == 0)
                return (ARCHIVE_OK);
        /* Only regular files and dirs can have flags. */
        if (!S_ISREG(mode) && !S_ISDIR(mode))
@@ -3616,11 +3626,18 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
         * defines. (?)  The code below degrades reasonably gracefully
         * if sf_mask is incomplete.
         */
-#ifdef EXT2_IMMUTABLE_FL
+#if defined(FS_IMMUTABLE_FL)
+       sf_mask |= FS_IMMUTABLE_FL;
+#elif defined(EXT2_IMMUTABLE_FL)
        sf_mask |= EXT2_IMMUTABLE_FL;
 #endif
-#ifdef EXT2_APPEND_FL
+#if defined(FS_APPEND_FL)
+       sf_mask |= FS_APPEND_FL;
+#elif defined(EXT2_APPEND_FL)
        sf_mask |= EXT2_APPEND_FL;
+#endif
+#if defined(FS_JOURNAL_DATA_FL)
+       sf_mask |= FS_JOURNAL_DATA_FL;
 #endif
        /*
         * XXX As above, this would be way simpler if we didn't have
@@ -3629,12 +3646,24 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
        ret = ARCHIVE_OK;
 
        /* Read the current file flags. */
-       if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) < 0)
+       if (ioctl(myfd,
+#ifdef FS_IOC_GETFLAGS
+           FS_IOC_GETFLAGS,
+#else
+           EXT2_IOC_GETFLAGS,
+#endif
+           &oldflags) < 0)
                goto fail;
 
        /* Try setting the flags as given. */
        newflags = (oldflags & ~clear) | set;
-       if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+       if (ioctl(myfd,
+#ifdef FS_IOC_SETFLAGS
+           FS_IOC_SETFLAGS,
+#else
+           EXT2_IOC_SETFLAGS,
+#endif
+           &newflags) >= 0)
                goto cleanup;
        if (errno != EPERM)
                goto fail;
@@ -3643,7 +3672,13 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
        newflags &= ~sf_mask;
        oldflags &= sf_mask;
        newflags |= oldflags;
-       if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+       if (ioctl(myfd,
+#ifdef FS_IOC_SETFLAGS
+           FS_IOC_SETFLAGS,
+#else
+           EXT2_IOC_SETFLAGS,
+#endif
+           &newflags) >= 0)
                goto cleanup;
 
        /* We couldn't set the flags, so report the failure. */
index b0b6c2bd4d45de6a864c623552644de200c91614..2ae6b38db06ecdb7405f0236f18e990e40394876 100644 (file)
@@ -45,6 +45,9 @@
 #if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
 #include <ext2fs/ext2_fs.h>     /* Linux file flags, broken on Cygwin */
 #endif
+#ifdef HAVE_LINUX_FS_H
+#include <linux/fs.h>
+#endif
 #include <limits.h>
 #include <locale.h>
 #ifdef HAVE_SIGNAL_H
@@ -1894,8 +1897,10 @@ assertion_nodump(const char *file, int line, const char *pathname)
                failure_finish(NULL);
                return (0);
        }
-#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
-        && defined(EXT2_NODUMP_FL)
+#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) && \
+       defined(FS_NODUMP_FL)) || \
+      (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
+        && defined(EXT2_NODUMP_FL))
        int fd, r, flags;
 
        assertion_count(file, line);
@@ -1905,14 +1910,31 @@ assertion_nodump(const char *file, int line, const char *pathname)
                failure_finish(NULL);
                return (0);
        }
-       r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+       r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+           FS_IOC_GETFLAGS,
+#else
+           EXT2_IOC_GETFLAGS,
+#endif
+           &flags);
        if (r < 0) {
                failure_start(file, line, "Can't get flags %s\n", pathname);
                failure_finish(NULL);
                return (0);
        }
+#ifdef FS_NODUMP_FL
+       flags |= FS_NODUMP_FL;
+#else
        flags |= EXT2_NODUMP_FL;
-       r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+#endif
+
+        r = ioctl(fd,
+#ifdef FS_IOC_SETFLAGS
+           FS_IOC_SETFLAGS,
+#else
+           EXT2_IOC_SETFLAGS,
+#endif
+           &flags);
        if (r < 0) {
                failure_start(file, line, "Can't set nodump %s\n", pathname);
                failure_finish(NULL);
@@ -2252,9 +2274,10 @@ canNodump(void)
        return (0);
 }
 
-#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
-        && defined(EXT2_NODUMP_FL)
-
+#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) \
+        && defined(FS_NODUMP_FL)) || \
+      (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
+        && defined(EXT2_NODUMP_FL))
 int
 canNodump(void)
 {
@@ -2265,22 +2288,48 @@ canNodump(void)
        fd = open(path, O_RDONLY | O_NONBLOCK);
        if (fd < 0)
                return (0);
-       r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+       r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+           FS_IOC_GETFLAGS,
+#else
+           EXT2_IOC_GETFLAGS,
+#endif
+           &flags);
        if (r < 0)
                return (0);
+#ifdef FS_NODUMP_FL
+       flags |= FS_NODUMP_FL;
+#else
        flags |= EXT2_NODUMP_FL;
-       r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+#endif
+       r = ioctl(fd,
+#ifdef FS_IOC_SETFLAGS
+           FS_IOC_SETFLAGS,
+#else
+           EXT2_IOC_SETFLAGS,
+#endif
+          &flags);
        if (r < 0)
                return (0);
        close(fd);
        fd = open(path, O_RDONLY | O_NONBLOCK);
        if (fd < 0)
                return (0);
-       r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+       r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+           FS_IOC_GETFLAGS,
+#else
+           EXT2_IOC_GETFLAGS,
+#endif
+           &flags);
        if (r < 0)
                return (0);
        close(fd);
+#ifdef FS_NODUMP_FL
+       if (flags & FS_NODUMP_FL)
+#else
        if (flags & EXT2_NODUMP_FL)
+#endif
                return (1);
        return (0);
 }