From b5b5f29179e2665b2967704fbd2ecfe9c635616b Mon Sep 17 00:00:00 2001 From: Jan-Simon Pendry Date: Thu, 28 Apr 1994 13:33:48 -0800 Subject: [PATCH] keep track of whether the union node is cached or not. this allows anonymous union_node's to be handled correctly. (an anon node is one with neither an upper or lower layer and comes into being when an existing upper-layer file is deleted.) SCCS-vsn: sys/miscfs/union/union_subr.c 8.6 --- usr/src/sys/miscfs/union/union_subr.c | 56 ++++++++++++++++----------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/usr/src/sys/miscfs/union/union_subr.c b/usr/src/sys/miscfs/union/union_subr.c index f0cd58e1d5..1149caa319 100644 --- a/usr/src/sys/miscfs/union/union_subr.c +++ b/usr/src/sys/miscfs/union/union_subr.c @@ -8,7 +8,7 @@ * * %sccs.include.redist.c% * - * @(#)union_subr.c 8.5 (Berkeley) %G% + * @(#)union_subr.c 8.6 (Berkeley) %G% */ #include @@ -85,31 +85,35 @@ union_updatevp(un, uppervp, lowervp) { int ohash = UNION_HASH(un->un_uppervp, un->un_lowervp); int nhash = UNION_HASH(uppervp, lowervp); + int docache = (lowervp != NULLVP || uppervp != NULLVP); - if (ohash != nhash) { - /* - * Ensure locking is ordered from lower to higher - * to avoid deadlocks. - */ - if (nhash < ohash) { - int t = ohash; - ohash = nhash; - nhash = t; - } + /* + * Ensure locking is ordered from lower to higher + * to avoid deadlocks. + */ + if (nhash < ohash) { + int t = ohash; + ohash = nhash; + nhash = t; + } + if (ohash != nhash) while (union_list_lock(ohash)) continue; - while (union_list_lock(nhash)) - continue; + while (union_list_lock(nhash)) + continue; - LIST_REMOVE(un, un_cache); - union_list_unlock(ohash); - } else { - while (union_list_lock(nhash)) - continue; + if (ohash != nhash || !docache) { + if (un->un_flags & UN_CACHED) { + LIST_REMOVE(un, un_cache); + un->un_flags &= ~UN_CACHED; + } } + if (ohash != nhash) + union_list_unlock(ohash); + if (un->un_lowervp != lowervp) { if (un->un_lowervp) { vrele(un->un_lowervp); @@ -132,8 +136,10 @@ union_updatevp(un, uppervp, lowervp) un->un_uppervp = uppervp; } - if (ohash != nhash) + if (docache && (ohash != nhash)) { LIST_INSERT_HEAD(&unhead[nhash], un, un_cache); + un->un_flags |= UN_CACHED; + } union_list_unlock(nhash); } @@ -417,6 +423,7 @@ loop: } LIST_INSERT_HEAD(&unhead[hash], un, un_cache); + un->un_flags |= UN_CACHED; if (xlowervp) vrele(xlowervp); @@ -433,13 +440,16 @@ union_freevp(vp) { struct union_node *un = VTOUNION(vp); - LIST_REMOVE(un, un_cache); + if (un->un_flags & UN_CACHED) { + LIST_REMOVE(un, un_cache); + un->un_flags &= ~UN_CACHED; + } - if (un->un_uppervp) + if (un->un_uppervp != NULLVP) vrele(un->un_uppervp); - if (un->un_lowervp) + if (un->un_lowervp != NULLVP) vrele(un->un_lowervp); - if (un->un_dirvp) + if (un->un_dirvp != NULLVP) vrele(un->un_dirvp); if (un->un_path) free(un->un_path, M_TEMP); -- 2.20.1