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