1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-12 14:29:28 +00:00

The CAM system has it's own ideas of what locks are to be held by whom.

So do GEOM.  Not a pretty sight.

Take all the interesting stuff out of GEOM::disk_create(), and leave just
the creation of the fake dev_t.  Schedule the topology munging to happen
in the g_event thread with g_call_me().

This makes disk_create() pretty lock-agnostic, almost lock-atheist.

Tripped over by:	peter
Sponsored by:	DARPA & NAI Labs
This commit is contained in:
Poul-Henning Kamp 2002-10-11 20:52:44 +00:00
parent 54603d8a36
commit 8523987b73
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=104936

View File

@ -66,6 +66,8 @@ struct g_class g_disk_class = {
G_CLASS_INITIALIZER
};
DECLARE_GEOM_CLASS(g_disk_class, g_disk);
static int
g_disk_access(struct g_provider *pp, int r, int w, int e)
{
@ -203,36 +205,39 @@ g_disk_start(struct bio *bp)
return;
}
dev_t
disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct cdevsw *proto)
static void
g_disk_create(void *arg)
{
static int once;
struct g_geom *gp;
struct g_provider *pp;
dev_t dev;
mtx_unlock(&Giant);
if (!once) {
g_add_class(&g_disk_class);
once++;
}
g_topology_assert();
dev = arg;
gp = g_new_geomf(&g_disk_class, dev->si_name);
gp->start = g_disk_start;
gp->access = g_disk_access;
gp->softc = dev->si_disk;
dev->si_disk->d_softc = gp;
pp = g_new_providerf(gp, "%s", gp->name);
g_error_provider(pp, 0);
}
dev_t
disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct cdevsw *proto)
{
dev_t dev;
dev = g_malloc(sizeof *dev, M_WAITOK | M_ZERO);
dp->d_dev = dev;
dp->d_devsw = cdevsw;
dev->si_devsw = cdevsw;
dev->si_disk = dp;
dev->si_udev = dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART);
g_topology_lock();
gp = g_new_geomf(&g_disk_class, "%s%d", cdevsw->d_name, unit);
strcpy(dev->si_name, gp->name);
gp->start = g_disk_start;
gp->access = g_disk_access;
gp->softc = dp;
dp->d_softc = gp;
pp = g_new_providerf(gp, "%s", gp->name);
g_error_provider(pp, 0);
g_topology_unlock();
mtx_lock(&Giant);
sprintf(dev->si_name, "%s%d", cdevsw->d_name, unit);
g_call_me(g_disk_create, dev);
return (dev);
}