Hi,

I think the vnode alias code becomes more readable when we convert
the hash buckets to SLIST macros.

ok?

bluhm

Index: kern/spec_vnops.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/spec_vnops.c,v
retrieving revision 1.98
diff -u -p -r1.98 spec_vnops.c
--- kern/spec_vnops.c   29 Oct 2019 16:24:42 -0000      1.98
+++ kern/spec_vnops.c   26 Dec 2019 21:19:19 -0000
@@ -60,7 +60,7 @@

 int    spec_open_clone(struct vop_open_args *);

-struct vnode *speclisth[SPECHSZ];
+struct vnodechain speclisth[SPECHSZ];

 struct vops spec_vops = {
        .vop_lookup     = vop_generic_lookup,
Index: kern/vfs_default.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/vfs_default.c,v
retrieving revision 1.44
diff -u -p -r1.44 vfs_default.c
--- kern/vfs_default.c  8 Dec 2019 12:29:42 -0000       1.44
+++ kern/vfs_default.c  26 Dec 2019 21:19:19 -0000
@@ -98,7 +98,7 @@ vop_generic_revoke(void *v)
                 */
                vp->v_flag |= VXLOCK;
                while (vp->v_flag & VALIASED) {
-                       for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
+                       SLIST_FOREACH(vq, vp->v_hashchain, v_specnext) {
                                if (vq->v_rdev != vp->v_rdev ||
                                    vq->v_type != vp->v_type || vp == vq)
                                        continue;
Index: kern/vfs_subr.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/vfs_subr.c,v
retrieving revision 1.295
diff -u -p -r1.295 vfs_subr.c
--- kern/vfs_subr.c     26 Dec 2019 18:59:05 -0000      1.295
+++ kern/vfs_subr.c     26 Dec 2019 21:19:19 -0000
@@ -551,14 +551,14 @@ checkalias(struct vnode *nvp, dev_t nvp_
 {
        struct proc *p = curproc;
        struct vnode *vp;
-       struct vnode **vpp;
+       struct vnodechain *vchain;

        if (nvp->v_type != VBLK && nvp->v_type != VCHR)
                return (NULLVP);

-       vpp = &speclisth[SPECHASH(nvp_rdev)];
+       vchain = &speclisth[SPECHASH(nvp_rdev)];
 loop:
-       for (vp = *vpp; vp; vp = vp->v_specnext) {
+       SLIST_FOREACH(vp, vchain, v_specnext) {
                if (nvp_rdev != vp->v_rdev || nvp->v_type != vp->v_type) {
                        continue;
                }
@@ -582,8 +582,7 @@ loop:
                nvp->v_specinfo = malloc(sizeof(struct specinfo), M_VNODE,
                        M_WAITOK);
                nvp->v_rdev = nvp_rdev;
-               nvp->v_hashchain = vpp;
-               nvp->v_specnext = *vpp;
+               nvp->v_hashchain = vchain;
                nvp->v_specmountpoint = NULL;
                nvp->v_speclockf = NULL;
                nvp->v_specbitmap = NULL;
@@ -596,7 +595,7 @@ loop:
                                nvp->v_specbitmap = malloc(CLONE_MAPSZ,
                                    M_VNODE, M_WAITOK | M_ZERO);
                }
-               *vpp = nvp;
+               SLIST_INSERT_HEAD(vchain, nvp, v_specnext);
                if (vp != NULLVP) {
                        nvp->v_flag |= VALIASED;
                        vp->v_flag |= VALIASED;
@@ -1127,21 +1126,10 @@ vgonel(struct vnode *vp, struct proc *p)
                    (minor(vp->v_rdev) >> CLONE_SHIFT == 0)) {
                        free(vp->v_specbitmap, M_VNODE, CLONE_MAPSZ);
                }
-               if (*vp->v_hashchain == vp) {
-                       *vp->v_hashchain = vp->v_specnext;
-               } else {
-                       for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
-                               if (vq->v_specnext != vp)
-                                       continue;
-                               vq->v_specnext = vp->v_specnext;
-                               break;
-                       }
-                       if (vq == NULL)
-                               panic("missing bdev");
-               }
+               SLIST_REMOVE(vp->v_hashchain, vp, vnode, v_specnext);
                if (vp->v_flag & VALIASED) {
                        vx = NULL;
-                       for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
+                       SLIST_FOREACH(vq, vp->v_hashchain, v_specnext) {
                                if (vq->v_rdev != vp->v_rdev ||
                                    vq->v_type != vp->v_type)
                                        continue;
@@ -1195,7 +1183,7 @@ vfinddev(dev_t dev, enum vtype type, str
        struct vnode *vp;
        int rc =0;

-       for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
+       SLIST_FOREACH(vp, &speclisth[SPECHASH(dev)], v_specnext) {
                if (dev != vp->v_rdev || type != vp->v_type)
                        continue;
                *vpp = vp;
@@ -1232,8 +1220,8 @@ vcount(struct vnode *vp)
 loop:
        if ((vp->v_flag & VALIASED) == 0)
                return (vp->v_usecount);
-       for (count = 0, vq = *vp->v_hashchain; vq; vq = vnext) {
-               vnext = vq->v_specnext;
+       count = 0;
+       SLIST_FOREACH_SAFE(vq, vp->v_hashchain, v_specnext, vnext) {
                if (vq->v_rdev != vp->v_rdev || vq->v_type != vp->v_type)
                        continue;
                /*
@@ -1386,7 +1374,7 @@ vfs_mountedon(struct vnode *vp)
        if (vp->v_specmountpoint != NULL)
                return (EBUSY);
        if (vp->v_flag & VALIASED) {
-               for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
+               SLIST_FOREACH(vq, vp->v_hashchain, v_specnext) {
                        if (vq->v_rdev != vp->v_rdev ||
                            vq->v_type != vp->v_type)
                                continue;
Index: sys/specdev.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/sys/specdev.h,v
retrieving revision 1.38
diff -u -p -r1.38 specdev.h
--- sys/specdev.h       21 Jan 2019 18:09:21 -0000      1.38
+++ sys/specdev.h       26 Dec 2019 21:19:19 -0000
@@ -32,14 +32,16 @@
  *     @(#)specdev.h   8.3 (Berkeley) 8/10/94
  */

+SLIST_HEAD(vnodechain, vnode);
+
 /*
  * This structure defines the information maintained about
  * special devices. It is allocated in checkalias and freed
  * in vgone.
  */
 struct specinfo {
-       struct  vnode **si_hashchain;
-       struct  vnode *si_specnext;
+       struct  vnodechain *si_hashchain;
+       SLIST_ENTRY(vnode) si_specnext;
        struct  mount *si_mountpoint;
        dev_t   si_rdev;
        struct  lockf_state *si_lockf;
@@ -85,7 +87,7 @@ struct cloneinfo {

 #ifdef _KERNEL

-extern struct vnode *speclisth[SPECHSZ];
+extern struct vnodechain speclisth[SPECHSZ];

 /*
  * Prototypes for special file operations on vnodes.

Reply via email to