Module Name: src Committed By: hannken Date: Wed May 22 08:44:49 UTC 2019
Modified Files: src/external/cddl/osnet/dist/uts/common/fs/zfs: zfs_ioctl.c zvol.c src/external/cddl/osnet/sys/kern: ddi.c src/external/cddl/osnet/sys/sys: sunddi.h Log Message: Update ddi environment: - Put device major numbers into "dev_info_t". - Fix an off-by-one in zvol_create_minor(). - When creating a node handle existing nodes and add owner read/write permission. - When removing nodes remove now empty directories. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c cvs rdiff -u -r1.8 -r1.9 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c cvs rdiff -u -r1.6 -r1.7 src/external/cddl/osnet/sys/kern/ddi.c cvs rdiff -u -r1.5 -r1.6 src/external/cddl/osnet/sys/sys/sunddi.h 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.17 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c:1.18 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c:1.17 Tue May 7 08:51:09 2019 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c Wed May 22 08:44:48 2019 @@ -211,11 +211,8 @@ static struct cdev *zfsdev; #endif #ifdef __NetBSD__ -static int zfs_cmajor = -1; -static int zfs_bmajor = -1; -dev_info_t *zfs_dip; - -#define ddi_driver_major(x) zfs_cmajor +static dev_info_t __zfs_devinfo = { -1, -1 }; +dev_info_t *zfs_dip = &__zfs_devinfo; #define zfs_init() /* nothing */ #define zfs_fini() /* nothing */ @@ -7204,8 +7201,8 @@ zfs_modcmd(modcmd_t cmd, void *arg) zfs_ioctl_init(); zfs_sysctl_init(); - error = devsw_attach("zfs", &zfs_bdevsw, &zfs_bmajor, - &zfs_cdevsw, &zfs_cmajor); + error = devsw_attach("zfs", &zfs_bdevsw, &zfs_dip->di_bmajor, + &zfs_cdevsw, &zfs_dip->di_cmajor); if (error != 0) { goto attacherr; } Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c:1.8 src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c:1.9 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c:1.8 Mon May 28 21:05:07 2018 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c Wed May 22 08:44:48 2019 @@ -676,7 +676,7 @@ zvol_create_minor(const char *name) minor_t minor = 0; vnode_t *vp = NULL; char *devpath; - size_t devpathlen = strlen(ZVOL_FULL_DEV_DIR) + strlen(name) + 1; + size_t devpathlen = strlen(ZVOL_FULL_DEV_DIR) + strlen(name) + 2; #endif mutex_enter(&zfsdev_state_lock); Index: src/external/cddl/osnet/sys/kern/ddi.c diff -u src/external/cddl/osnet/sys/kern/ddi.c:1.6 src/external/cddl/osnet/sys/kern/ddi.c:1.7 --- src/external/cddl/osnet/sys/kern/ddi.c:1.6 Mon May 28 21:05:09 2018 +++ src/external/cddl/osnet/sys/kern/ddi.c Wed May 22 08:44:48 2019 @@ -65,6 +65,7 @@ #include <sys/cmn_err.h> #include <sys/namei.h> #include <sys/stat.h> +#include <sys/vnode.h> #include <sys/vfs_syscalls.h> __strong_alias(ddi_strtol,ddi_strtoul) @@ -142,6 +143,50 @@ do_mkdirp(const char *path) return error; } +static void +do_rmdirp(const char *path) +{ + struct pathbuf *pb; + struct nameidata nd; + char *here, *e; + int error; + + here = PNBUF_GET(); + strlcpy(here, path, MAXPATHLEN); + while ((e = strrchr(here, '/')) && e != here) { + *e = '\0'; + pb = pathbuf_create(here); + if (pb == NULL) + break; + /* XXX need do_sys_rmdir()? */ + NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF | TRYEMULROOT, pb); + error = namei(&nd); + if (error) { + pathbuf_destroy(pb); + break; + } + if ((nd.ni_vp->v_vflag & VV_ROOT) || + nd.ni_vp->v_type != VDIR || + nd.ni_vp->v_mountedhere || + nd.ni_vp == nd.ni_dvp) { + VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); + if (nd.ni_vp == nd.ni_dvp) + vrele(nd.ni_dvp); + else + vput(nd.ni_dvp); + vput(nd.ni_vp); + pathbuf_destroy(pb); + break; + } + error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); + vput(nd.ni_dvp); + pathbuf_destroy(pb); + if (error) + break; + } + PNBUF_PUT(here); +} + int ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result) { @@ -562,25 +607,49 @@ ddi_create_minor_node(dev_info_t *dip, c minor_t minor_num, char *node_type, int flag) { struct lwp *l = curlwp; + vnode_t *vp; + enum vtype vtype; + struct stat sb; char *pn; dev_t dev; int error; register_t ret; - printf("ddi_create_minor_node: name %s\n", name); - - dev = makedev(flag, minor_num); - pn = PNBUF_GET(); - if (spec_type == S_IFCHR) + if (spec_type == S_IFCHR) { + vtype = VCHR; + dev = makedev(dip->di_cmajor, minor_num); snprintf(pn, MAXPATHLEN, "/dev/zvol/rdsk/%s", name); - else + } else if (spec_type == S_IFBLK) { + vtype = VBLK; + dev = makedev(dip->di_bmajor, minor_num); snprintf(pn, MAXPATHLEN, "/dev/zvol/dsk/%s", name); + } else { + panic("bad spectype %#x", spec_type); + } + spec_type |= (S_IRUSR | S_IWUSR); + /* Create missing directories. */ if ((error = do_mkdirp(pn)) != 0) goto exit; - - error = do_sys_mknod(l, (const char *)pn, spec_type, dev, &ret, UIO_SYSSPACE); + + /* + * If node exists and has correct type and rdev all done, + * otherwise unlink the node. + */ + if (namei_simple_kernel(pn, NSM_NOFOLLOW_NOEMULROOT, &vp) == 0) { + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + error = vn_stat(vp, &sb); + VOP_UNLOCK(vp, 0); + if (error == 0 && vp->v_type == vtype && sb.st_rdev == dev) { + vrele(vp); + return 0; + } + vrele(vp); + (void)do_sys_unlink(pn, UIO_SYSSPACE); + } + + error = do_sys_mknod(l, pn, spec_type, dev, &ret, UIO_SYSSPACE); exit: PNBUF_PUT(pn); @@ -592,17 +661,19 @@ void ddi_remove_minor_node(dev_info_t *dip, char *name) { char *pn; - int error; + /* Unlink block device and remove empty directories. */ pn = PNBUF_GET(); snprintf(pn, MAXPATHLEN, "/dev/zvol/dsk/%s", name); (void)do_sys_unlink(pn, UIO_SYSSPACE); + do_rmdirp(pn); PNBUF_PUT(pn); - /* We need to remove raw and block device nodes */ + /* Unlink raw device and remove empty directories. */ pn = PNBUF_GET(); snprintf(pn, MAXPATHLEN, "/dev/zvol/rdsk/%s", name); (void)do_sys_unlink(pn, UIO_SYSSPACE); + do_rmdirp(pn); PNBUF_PUT(pn); } Index: src/external/cddl/osnet/sys/sys/sunddi.h diff -u src/external/cddl/osnet/sys/sys/sunddi.h:1.5 src/external/cddl/osnet/sys/sys/sunddi.h:1.6 --- src/external/cddl/osnet/sys/sys/sunddi.h:1.5 Mon May 28 21:05:10 2018 +++ src/external/cddl/osnet/sys/sys/sunddi.h Wed May 22 08:44:48 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sunddi.h,v 1.5 2018/05/28 21:05:10 chs Exp $ */ +/* $NetBSD: sunddi.h,v 1.6 2019/05/22 08:44:48 hannken Exp $ */ /*- * Copyright (c) 2007 Pawel Jakub Dawidek <p...@freebsd.org> @@ -70,7 +70,12 @@ int _ddi_log_sysevent(char *vendor, char #define DDI_PSEUDO "" -typedef void *dev_info_t; +struct dev_info { + int di_cmajor; + int di_bmajor; +}; +typedef struct dev_info dev_info_t; + int ddi_create_minor_node(dev_info_t *, char *, int, minor_t, char *, int); void ddi_remove_minor_node(dev_info_t *, char *);