Index: kern/vfs_mount.c =================================================================== --- kern/vfs_mount.c +++ kern/vfs_mount.c @@ -110,6 +110,7 @@ "rw", "nosuid", "noexec", + "fsid", NULL }; @@ -838,6 +839,9 @@ struct mount *mp; struct vnode *newdp; int error; + uint64_t fsidval; + char *fsidstr, *fsidend; + int fsidlen; ASSERT_VOP_ELOCKED(vp, __func__); KASSERT((fsflags & MNT_UPDATE) == 0, ("MNT_UPDATE shouldn't be here")); @@ -890,6 +894,28 @@ * get. No freeing of cn_pnbuf. */ error = VFS_MOUNT(mp); + + /* + * Set the fsid if the mount option was specified. + */ + if (error == 0) { + fsidlen = 0; + error = vfs_getopt(mp->mnt_optnew, "fsid", (void **)&fsidstr, + &fsidlen); + if (error == 0) { + if (fsidlen == 0 || fsidstr[fsidlen - 1] != '\0') + error = EINVAL; + if (error == 0) { + fsidval = strtouq(fsidstr, &fsidend, 0); + if (*fsidend != '\0') + error = EINVAL; + } + if (error == 0) + error = vfs_setfsid(mp, fsidval); + } else + error = 0; + } + if (error != 0) { vfs_unbusy(mp); mp->mnt_vnodecovered = NULL; Index: kern/vfs_subr.c =================================================================== --- kern/vfs_subr.c +++ kern/vfs_subr.c @@ -769,6 +769,37 @@ } /* + * Set the f_fsid to the argument, if possible. + */ +int +vfs_setfsid(struct mount *mp, uint64_t val) +{ + struct mount *nmp; + fsid_t tfsid; + + CTR2(KTR_VFS, "%s: mp %p", __func__, mp); + /* + * Fill in the two 32bit fields of the fsid to "val". + */ + tfsid.val[0] = val; + tfsid.val[1] = val >> 32; + mtx_lock(&mntid_mtx); + if ((nmp = vfs_getvfs(&tfsid)) != NULL) { + vfs_rel(nmp); + mtx_unlock(&mntid_mtx); + if (nmp != mp) + return (EINVAL); + return (0); + } + MNT_ILOCK(mp); + mp->mnt_stat.f_fsid.val[0] = tfsid.val[0]; + mp->mnt_stat.f_fsid.val[1] = tfsid.val[1]; + MNT_IUNLOCK(mp); + mtx_unlock(&mntid_mtx); + return (0); +} + +/* * Knob to control the precision of file timestamps: * * 0 = seconds only; nanoseconds zeroed. Index: sys/mount.h =================================================================== --- sys/mount.h +++ sys/mount.h @@ -918,6 +918,7 @@ int vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions); void vfs_getnewfsid(struct mount *); +int vfs_setfsid(struct mount *, uint64_t); struct cdev *vfs_getrootfsid(struct mount *); struct mount *vfs_getvfs(fsid_t *); /* return vfs given fsid */ struct mount *vfs_busyfs(fsid_t *);