Module Name: src Committed By: hannken Date: Sat Jan 12 10:43:33 UTC 2019
Modified Files: src/external/cddl/osnet/dist/uts/common/fs/zfs: zfs_ioctl.c zfs_onexit.c Log Message: The ZFS onexit routines expect opening ZFS_DEV with O_EXCL to return a cloned device with an unique minor number. Use fd_clone() on this condition to return a cloned device descriptor. To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c cvs rdiff -u -r1.2 -r1.3 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_onexit.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c:1.14 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c:1.15 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c:1.14 Tue Jan 1 10:08:01 2019 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c Sat Jan 12 10:43:33 2019 @@ -6205,6 +6205,8 @@ zfs_ctldev_init(dev_t *devp) #ifdef __FreeBSD__ devfs_set_cdevpriv((void *)(uintptr_t)minor, zfsdev_close); +#else + *devp = makedev(major(*devp), minor); #endif zs = ddi_get_soft_state(zfsdev_state, minor); @@ -6973,11 +6975,52 @@ MODULE_DEPEND(zfsctrl, acl_nfs4, 1, 1, 1 MODULE(MODULE_CLASS_DRIVER, zfs, "solaris"); +static const struct fileops zfs_fileops; + +static int +nb_zfsdev_fioctl(struct file *fp, u_long cmd, void *argp) +{ + dev_t dev = (dev_t)(uintptr_t)fp->f_data; + int rval; + + return zfsdev_ioctl(dev, cmd, (intptr_t)argp, fp->f_flag, + kauth_cred_get(), &rval); +} + +static int +nb_zfsdev_fclose(struct file *fp) +{ + dev_t dev = (dev_t)(uintptr_t)fp->f_data; + int error; + + return zfsdev_close(dev, fp->f_flag, OTYPCHR, fp->f_cred); +} + static int nb_zfsdev_copen(dev_t dev, int flag, int mode, lwp_t *l) { + const bool must_clone = (getminor(dev) == 0 && (flag & FEXCL) != 0); + struct file *fp; + int error, fd; + + if (must_clone) { + error = fd_allocfile(&fp, &fd); + if (error) + return error; + } + + error = zfsdev_open(&dev, flag, OTYPCHR, kauth_cred_get()); - return zfsdev_open(&dev, flag, OTYPCHR, kauth_cred_get()); + if (must_clone) { + if (error) { + fd_abort(curproc, fp, fd); + return error; + } + return fd_clone(fp, fd, flag, &zfs_fileops, + (void *)(uintptr_t)dev); + } + + return error; } static int @@ -7031,6 +7074,19 @@ nb_zvol_strategy(struct buf *bp) (void) zvol_strategy(bp); } +static const struct fileops zfs_fileops = { + .fo_name = "zfs", + .fo_read = fbadop_read, + .fo_write = fbadop_write, + .fo_ioctl = nb_zfsdev_fioctl, + .fo_fcntl = fnullop_fcntl, + .fo_poll = fnullop_poll, + .fo_stat = fbadop_stat, + .fo_close = nb_zfsdev_fclose, + .fo_kqfilter = fnullop_kqfilter, + .fo_restart = fnullop_restart, +}; + const struct bdevsw zfs_bdevsw = { .d_open = nb_zfsdev_bopen, .d_close = nb_zfsdev_bclose, Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_onexit.c diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_onexit.c:1.2 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_onexit.c:1.3 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_onexit.c:1.2 Mon May 28 21:05:07 2018 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_onexit.c Sat Jan 12 10:43:33 2019 @@ -146,7 +146,8 @@ zfs_onexit_fd_hold(int fd, minor_t *mino if (fp == NULL) return (SET_ERROR(EBADF)); - *minorp = getminor(fp->f_vnode->v_rdev); + ASSERT(strcmp(fp->f_ops->fo_name, "zfs") == 0); + *minorp = minor((dev_t)(uintptr_t)fp->f_data); #endif return (zfs_onexit_minor_to_state(*minorp, &zo));