detect root node and set VROOT flag
[unix-history] / usr / src / sys / miscfs / union / union_subr.c
index 9e444c7..f0cd58e 100644 (file)
@@ -8,7 +8,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)union_subr.c        8.4 (Berkeley) %G%
+ *     @(#)union_subr.c        8.5 (Berkeley) %G%
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -21,6 +21,7 @@
 #include <sys/file.h>
 #include <sys/filedesc.h>
 #include <sys/queue.h>
 #include <sys/file.h>
 #include <sys/filedesc.h>
 #include <sys/queue.h>
+#include <sys/mount.h>
 #include <miscfs/union/union.h>
 
 #ifdef DIAGNOSTIC
 #include <miscfs/union/union.h>
 
 #ifdef DIAGNOSTIC
@@ -200,7 +201,9 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
        struct union_node *un;
        struct union_node **pp;
        struct vnode *xlowervp = NULLVP;
        struct union_node *un;
        struct union_node **pp;
        struct vnode *xlowervp = NULLVP;
+       struct union_mount *um = MOUNTTOUNIONMOUNT(mp);
        int hash;
        int hash;
+       int vflag;
        int try;
 
        if (uppervp == NULLVP && lowervp == NULLVP)
        int try;
 
        if (uppervp == NULLVP && lowervp == NULLVP)
@@ -211,6 +214,17 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
                lowervp = NULLVP;
        }
 
                lowervp = NULLVP;
        }
 
+       /* detect the root vnode (and aliases) */
+       vflag = 0;
+       if ((uppervp == um->um_uppervp) &&
+           ((lowervp == NULLVP) || lowervp == um->um_lowervp)) {
+               if (lowervp == NULLVP) {
+                       lowervp = um->um_lowervp;
+                       VREF(lowervp);
+               }
+               vflag = VROOT;
+       }
+
 loop:
        for (try = 0; try < 3; try++) {
                switch (try) {
 loop:
        for (try = 0; try < 3; try++) {
                switch (try) {
@@ -370,6 +384,7 @@ loop:
        MALLOC((*vpp)->v_data, void *, sizeof(struct union_node),
                M_TEMP, M_WAITOK);
 
        MALLOC((*vpp)->v_data, void *, sizeof(struct union_node),
                M_TEMP, M_WAITOK);
 
+       (*vpp)->v_flag |= vflag;
        if (uppervp)
                (*vpp)->v_type = uppervp->v_type;
        else
        if (uppervp)
                (*vpp)->v_type = uppervp->v_type;
        else