Make g_attach() return ENXIO for orphaned providers; update various
classes to add missing error checking. Reviewed by: imp MFC after: 2 weeks Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D26658
This commit is contained in:
parent
6221ec6064
commit
d22ff249d9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=366811
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd January 16, 2004
|
.Dd October 10, 2020
|
||||||
.Dt G_ATTACH 9
|
.Dt G_ATTACH 9
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -122,6 +122,8 @@ Possible errors:
|
|||||||
.Bl -tag -width Er
|
.Bl -tag -width Er
|
||||||
.It Bq Er ELOOP
|
.It Bq Er ELOOP
|
||||||
The operation creates a topology loop.
|
The operation creates a topology loop.
|
||||||
|
.It Bq Er ENXIO
|
||||||
|
Provider got orphaned.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr geom 4 ,
|
.Xr geom 4 ,
|
||||||
|
@ -131,7 +131,13 @@ g_bde_create_geom(struct gctl_req *req, struct g_class *mp, struct g_provider *p
|
|||||||
|
|
||||||
gp = g_new_geomf(mp, "%s.bde", pp->name);
|
gp = g_new_geomf(mp, "%s.bde", pp->name);
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
|
if (error != 0) {
|
||||||
|
g_destroy_consumer(cp);
|
||||||
|
g_destroy_geom(gp);
|
||||||
|
gctl_error(req, "could not attach consumer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
error = g_access(cp, 1, 1, 1);
|
error = g_access(cp, 1, 1, 1);
|
||||||
if (error) {
|
if (error) {
|
||||||
g_detach(cp);
|
g_detach(cp);
|
||||||
|
8
sys/geom/cache/g_cache.c
vendored
8
sys/geom/cache/g_cache.c
vendored
@ -673,9 +673,11 @@ g_cache_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
gp->orphan = g_cache_orphan;
|
gp->orphan = g_cache_orphan;
|
||||||
gp->access = g_cache_access;
|
gp->access = g_cache_access;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
error = g_cache_read_metadata(cp, &md);
|
if (error == 0) {
|
||||||
g_detach(cp);
|
error = g_cache_read_metadata(cp, &md);
|
||||||
|
g_detach(cp);
|
||||||
|
}
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
|
@ -718,9 +718,11 @@ g_concat_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
gp->access = g_concat_access;
|
gp->access = g_concat_access;
|
||||||
gp->orphan = g_concat_orphan;
|
gp->orphan = g_concat_orphan;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
error = g_concat_read_metadata(cp, &md);
|
if (error == 0) {
|
||||||
g_detach(cp);
|
error = g_concat_read_metadata(cp, &md);
|
||||||
|
g_detach(cp);
|
||||||
|
}
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
|
@ -346,7 +346,7 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
|
|||||||
cp->private = sc;
|
cp->private = sc;
|
||||||
cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE;
|
cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE;
|
||||||
error = g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
KASSERT(error == 0,
|
KASSERT(error == 0 || error == ENXIO,
|
||||||
("g_dev_taste(%s) failed to g_attach, err=%d", pp->name, error));
|
("g_dev_taste(%s) failed to g_attach, err=%d", pp->name, error));
|
||||||
|
|
||||||
make_dev_args_init(&args);
|
make_dev_args_init(&args);
|
||||||
|
@ -896,6 +896,8 @@ g_attach(struct g_consumer *cp, struct g_provider *pp)
|
|||||||
G_VALID_PROVIDER(pp);
|
G_VALID_PROVIDER(pp);
|
||||||
g_trace(G_T_TOPOLOGY, "g_attach(%p, %p)", cp, pp);
|
g_trace(G_T_TOPOLOGY, "g_attach(%p, %p)", cp, pp);
|
||||||
KASSERT(cp->provider == NULL, ("attach but attached"));
|
KASSERT(cp->provider == NULL, ("attach but attached"));
|
||||||
|
if ((pp->flags & (G_PF_ORPHAN | G_PF_WITHER)) != 0)
|
||||||
|
return (ENXIO);
|
||||||
cp->provider = pp;
|
cp->provider = pp;
|
||||||
cp->flags &= ~G_CF_ORPHAN;
|
cp->flags &= ~G_CF_ORPHAN;
|
||||||
LIST_INSERT_HEAD(&pp->consumers, cp, consumers);
|
LIST_INSERT_HEAD(&pp->consumers, cp, consumers);
|
||||||
|
@ -260,7 +260,11 @@ g_vfs_open(struct vnode *vp, struct g_consumer **cpp, const char *fsname, int wr
|
|||||||
sc->sc_bo = bo;
|
sc->sc_bo = bo;
|
||||||
gp->softc = sc;
|
gp->softc = sc;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
|
if (error) {
|
||||||
|
g_wither_geom(gp, ENXIO);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
error = g_access(cp, 1, wr, wr);
|
error = g_access(cp, 1, wr, wr);
|
||||||
if (error) {
|
if (error) {
|
||||||
g_wither_geom(gp, ENXIO);
|
g_wither_geom(gp, ENXIO);
|
||||||
|
@ -2483,9 +2483,11 @@ g_journal_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
/* This orphan function should be never called. */
|
/* This orphan function should be never called. */
|
||||||
gp->orphan = g_journal_taste_orphan;
|
gp->orphan = g_journal_taste_orphan;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
error = g_journal_metadata_read(cp, &md);
|
if (error == 0) {
|
||||||
g_detach(cp);
|
error = g_journal_metadata_read(cp, &md);
|
||||||
|
g_detach(cp);
|
||||||
|
}
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
|
@ -400,7 +400,8 @@ g_label_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
gp->access = g_label_access_taste;
|
gp->access = g_label_access_taste;
|
||||||
gp->orphan = g_label_orphan_taste;
|
gp->orphan = g_label_orphan_taste;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
if (g_attach(cp, pp) != 0)
|
||||||
|
goto end2;
|
||||||
if (g_access(cp, 1, 0, 0) != 0)
|
if (g_access(cp, 1, 0, 0) != 0)
|
||||||
goto end;
|
goto end;
|
||||||
for (i = 0; g_labels[i] != NULL; i++) {
|
for (i = 0; g_labels[i] != NULL; i++) {
|
||||||
@ -425,6 +426,7 @@ g_label_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
g_access(cp, -1, 0, 0);
|
g_access(cp, -1, 0, 0);
|
||||||
end:
|
end:
|
||||||
g_detach(cp);
|
g_detach(cp);
|
||||||
|
end2:
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
@ -543,11 +543,13 @@ g_llvm_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
/* This orphan function should be never called. */
|
/* This orphan function should be never called. */
|
||||||
gp->orphan = g_llvm_taste_orphan;
|
gp->orphan = g_llvm_taste_orphan;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
error = g_llvm_read_label(cp, &ll);
|
if (error == 0) {
|
||||||
if (!error)
|
error = g_llvm_read_label(cp, &ll);
|
||||||
error = g_llvm_read_md(cp, &md, &ll);
|
if (error == 0)
|
||||||
g_detach(cp);
|
error = g_llvm_read_md(cp, &md, &ll);
|
||||||
|
g_detach(cp);
|
||||||
|
}
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
|
@ -3241,9 +3241,11 @@ g_mirror_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
*/
|
*/
|
||||||
gp->orphan = g_mirror_taste_orphan;
|
gp->orphan = g_mirror_taste_orphan;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
error = g_mirror_read_metadata(cp, &md);
|
if (error == 0) {
|
||||||
g_detach(cp);
|
error = g_mirror_read_metadata(cp, &md);
|
||||||
|
g_detach(cp);
|
||||||
|
}
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
|
@ -449,7 +449,11 @@ g_mirror_ctl_create(struct gctl_req *req, struct g_class *mp)
|
|||||||
g_topology_unlock();
|
g_topology_unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_attach(cp, pp);
|
if (g_attach(cp, pp) != 0) {
|
||||||
|
G_MIRROR_DEBUG(1, "Can't attach disk %s.", pp->name);
|
||||||
|
gctl_error(req, "Can't attach disk %s.", pp->name);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
if (g_access(cp, 1, 0, 0) != 0) {
|
if (g_access(cp, 1, 0, 0) != 0) {
|
||||||
G_MIRROR_DEBUG(1, "Can't open disk %s.", pp->name);
|
G_MIRROR_DEBUG(1, "Can't open disk %s.", pp->name);
|
||||||
gctl_error(req, "Can't open disk %s.", pp->name);
|
gctl_error(req, "Can't open disk %s.", pp->name);
|
||||||
|
@ -586,7 +586,12 @@ g_mountver_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
cp = LIST_FIRST(&gp->consumer);
|
cp = LIST_FIRST(&gp->consumer);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
|
if (error != 0) {
|
||||||
|
G_MOUNTVER_DEBUG(0, "Cannot attach to %s; error = %d.", pp->name, error);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
error = g_mountver_ident_matches(gp);
|
error = g_mountver_ident_matches(gp);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
g_detach(cp);
|
g_detach(cp);
|
||||||
|
@ -823,9 +823,11 @@ g_multipath_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
gp->access = g_multipath_access;
|
gp->access = g_multipath_access;
|
||||||
gp->orphan = g_multipath_orphan;
|
gp->orphan = g_multipath_orphan;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
error = g_multipath_read_metadata(cp, &md);
|
if (error == 0) {
|
||||||
g_detach(cp);
|
error = g_multipath_read_metadata(cp, &md);
|
||||||
|
g_detach(cp);
|
||||||
|
}
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
|
@ -2228,7 +2228,8 @@ g_raid_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
gp->orphan = g_raid_taste_orphan;
|
gp->orphan = g_raid_taste_orphan;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
cp->flags |= G_CF_DIRECT_RECEIVE;
|
cp->flags |= G_CF_DIRECT_RECEIVE;
|
||||||
g_attach(cp, pp);
|
if (g_attach(cp, pp) != 0)
|
||||||
|
goto ofail2;
|
||||||
if (g_access(cp, 1, 0, 0) != 0)
|
if (g_access(cp, 1, 0, 0) != 0)
|
||||||
goto ofail;
|
goto ofail;
|
||||||
|
|
||||||
@ -2251,6 +2252,7 @@ g_raid_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
(void)g_access(cp, -1, 0, 0);
|
(void)g_access(cp, -1, 0, 0);
|
||||||
ofail:
|
ofail:
|
||||||
g_detach(cp);
|
g_detach(cp);
|
||||||
|
ofail2:
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
G_RAID_DEBUG(2, "Tasting provider %s done.", pp->name);
|
G_RAID_DEBUG(2, "Tasting provider %s done.", pp->name);
|
||||||
|
@ -3315,9 +3315,11 @@ g_raid3_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
/* This orphan function should be never called. */
|
/* This orphan function should be never called. */
|
||||||
gp->orphan = g_raid3_taste_orphan;
|
gp->orphan = g_raid3_taste_orphan;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
error = g_raid3_read_metadata(cp, &md);
|
if (error == 0) {
|
||||||
g_detach(cp);
|
error = g_raid3_read_metadata(cp, &md);
|
||||||
|
g_detach(cp);
|
||||||
|
}
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
|
@ -646,9 +646,11 @@ g_shsec_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
gp->access = g_shsec_access;
|
gp->access = g_shsec_access;
|
||||||
gp->orphan = g_shsec_orphan;
|
gp->orphan = g_shsec_orphan;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
error = g_shsec_read_metadata(cp, &md);
|
if (error == 0) {
|
||||||
g_detach(cp);
|
error = g_shsec_read_metadata(cp, &md);
|
||||||
|
g_detach(cp);
|
||||||
|
}
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
|
@ -963,9 +963,11 @@ g_stripe_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
gp->access = g_stripe_access;
|
gp->access = g_stripe_access;
|
||||||
gp->orphan = g_stripe_orphan;
|
gp->orphan = g_stripe_orphan;
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
error = g_stripe_read_metadata(cp, &md);
|
if (error == 0) {
|
||||||
g_detach(cp);
|
error = g_stripe_read_metadata(cp, &md);
|
||||||
|
g_detach(cp);
|
||||||
|
}
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
|
@ -780,9 +780,11 @@ g_virstor_taste(struct g_class *mp, struct g_provider *pp, int flags)
|
|||||||
gp->orphan = (void *)invalid_call; /* I really want these to fail. */
|
gp->orphan = (void *)invalid_call; /* I really want these to fail. */
|
||||||
|
|
||||||
cp = g_new_consumer(gp);
|
cp = g_new_consumer(gp);
|
||||||
g_attach(cp, pp);
|
error = g_attach(cp, pp);
|
||||||
error = read_metadata(cp, &md);
|
if (error == 0) {
|
||||||
g_detach(cp);
|
error = read_metadata(cp, &md);
|
||||||
|
g_detach(cp);
|
||||||
|
}
|
||||||
g_destroy_consumer(cp);
|
g_destroy_consumer(cp);
|
||||||
g_destroy_geom(gp);
|
g_destroy_geom(gp);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user