|
Lines 103-108
g_slice_access(struct g_provider *pp, int dr, int dw, int de)
Link Here
|
| 103 |
struct g_provider *pp2; |
103 |
struct g_provider *pp2; |
| 104 |
struct g_slicer *gsp; |
104 |
struct g_slicer *gsp; |
| 105 |
struct g_slice *gsl, *gsl2; |
105 |
struct g_slice *gsl, *gsl2; |
|
|
106 |
bool first_open; |
| 106 |
|
107 |
|
| 107 |
gp = pp->geom; |
108 |
gp = pp->geom; |
| 108 |
cp = LIST_FIRST(&gp->consumer); |
109 |
cp = LIST_FIRST(&gp->consumer); |
|
Lines 128-141
g_slice_access(struct g_provider *pp, int dr, int dw, int de)
Link Here
|
| 128 |
return (EPERM); |
129 |
return (EPERM); |
| 129 |
} |
130 |
} |
| 130 |
} |
131 |
} |
|
|
132 |
|
| 131 |
/* On first open, grab an extra "exclusive" bit */ |
133 |
/* On first open, grab an extra "exclusive" bit */ |
| 132 |
if (cp->acr == 0 && cp->acw == 0 && cp->ace == 0) |
134 |
first_open = false; |
|
|
135 |
if (cp->acr == 0 && cp->acw == 0 && cp->ace == 0) { |
| 133 |
de++; |
136 |
de++; |
|
|
137 |
first_open = true; |
| 138 |
} |
| 139 |
|
| 134 |
/* ... and let go of it on last close */ |
140 |
/* ... and let go of it on last close */ |
| 135 |
if ((cp->acr + dr) == 0 && (cp->acw + dw) == 0 && (cp->ace + de) == 1) |
141 |
if ((cp->acr + dr) == 0 && (cp->acw + dw) == 0 && (cp->ace + de) == 1) |
| 136 |
de--; |
142 |
de--; |
|
|
143 |
|
| 137 |
error = g_access(cp, dr, dw, de); |
144 |
error = g_access(cp, dr, dw, de); |
| 138 |
|
145 |
|
|
|
146 |
if (error == 0 && first_open && |
| 147 |
(cp->acr != dr || cp->acw != dw || cp->ace != de)) { |
| 148 |
/* |
| 149 |
* GEOM topology lock has been dropped and reacquired by one |
| 150 |
* of underlying geoms because it needed to perform an I/O |
| 151 |
* operation. While the lock was not held by this thread |
| 152 |
* another thread performed a concurrent "first open" and this |
| 153 |
* thread lost the race. So, drop the extra "exclusive" bit. |
| 154 |
*/ |
| 155 |
g_topology_assert(); |
| 156 |
KASSERT(cp->ace >= 2, ("%s: lost exclusive bit", __func__)); |
| 157 |
g_trace(G_T_ACCESS, "%s(%s): lost first-open race", __func__, |
| 158 |
gp->name); |
| 159 |
cp->ace--; |
| 160 |
} |
| 161 |
|
| 139 |
/* |
162 |
/* |
| 140 |
* Free the softc if all providers have been closed and this geom |
163 |
* Free the softc if all providers have been closed and this geom |
| 141 |
* is being removed. |
164 |
* is being removed. |