Hi,

It may be useful for users to know which ext2fs features are not supported.
This patch adds more verbose messages mostly based on FreeBSD's r320578.

w/o patch:
ext2fs: unsupported incompat features 0x2c2

w/ patch:
ext2fs: unsupported incompat features: 64bit

Index: sys/ufs/ext2fs/ext2fs.h
===================================================================
RCS file: /cvs/src/sys/ufs/ext2fs/ext2fs.h,v
retrieving revision 1.23
diff -u -p -u -p -r1.23 ext2fs.h
--- sys/ufs/ext2fs/ext2fs.h     27 Apr 2016 11:27:24 -0000      1.23
+++ sys/ufs/ext2fs/ext2fs.h     28 Jun 2019 05:36:15 -0000
@@ -195,15 +195,25 @@ e2fs_overflow(struct m_ext2fs *fs, off_t
 
 /* compatible/imcompatible features */
 #define EXT2F_COMPAT_PREALLOC          0x0001
-#define EXT2F_COMPAT_HASJOURNAL                0x0004
+#define EXT2F_COMPAT_IMAGIC_INODES     0x0002
+#define EXT2F_COMPAT_HAS_JOURNAL       0x0004
+#define EXT2F_COMPAT_EXT_ATTR          0x0008
 #define EXT2F_COMPAT_RESIZE            0x0010
-#define EXT2F_COMPAT_DIRHASHINDEX      0x0020
+#define EXT2F_COMPAT_DIR_INDEX         0x0020
+#define EXT2F_COMPAT_SPARSE_SUPER2     0x0200
 
-
-#define EXT2F_ROCOMPAT_SPARSESUPER     0x0001
-#define EXT2F_ROCOMPAT_LARGEFILE       0x0002
+#define EXT2F_ROCOMPAT_SPARSE_SUPER    0x0001
+#define EXT2F_ROCOMPAT_LARGE_FILE      0x0002
 #define EXT2F_ROCOMPAT_BTREE_DIR       0x0004
 #define EXT2F_ROCOMPAT_HUGE_FILE       0x0008
+#define EXT2F_ROCOMPAT_GDT_CSUM                0x0010
+#define EXT2F_ROCOMPAT_DIR_NLINK       0x0020
+#define EXT2F_ROCOMPAT_EXTRA_ISIZE     0x0040
+#define EXT2F_ROCOMPAT_QUOTA           0x0100
+#define EXT2F_ROCOMPAT_BIGALLOC                0x0200
+#define EXT2F_ROCOMPAT_METADATA_CKSUM  0x0400
+#define EXT2F_ROCOMPAT_READONLY                0x1000
+#define EXT2F_ROCOMPAT_PROJECT         0x2000
 
 #define EXT2F_INCOMPAT_COMP            0x0001
 #define EXT2F_INCOMPAT_FTYPE           0x0002
@@ -211,12 +221,58 @@ e2fs_overflow(struct m_ext2fs *fs, off_t
 #define EXT2F_INCOMPAT_JOURNAL_DEV     0x0008
 #define EXT2F_INCOMPAT_META_BG         0x0010
 #define EXT2F_INCOMPAT_EXTENTS         0x0040
+#define EXT2F_INCOMPAT_64BIT           0x0080
+#define EXT2F_INCOMPAT_MMP             0x0100
 #define EXT2F_INCOMPAT_FLEX_BG         0x0200
+#define EXT2F_INCOMPAT_EA_INODE                0x0400
+#define EXT2F_INCOMPAT_DIRDATA         0x1000
+#define EXT2F_INCOMPAT_CSUM_SEED       0x2000
+#define EXT2F_INCOMPAT_LARGEDIR                0x4000
+#define EXT2F_INCOMPAT_INLINE_DATA     0x8000
+#define EXT2F_INCOMPAT_ENCRYPT         0x10000
+
+struct ext2_feature {
+       uint32_t mask;
+       const char *name;
+};
+
+static const struct ext2_feature ro_compat[] = {
+       { EXT2F_ROCOMPAT_SPARSE_SUPER,          "sparse_super" },
+       { EXT2F_ROCOMPAT_LARGE_FILE,            "large_file" },
+       { EXT2F_ROCOMPAT_BTREE_DIR,             "btree_dir" },
+       { EXT2F_ROCOMPAT_HUGE_FILE,             "huge_file" },
+       { EXT2F_ROCOMPAT_GDT_CSUM,              "uninit_bg" },
+       { EXT2F_ROCOMPAT_DIR_NLINK,             "dir_nlink" },
+       { EXT2F_ROCOMPAT_EXTRA_ISIZE,           "extra_isize" },
+       { EXT2F_ROCOMPAT_QUOTA,                 "quota" },
+       { EXT2F_ROCOMPAT_BIGALLOC,              "bigalloc" },
+       { EXT2F_ROCOMPAT_METADATA_CKSUM,        "metadata_csum" },
+       { EXT2F_ROCOMPAT_READONLY,              "read-only" },
+       { EXT2F_ROCOMPAT_PROJECT,               "project" }
+};
+
+static const struct ext2_feature incompat[] = {
+       { EXT2F_INCOMPAT_COMP,          "compression" },
+       { EXT2F_INCOMPAT_FTYPE,         "filetype" },
+       { EXT2F_INCOMPAT_RECOVER,       "needs_recovery" },
+       { EXT2F_INCOMPAT_JOURNAL_DEV,   "journal_dev" },
+       { EXT2F_INCOMPAT_META_BG,       "meta_bg" },
+       { EXT2F_INCOMPAT_EXTENTS,       "extents" },
+       { EXT2F_INCOMPAT_64BIT,         "64bit" },
+       { EXT2F_INCOMPAT_MMP,           "mmp" },
+       { EXT2F_INCOMPAT_FLEX_BG,       "flex_bg" },
+       { EXT2F_INCOMPAT_EA_INODE,      "ea_inode" },
+       { EXT2F_INCOMPAT_DIRDATA,       "dirdata" },
+       { EXT2F_INCOMPAT_CSUM_SEED,     "metadata_csum_seed" },
+       { EXT2F_INCOMPAT_LARGEDIR,      "large_dir" },
+       { EXT2F_INCOMPAT_INLINE_DATA,   "inline_data" },
+       { EXT2F_INCOMPAT_ENCRYPT,       "encrypt" }
+};
 
 /* features supported in this implementation */
 #define EXT2F_COMPAT_SUPP              0x0000
-#define EXT2F_ROCOMPAT_SUPP            (EXT2F_ROCOMPAT_SPARSESUPER | \
-                                        EXT2F_ROCOMPAT_LARGEFILE)
+#define EXT2F_ROCOMPAT_SUPP            (EXT2F_ROCOMPAT_SPARSE_SUPER | \
+                                        EXT2F_ROCOMPAT_LARGE_FILE)
 #define EXT2F_INCOMPAT_SUPP            (EXT2F_INCOMPAT_FTYPE)
 #define EXT4F_RO_INCOMPAT_SUPP         (EXT2F_INCOMPAT_EXTENTS | \
                                         EXT2F_INCOMPAT_FLEX_BG | \
