Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/cddl/osnet Update ddi environment:



details:   https://anonhg.NetBSD.org/src/rev/8435da909266
branches:  trunk
changeset: 451422:8435da909266
user:      hannken <hannken%NetBSD.org@localhost>
date:      Wed May 22 08:44:48 2019 +0000

description:
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.

diffstat:

 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c |  11 +-
 external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c      |   2 +-
 external/cddl/osnet/sys/kern/ddi.c                     |  97 +++++++++++++++--
 external/cddl/osnet/sys/sys/sunddi.h                   |   9 +-
 4 files changed, 96 insertions(+), 23 deletions(-)

diffs (208 lines):

diff -r 13ea21682f29 -r 8435da909266 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c
--- a/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c    Wed May 22 08:42:57 2019 +0000
+++ b/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c    Wed May 22 08:44:48 2019 +0000
@@ -211,11 +211,8 @@
 #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_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;
                }
diff -r 13ea21682f29 -r 8435da909266 external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c
--- a/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c Wed May 22 08:42:57 2019 +0000
+++ b/external/cddl/osnet/dist/uts/common/fs/zfs/zvol.c Wed May 22 08:44:48 2019 +0000
@@ -676,7 +676,7 @@
        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);
diff -r 13ea21682f29 -r 8435da909266 external/cddl/osnet/sys/kern/ddi.c
--- a/external/cddl/osnet/sys/kern/ddi.c        Wed May 22 08:42:57 2019 +0000
+++ b/external/cddl/osnet/sys/kern/ddi.c        Wed May 22 08:44:48 2019 +0000
@@ -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 @@
        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 @@
     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);
+       pn = PNBUF_GET();
+       if (spec_type == S_IFCHR) {
+               vtype = VCHR;
+               dev = makedev(dip->di_cmajor, minor_num);
+               snprintf(pn, MAXPATHLEN, "/dev/zvol/rdsk/%s", name);
+       } 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);
 
-       dev = makedev(flag, minor_num);
-       
-       pn = PNBUF_GET();
-       if (spec_type == S_IFCHR)
-               snprintf(pn, MAXPATHLEN, "/dev/zvol/rdsk/%s", name);
-       else
-               snprintf(pn, MAXPATHLEN, "/dev/zvol/dsk/%s", name);
-
+       /* 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 @@
 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);
 }
 
diff -r 13ea21682f29 -r 8435da909266 external/cddl/osnet/sys/sys/sunddi.h
--- a/external/cddl/osnet/sys/sys/sunddi.h      Wed May 22 08:42:57 2019 +0000
+++ b/external/cddl/osnet/sys/sys/sunddi.h      Wed May 22 08:44:48 2019 +0000
@@ -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 <pjd%FreeBSD.org@localhost>
@@ -70,7 +70,12 @@
 
 #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 *);



Home | Main Index | Thread Index | Old Index