diff options
author | phk <phk@FreeBSD.org> | 2004-07-04 13:44:48 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2004-07-04 13:44:48 +0000 |
commit | 0b5402fc6b7225b89bf8a3dd809b4e100b3ea150 (patch) | |
tree | 82ecbac8961e50272a7d89d0a4ceca452df2a01d /sys/geom | |
parent | 704b01603a0dd3fd25f535d98e5a5c0ff48d80e5 (diff) | |
download | FreeBSD-src-0b5402fc6b7225b89bf8a3dd809b4e100b3ea150.zip FreeBSD-src-0b5402fc6b7225b89bf8a3dd809b4e100b3ea150.tar.gz |
We only need to check for overlaps if we increasing access counts.
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/geom_slice.c | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/sys/geom/geom_slice.c b/sys/geom/geom_slice.c index 736ab0c..549005b 100644 --- a/sys/geom/geom_slice.c +++ b/sys/geom/geom_slice.c @@ -99,23 +99,25 @@ g_slice_access(struct g_provider *pp, int dr, int dw, int de) cp = LIST_FIRST(&gp->consumer); KASSERT (cp != NULL, ("g_slice_access but no consumer")); gsp = gp->softc; - gsl = &gsp->slices[pp->index]; - for (u = 0; u < gsp->nslice; u++) { - gsl2 = &gsp->slices[u]; - if (gsl2->length == 0) - continue; - if (u == pp->index) - continue; - if (gsl->offset + gsl->length <= gsl2->offset) - continue; - if (gsl2->offset + gsl2->length <= gsl->offset) - continue; - /* overlap */ - pp2 = gsl2->provider; - if ((pp->acw + dw) > 0 && pp2->ace > 0) - return (EPERM); - if ((pp->ace + de) > 0 && pp2->acw > 0) - return (EPERM); + if (dr > 0 || dw > 0 || de > 0) { + gsl = &gsp->slices[pp->index]; + for (u = 0; u < gsp->nslice; u++) { + gsl2 = &gsp->slices[u]; + if (gsl2->length == 0) + continue; + if (u == pp->index) + continue; + if (gsl->offset + gsl->length <= gsl2->offset) + continue; + if (gsl2->offset + gsl2->length <= gsl->offset) + continue; + /* overlap */ + pp2 = gsl2->provider; + if ((pp->acw + dw) > 0 && pp2->ace > 0) + return (EPERM); + if ((pp->ace + de) > 0 && pp2->acw > 0) + return (EPERM); + } } /* On first open, grab an extra "exclusive" bit */ if (cp->acr == 0 && cp->acw == 0 && cp->ace == 0) |