@@ -258,7 +314,7 @@ struct ext2_gd {
 };
 
 /*
- * If the EXT2F_ROCOMPAT_SPARSESUPER flag is set, the cylinder group has a
+ * If the EXT2F_ROCOMPAT_SPARSE_SUPER flag is set, the cylinder group has a
  * copy of the super and cylinder group descriptors blocks only if it's
  * a power of 3, 5 or 7
  */
Index: sys/ufs/ext2fs/ext2fs_inode.c
===================================================================
RCS file: /cvs/src/sys/ufs/ext2fs/ext2fs_inode.c,v
retrieving revision 1.59
diff -u -p -u -p -r1.59 ext2fs_inode.c
--- sys/ufs/ext2fs/ext2fs_inode.c       28 Apr 2018 03:13:05 -0000      1.59
+++ sys/ufs/ext2fs/ext2fs_inode.c       28 Jun 2019 05:36:15 -0000
@@ -87,8 +87,8 @@ ext2fs_setsize(struct inode *ip, u_int64
        if (fs->e2fs.e2fs_rev <= E2FS_REV0)
                return (EFBIG);
 
-       if ((fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_LARGEFILE) == 0) {
-               fs->e2fs.e2fs_features_rocompat |= EXT2F_ROCOMPAT_LARGEFILE;
+       if (!(fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_LARGE_FILE)) {
+               fs->e2fs.e2fs_features_rocompat |= EXT2F_ROCOMPAT_LARGE_FILE;
                fs->e2fs_fmod = 1;
        }
        return (EFBIG);
Index: sys/ufs/ext2fs/ext2fs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.110
diff -u -p -u -p -r1.110 ext2fs_vfsops.c
--- sys/ufs/ext2fs/ext2fs_vfsops.c      26 Sep 2018 14:51:44 -0000      1.110
+++ sys/ufs/ext2fs/ext2fs_vfsops.c      28 Jun 2019 05:36:15 -0000
@@ -400,7 +400,7 @@ e2fs_sbfill(struct vnode *devvp, struct 
                bp = NULL;
        }
 
-       if ((fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_LARGEFILE) == 0 ||
+       if (!(fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_LARGE_FILE) ||
            (fs->e2fs.e2fs_rev == E2FS_REV0))
                fs->e2fs_maxfilesize = INT_MAX;
        else
@@ -674,7 +674,7 @@ ext2fs_statfs(struct mount *mp, struct s
        overhead = fs->e2fs.e2fs_first_dblock +
            fs->e2fs_ncg * overhead_per_group;
        if (fs->e2fs.e2fs_rev > E2FS_REV0 &&
-           fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSESUPER) {
+           fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSE_SUPER) {
                for (i = 0, ngroups = 0; i < fs->e2fs_ncg; i++) {
                        if (cg_has_sb(i))
                                ngroups++;
@@ -1072,7 +1072,8 @@ ext2fs_cgupdate(struct ufsmount *mp, int
 static int
 e2fs_sbcheck(struct ext2fs *fs, int ronly)
 {
-       u_int32_t tmp;
+       u_int32_t mask, tmp;
+       int i;
 
        tmp = letoh16(fs->e2fs_magic);
        if (tmp != E2FS_MAGIC) {
@@ -1108,8 +1109,13 @@ e2fs_sbcheck(struct ext2fs *fs, int ronl
        }
 
        tmp = letoh32(fs->e2fs_features_incompat);
-       if (tmp & ~(EXT2F_INCOMPAT_SUPP | EXT4F_RO_INCOMPAT_SUPP)) {
-               printf("ext2fs: unsupported incompat features 0x%x\n", tmp);
+       mask = tmp & ~(EXT2F_INCOMPAT_SUPP | EXT4F_RO_INCOMPAT_SUPP);
+       if (mask) {
+               printf("ext2fs: unsupported incompat features: ");
+               for (i = 0; i < nitems(incompat); i++)
+                       if (mask & incompat[i].mask)
+                               printf("%s ", incompat[i].name);
+               printf("\n");
                return (EINVAL);      /* XXX needs translation */
        }
 
@@ -1124,9 +1130,13 @@ e2fs_sbcheck(struct ext2fs *fs, int ronl
                        return (EROFS); /* XXX needs translation */
        }
 
-       tmp = letoh32(fs->e2fs_features_rocompat);
-       if (!ronly && (tmp & ~EXT2F_ROCOMPAT_SUPP)) {
-               printf("ext2fs: unsupported R/O compat features 0x%x\n", tmp);
+       tmp = letoh32(fs->e2fs_features_rocompat) & ~EXT2F_ROCOMPAT_SUPP;
+       if (!ronly && tmp) {
+               printf("ext2fs: unsupported R/O compat features: ");
+               for (i = 0; i < nitems(ro_compat); i++)
+                       if (tmp & ro_compat[i].mask)
+                               printf("%s ", ro_compat[i].name);
+               printf("\n");
                return (EROFS);      /* XXX needs translation */
        }
 

Reply via email to