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));