View | Details | Raw Unified | Return to bug 225960
Collapse All | Expand All

(-)b/sys/geom/geom_slice.c (-1 / +24 lines)
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.

Return to bug 225960