Use g_handleattr() to reply to GEOM::candelete queries.

g_handleattr() fills out bp->bio_completed; otherwise, g_getattr()
returns an error in response to the query.  This caused BIO_DELETE
support to not be propagated through stacked configurations, e.g.,
a gconcat of gmirror volumes would not handle BIO_DELETE even when
the gmirrors do.  g_io_getattr() was not affected by the problem.

PR:		232676
Reported and tested by:	noah.bergbauer@tum.de
MFC after:	1 week
This commit is contained in:
Mark Johnston 2019-01-02 15:52:16 +00:00
parent 9bfc7fa41d
commit 438622af06
3 changed files with 11 additions and 20 deletions

View File

@ -210,20 +210,16 @@ g_concat_candelete(struct bio *bp)
{ {
struct g_concat_softc *sc; struct g_concat_softc *sc;
struct g_concat_disk *disk; struct g_concat_disk *disk;
int i, *val; int i, val;
val = (int *)bp->bio_data;
*val = 0;
sc = bp->bio_to->geom->softc; sc = bp->bio_to->geom->softc;
for (i = 0; i < sc->sc_ndisks; i++) { for (i = 0; i < sc->sc_ndisks; i++) {
disk = &sc->sc_disks[i]; disk = &sc->sc_disks[i];
if (!disk->d_removed && disk->d_candelete) { if (!disk->d_removed && disk->d_candelete)
*val = 1;
break; break;
}
} }
g_io_deliver(bp, 0); val = i < sc->sc_ndisks;
g_handleattr(bp, "GEOM::candelete", &val, sizeof(val));
} }
static void static void

View File

@ -1086,16 +1086,15 @@ g_mirror_candelete(struct bio *bp)
{ {
struct g_mirror_softc *sc; struct g_mirror_softc *sc;
struct g_mirror_disk *disk; struct g_mirror_disk *disk;
int *val; int val;
sc = bp->bio_to->private; sc = bp->bio_to->private;
LIST_FOREACH(disk, &sc->sc_disks, d_next) { LIST_FOREACH(disk, &sc->sc_disks, d_next) {
if (disk->d_flags & G_MIRROR_DISK_FLAG_CANDELETE) if (disk->d_flags & G_MIRROR_DISK_FLAG_CANDELETE)
break; break;
} }
val = (int *)bp->bio_data; val = disk != NULL;
*val = (disk != NULL); g_handleattr(bp, "GEOM::candelete", &val, sizeof(val));
g_io_deliver(bp, 0);
} }
static void static void

View File

@ -1075,23 +1075,19 @@ g_raid_candelete(struct g_raid_softc *sc, struct bio *bp)
struct g_provider *pp; struct g_provider *pp;
struct g_raid_volume *vol; struct g_raid_volume *vol;
struct g_raid_subdisk *sd; struct g_raid_subdisk *sd;
int *val; int i, val;
int i;
val = (int *)bp->bio_data;
pp = bp->bio_to; pp = bp->bio_to;
vol = pp->private; vol = pp->private;
*val = 0;
for (i = 0; i < vol->v_disks_count; i++) { for (i = 0; i < vol->v_disks_count; i++) {
sd = &vol->v_subdisks[i]; sd = &vol->v_subdisks[i];
if (sd->sd_state == G_RAID_SUBDISK_S_NONE) if (sd->sd_state == G_RAID_SUBDISK_S_NONE)
continue; continue;
if (sd->sd_disk->d_candelete) { if (sd->sd_disk->d_candelete)
*val = 1;
break; break;
}
} }
g_io_deliver(bp, 0); val = i < vol->v_disks_count;
g_handleattr(bp, "GEOM::candelete", &val, sizeof(val));
} }
static void static void