Index: sys/fs/ext2fs/ext2_vfsops.c =================================================================== --- sys/fs/ext2fs/ext2_vfsops.c +++ sys/fs/ext2fs/ext2_vfsops.c @@ -279,6 +279,7 @@ static int ext2_check_sb_compat(struct ext2fs *es, struct cdev *dev, int ronly) { + uint32_t i, mask; if (es->e2fs_magic != E2FS_MAGIC) { printf("ext2fs: %s: wrong magic number %#x (expected %#x)\n", @@ -286,17 +287,25 @@ return (1); } if (es->e2fs_rev > E2FS_REV0) { - if (es->e2fs_features_incompat & ~(EXT2F_INCOMPAT_SUPP | - EXT4F_RO_INCOMPAT_SUPP)) { - printf( -"WARNING: mount of %s denied due to unsupported optional features\n", - devtoname(dev)); + mask = es->e2fs_features_incompat & ~(EXT2F_INCOMPAT_SUPP | + EXT4F_RO_INCOMPAT_SUPP); + if (mask) { + printf("WARNING: mount of %s denied due to " + "unsupported optional features:\n", devtoname(dev)); + for (i = 0; i < nitems(incompat_names); i++) + if (mask & incompat_names[i].mask) + printf("%s ", incompat_names[i].name); + printf("\n"); return (1); } - if (!ronly && - (es->e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP)) { + mask = es->e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP; + if (!ronly && mask) { printf("WARNING: R/W mount of %s denied due to " - "unsupported optional features\n", devtoname(dev)); + "unsupported optional features:\n", devtoname(dev)); + for (i = 0; i < nitems(ro_compat_names); i++) + if (mask & ro_compat_names[i].mask) + printf("%s ", ro_compat_names[i].name); + printf("\n"); return (1); } } Index: sys/fs/ext2fs/ext2fs.h =================================================================== --- sys/fs/ext2fs/ext2fs.h +++ sys/fs/ext2fs/ext2fs.h @@ -202,40 +202,104 @@ /* * compatible/incompatible features */ -#define EXT2F_COMPAT_PREALLOC 0x0001 -#define EXT2F_COMPAT_HASJOURNAL 0x0004 -#define EXT2F_COMPAT_EXT_ATTR 0x0008 -#define EXT2F_COMPAT_RESIZE 0x0010 -#define EXT2F_COMPAT_DIRHASHINDEX 0x0020 -#define EXT2F_COMPAT_SPARSESUPER2 0x0200 - -#define EXT2F_ROCOMPAT_SPARSESUPER 0x0001 -#define EXT2F_ROCOMPAT_LARGEFILE 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 -#define EXT2F_INCOMPAT_RECOVER 0x0004 -#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 +typedef enum { + EXT2F_COMPAT_PREALLOC = 0x0001, + EXT2F_COMPAT_IMAGIC_INODES = 0x0002, + EXT2F_COMPAT_HASJOURNAL = 0x0004, + EXT2F_COMPAT_EXT_ATTR = 0x0008, + EXT2F_COMPAT_RESIZE = 0x0010, + EXT2F_COMPAT_DIRHASHINDEX = 0x0020, + EXT2F_COMPAT_LAZY_BG = 0x0040, + EXT2F_COMPAT_EXCLUDE_BITMAP = 0x0100, + EXT2F_COMPAT_SPARSESUPER2 = 0x0200 +} compat; + +typedef enum { + EXT2F_ROCOMPAT_SPARSESUPER = 0x0001, + EXT2F_ROCOMPAT_LARGEFILE = 0x0002, + EXT2F_ROCOMPAT_BTREE_DIR = 0x0004, + EXT2F_ROCOMPAT_HUGE_FILE = 0x0008, + EXT2F_ROCOMPAT_GDT_CSUM = 0x0010, + EXT2F_ROCOMPAT_DIR_NLINK = 0x0020, + EXT2F_ROCOMPAT_EXTRA_ISIZE = 0x0040, + EXT2F_ROCOMPAT_HAS_SNAPSHOT = 0x0080, + EXT2F_ROCOMPAT_QUOTA = 0x0100, + EXT2F_ROCOMPAT_BIGALLOC = 0x0200, + EXT2F_ROCOMPAT_METADATA_CKSUM = 0x0400, + EXT2F_ROCOMPAT_REPLICA = 0x0800, + EXT2F_ROCOMPAT_READONLY = 0x1000, + EXT2F_ROCOMPAT_PROJECT = 0x2000 +} ro_compat; + +typedef enum { + EXT2F_INCOMPAT_COMP = 0x0001, + EXT2F_INCOMPAT_FTYPE = 0x0002, + EXT2F_INCOMPAT_RECOVER = 0x0004, + EXT2F_INCOMPAT_JOURNAL_DEV = 0x0008, + EXT2F_INCOMPAT_META_BG = 0x0010, + EXT2F_INCOMPAT_EXTENTS = 0x0040, + EXT2F_INCOMPAT_64BIT = 0x0080, + EXT2F_INCOMPAT_MMP = 0x0100, + EXT2F_INCOMPAT_FLEX_BG = 0x0200, + EXT2F_INCOMPAT_EA_INODE = 0x0400, + EXT2F_INCOMPAT_DIRDATA = 0x1000, + EXT2F_INCOMPAT_CSUM_SEED = 0x2000, + EXT2F_INCOMPAT_LARGEDIR = 0x4000, + EXT2F_INCOMPAT_INLINE_DATA = 0x8000, + EXT2F_INCOMPAT_ENCRYPT = 0x10000 +} incompat; + +struct ext2_feature +{ + int mask; + const char *name; +}; + +static const struct ext2_feature compat_names[] = { + { EXT2F_COMPAT_PREALLOC, "dir_prealloc" }, + { EXT2F_COMPAT_IMAGIC_INODES, "imagic_inodes" }, + { EXT2F_COMPAT_HASJOURNAL, "has_journal" }, + { EXT2F_COMPAT_EXT_ATTR, "ext_attr" }, + { EXT2F_COMPAT_RESIZE, "resize_inode" }, + { EXT2F_COMPAT_DIRHASHINDEX, "dir_index" }, + { EXT2F_COMPAT_EXCLUDE_BITMAP, "snapshot_bitmap" }, + { EXT2F_COMPAT_SPARSESUPER2, "sparse_super2" } +}; + +static const struct ext2_feature ro_compat_names[] = { + { EXT2F_ROCOMPAT_SPARSESUPER, "sparse_super" }, + { EXT2F_ROCOMPAT_LARGEFILE, "large_file" }, + { EXT2F_ROCOMPAT_BTREE_DIR, "btree_dir" }, + { EXT2F_ROCOMPAT_HUGE_FILE, "huge_file" }, + { EXT2F_ROCOMPAT_GDT_CSUM, "uninit_groups" }, + { EXT2F_ROCOMPAT_DIR_NLINK, "dir_nlink" }, + { EXT2F_ROCOMPAT_EXTRA_ISIZE, "extra_isize" }, + { EXT2F_ROCOMPAT_HAS_SNAPSHOT, "snapshot" }, + { EXT2F_ROCOMPAT_QUOTA, "quota" }, + { EXT2F_ROCOMPAT_BIGALLOC, "bigalloc" }, + { EXT2F_ROCOMPAT_METADATA_CKSUM, "metadata_csum" }, + { EXT2F_ROCOMPAT_REPLICA, "replica" }, + { EXT2F_ROCOMPAT_READONLY, "ro" }, + { EXT2F_ROCOMPAT_PROJECT, "project" } +}; + +static const struct ext2_feature incompat_names[] = { + { 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