diff --git a/sys/compat/lindebugfs/lindebugfs.c b/sys/compat/lindebugfs/lindebugfs.c --- a/sys/compat/lindebugfs/lindebugfs.c +++ b/sys/compat/lindebugfs/lindebugfs.c @@ -658,5 +658,5 @@ return (0); } -PSEUDOFS(lindebugfs, 1, VFCF_JAIL); +PSEUDOFS(lindebugfs, 1, VFCF_JAIL, VFS_KPI_VERSION_1); MODULE_DEPEND(lindebugfs, linuxkpi, 1, 1, 1); diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -2269,7 +2269,7 @@ return (0); } -PSEUDOFS(linprocfs, 1, VFCF_JAIL); +PSEUDOFS(linprocfs, 1, VFCF_JAIL, VFS_KPI_VERSION_1); #if defined(__aarch64__) || defined(__amd64__) MODULE_DEPEND(linprocfs, linux_common, 1, 1, 1); #else diff --git a/sys/compat/linsysfs/linsysfs.c b/sys/compat/linsysfs/linsysfs.c --- a/sys/compat/linsysfs/linsysfs.c +++ b/sys/compat/linsysfs/linsysfs.c @@ -560,7 +560,7 @@ return (0); } -PSEUDOFS(linsysfs, 1, VFCF_JAIL); +PSEUDOFS(linsysfs, 1, VFCF_JAIL, VFS_KPI_VERSION_1); #if defined(__aarch64__) || defined(__amd64__) MODULE_DEPEND(linsysfs, linux_common, 1, 1, 1); #else diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c @@ -159,9 +159,9 @@ #ifdef VFCF_CROSS_COPY_FILE_RANGE VFS_SET(zfs_vfsops, zfs, - VFCF_DELEGADMIN | VFCF_JAIL | VFCF_CROSS_COPY_FILE_RANGE); + VFCF_DELEGADMIN | VFCF_JAIL | VFCF_CROSS_COPY_FILE_RANGE, VFS_KPI_VERSION_1); #else -VFS_SET(zfs_vfsops, zfs, VFCF_DELEGADMIN | VFCF_JAIL); +VFS_SET(zfs_vfsops, zfs, VFCF_DELEGADMIN | VFCF_JAIL, VFS_KPI_VERSION_1); #endif /* diff --git a/sys/fs/autofs/autofs_vfsops.c b/sys/fs/autofs/autofs_vfsops.c --- a/sys/fs/autofs/autofs_vfsops.c +++ b/sys/fs/autofs/autofs_vfsops.c @@ -216,5 +216,5 @@ .vfs_uninit = autofs_uninit, }; -VFS_SET(autofs_vfsops, autofs, VFCF_SYNTHETIC | VFCF_NETWORK); +VFS_SET(autofs_vfsops, autofs, VFCF_SYNTHETIC | VFCF_NETWORK, VFS_KPI_VERSION_1); MODULE_VERSION(autofs, 1); diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c --- a/sys/fs/cd9660/cd9660_vfsops.c +++ b/sys/fs/cd9660/cd9660_vfsops.c @@ -87,7 +87,7 @@ .vfs_unmount = cd9660_unmount, .vfs_vget = cd9660_vget, }; -VFS_SET(cd9660_vfsops, cd9660, VFCF_READONLY); +VFS_SET(cd9660_vfsops, cd9660, VFCF_READONLY, VFS_KPI_VERSION_1); MODULE_VERSION(cd9660, 1); static int cd9660_vfs_hash_cmp(struct vnode *vp, void *pino); diff --git a/sys/fs/devfs/devfs_vfsops.c b/sys/fs/devfs/devfs_vfsops.c --- a/sys/fs/devfs/devfs_vfsops.c +++ b/sys/fs/devfs/devfs_vfsops.c @@ -245,4 +245,4 @@ .vfs_unmount = devfs_unmount, }; -VFS_SET(devfs_vfsops, devfs, VFCF_SYNTHETIC | VFCF_JAIL); +VFS_SET(devfs_vfsops, devfs, VFCF_SYNTHETIC | VFCF_JAIL, VFS_KPI_VERSION_1); diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c --- a/sys/fs/ext2fs/ext2_vfsops.c +++ b/sys/fs/ext2fs/ext2_vfsops.c @@ -104,7 +104,7 @@ .vfs_vget = ext2_vget, }; -VFS_SET(ext2fs_vfsops, ext2fs, 0); +VFS_SET(ext2fs_vfsops, ext2fs, 0, VFS_KPI_VERSION_1); static int ext2_check_sb_compat(struct ext2fs *es, struct cdev *dev, int ronly); diff --git a/sys/fs/fdescfs/fdesc_vfsops.c b/sys/fs/fdescfs/fdesc_vfsops.c --- a/sys/fs/fdescfs/fdesc_vfsops.c +++ b/sys/fs/fdescfs/fdesc_vfsops.c @@ -240,4 +240,4 @@ .vfs_unmount = fdesc_unmount, }; -VFS_SET(fdesc_vfsops, fdescfs, VFCF_SYNTHETIC | VFCF_JAIL); +VFS_SET(fdesc_vfsops, fdescfs, VFCF_SYNTHETIC | VFCF_JAIL, VFS_KPI_VERSION_1); diff --git a/sys/fs/fuse/fuse_main.c b/sys/fs/fuse/fuse_main.c --- a/sys/fs/fuse/fuse_main.c +++ b/sys/fs/fuse/fuse_main.c @@ -98,7 +98,8 @@ extern struct vop_vector fuse_fifonops; static struct vfsconf fuse_vfsconf = { - .vfc_version = VFS_VERSION, + .vfc_kbi_version = VFS_KBI_VERSION, + .vfc_kpi_version = VFS_KPI_VERSION_1, .vfc_name = "fusefs", .vfc_vfsops = &fuse_vfsops, .vfc_typenum = -1, diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -1195,5 +1195,5 @@ .vfs_unmount = msdosfs_unmount, }; -VFS_SET(msdosfs_vfsops, msdosfs, 0); +VFS_SET(msdosfs_vfsops, msdosfs, 0, VFS_KPI_VERSION_1); MODULE_VERSION(msdosfs, 1); diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -155,7 +155,7 @@ * for "nfscl" and is needed so that a custom event handling * function gets called. MODULE_DEPEND() macros are found there. */ -VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY); +VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY, VFS_KPI_VERSION_1); MODULE_VERSION(nfs, 1); diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c --- a/sys/fs/nullfs/null_vfsops.c +++ b/sys/fs/nullfs/null_vfsops.c @@ -488,4 +488,4 @@ .vfs_unlink_lowervp = nullfs_unlink_lowervp, }; -VFS_SET(null_vfsops, nullfs, VFCF_LOOPBACK | VFCF_JAIL | VFCF_FILEMOUNT); +VFS_SET(null_vfsops, nullfs, VFCF_LOOPBACK | VFCF_JAIL | VFCF_FILEMOUNT, VFS_KPI_VERSION_1); diff --git a/sys/fs/procfs/procfs.c b/sys/fs/procfs/procfs.c --- a/sys/fs/procfs/procfs.c +++ b/sys/fs/procfs/procfs.c @@ -206,4 +206,4 @@ return (0); } -PSEUDOFS(procfs, 1, VFCF_JAIL); +PSEUDOFS(procfs, 1, VFCF_JAIL, VFS_KPI_VERSION_1); diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h --- a/sys/fs/pseudofs/pseudofs.h +++ b/sys/fs/pseudofs/pseudofs.h @@ -275,7 +275,7 @@ /* * Now for some initialization magic... */ -#define PSEUDOFS(name, version, flags) \ +#define PSEUDOFS(name, version, flags, kpi_version) \ \ static struct pfs_info name##_info = { \ #name, \ @@ -307,7 +307,7 @@ .vfs_uninit = _##name##_uninit, \ .vfs_unmount = pfs_unmount, \ }; \ -VFS_SET(name##_vfsops, name, VFCF_SYNTHETIC | flags); \ +VFS_SET(name##_vfsops, name, VFCF_SYNTHETIC | flags, kpi_version); \ MODULE_VERSION(name, version); \ MODULE_DEPEND(name, pseudofs, 1, 1, 1); diff --git a/sys/fs/smbfs/smbfs_vfsops.c b/sys/fs/smbfs/smbfs_vfsops.c --- a/sys/fs/smbfs/smbfs_vfsops.c +++ b/sys/fs/smbfs/smbfs_vfsops.c @@ -81,7 +81,7 @@ .vfs_unmount = smbfs_unmount, }; -VFS_SET(smbfs_vfsops, smbfs, VFCF_NETWORK); +VFS_SET(smbfs_vfsops, smbfs, VFCF_NETWORK, VFS_KPI_VERSION_1); MODULE_DEPEND(smbfs, netsmb, NSMB_VERSION, NSMB_VERSION, NSMB_VERSION); MODULE_DEPEND(smbfs, libiconv, 1, 1, 2); diff --git a/sys/fs/tarfs/tarfs_vfsops.c b/sys/fs/tarfs/tarfs_vfsops.c --- a/sys/fs/tarfs/tarfs_vfsops.c +++ b/sys/fs/tarfs/tarfs_vfsops.c @@ -1209,6 +1209,6 @@ .vfs_unmount = tarfs_unmount, .vfs_vget = tarfs_vget, }; -VFS_SET(tarfs_vfsops, tarfs, VFCF_READONLY); +VFS_SET(tarfs_vfsops, tarfs, VFCF_READONLY, VFS_KPI_VERSION_1); MODULE_VERSION(tarfs, 1); MODULE_DEPEND(tarfs, xz, 1, 1, 1); diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -704,7 +704,7 @@ .vfs_init = tmpfs_init, .vfs_uninit = tmpfs_uninit, }; -VFS_SET(tmpfs_vfsops, tmpfs, VFCF_JAIL); +VFS_SET(tmpfs_vfsops, tmpfs, VFCF_JAIL, VFS_KPI_VERSION_1); #ifdef DDB #include diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c --- a/sys/fs/udf/udf_vfsops.c +++ b/sys/fs/udf/udf_vfsops.c @@ -132,7 +132,7 @@ .vfs_unmount = udf_unmount, .vfs_vget = udf_vget, }; -VFS_SET(udf_vfsops, udf, VFCF_READONLY); +VFS_SET(udf_vfsops, udf, VFCF_READONLY, VFS_KPI_VERSION_1); MODULE_VERSION(udf, 1); diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c --- a/sys/fs/unionfs/union_vfsops.c +++ b/sys/fs/unionfs/union_vfsops.c @@ -584,4 +584,4 @@ .vfs_vget = unionfs_vget, }; -VFS_SET(unionfs_vfsops, unionfs, VFCF_LOOPBACK); +VFS_SET(unionfs_vfsops, unionfs, VFCF_LOOPBACK, VFS_KPI_VERSION_1); diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -2697,7 +2697,8 @@ }; static struct vfsconf mqueuefs_vfsconf = { - .vfc_version = VFS_VERSION, + .vfc_kbi_version = VFS_KBI_VERSION, + .vfc_kpi_version = VFS_KPI_VERSION_1, .vfc_name = "mqueuefs", .vfc_vfsops = &mqfs_vfsops, .vfc_typenum = -1, diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -399,11 +399,18 @@ once = 1; } - if (vfc->vfc_version != VFS_VERSION) { - printf("ERROR: filesystem %s, unsupported ABI version %x\n", - vfc->vfc_name, vfc->vfc_version); + if (vfc->vfc_kbi_version != VFS_KBI_VERSION) { + printf("ERROR: ABI version mismatch for filesystem %s (kernel %x, module %x)\n", + vfc->vfc_name, VFS_KBI_VERSION, vfc->vfc_kbi_version); return (EINVAL); } + + if (vfc->vfc_kpi_version != VFS_KPI_VERSION_1) { + printf("ERROR: API version mismatch for filesystem %s (kernel %x, module %x)\n", + vfc->vfc_name, VFS_KPI_VERSION_1, vfc->vfc_kpi_version); + return (EINVAL); + } + vfsconf_lock(); if (vfs_byname_locked(vfc->vfc_name) != NULL) { vfsconf_unlock(); diff --git a/sys/sys/mount.h b/sys/sys/mount.h --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -634,7 +634,8 @@ * XXX: Never change the first two arguments! */ struct vfsconf { - u_int vfc_version; /* ABI version number */ + u_int vfc_kbi_version; /* ABI version number */ + u_int vfc_kpi_version; /* API version number */ char vfc_name[MFSNAMELEN]; /* filesystem type name */ struct vfsops *vfc_vfsops; /* filesystem operations vector */ struct vfsops *vfc_vfsops_sd; /* ... signal-deferred */ @@ -952,14 +953,18 @@ /* * Version numbers. */ -#define VFS_VERSION_00 0x19660120 -#define VFS_VERSION_01 0x20121030 -#define VFS_VERSION_02 0x20180504 -#define VFS_VERSION VFS_VERSION_02 +#define VFS_KBI_VERSION_00 0x19660120 +#define VFS_KBI_VERSION_01 0x20121030 +#define VFS_KBI_VERSION_02 0x20180504 +#define VFS_KBI_VERSION_03 0x20230706 +#define VFS_KBI_VERSION VFS_KBI_VERSION_03 -#define VFS_SET(vfsops, fsname, flags) \ +#define VFS_KPI_VERSION_1 0x20230706 + +#define VFS_SET(vfsops, fsname, flags, kpi_version) \ static struct vfsconf fsname ## _vfsconf = { \ - .vfc_version = VFS_VERSION, \ + .vfc_kbi_version = VFS_KBI_VERSION, \ + .vfc_kpi_version = kpi_version, \ .vfc_name = #fsname, \ .vfc_vfsops = &vfsops, \ .vfc_typenum = -1, \ diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -121,7 +121,7 @@ .vfs_susp_clean = process_deferred_inactive, }; -VFS_SET(ufs_vfsops, ufs, 0); +VFS_SET(ufs_vfsops, ufs, 0, VFS_KPI_VERSION_1); MODULE_VERSION(ufs, 1); static b_strategy_t ffs_geom_strategy;