mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
Fix locking problem in disk_resize(); previously it would run without
topology lock, resulting in assertion when running with DIAGNOSTIC. Reviewed by: mav (earlier version)
This commit is contained in:
parent
a9387eb1df
commit
1af2d09b49
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=242322
@ -2673,6 +2673,7 @@ dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector,
|
|||||||
struct da_softc *softc;
|
struct da_softc *softc;
|
||||||
struct disk_params *dp;
|
struct disk_params *dp;
|
||||||
u_int lbppbe, lalba;
|
u_int lbppbe, lalba;
|
||||||
|
int error;
|
||||||
|
|
||||||
softc = (struct da_softc *)periph->softc;
|
softc = (struct da_softc *)periph->softc;
|
||||||
|
|
||||||
@ -2779,10 +2780,9 @@ dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector,
|
|||||||
else
|
else
|
||||||
softc->disk->d_flags &= ~DISKFLAG_CANDELETE;
|
softc->disk->d_flags &= ~DISKFLAG_CANDELETE;
|
||||||
|
|
||||||
/* Currently as of 6/13/2012, panics if DIAGNOSTIC is set */
|
error = disk_resize(softc->disk, M_NOWAIT);
|
||||||
#ifndef DIAGNOSTIC
|
if (error != 0)
|
||||||
disk_resize(softc->disk);
|
xpt_print(periph->path, "disk_resize(9) failed, error = %d\n", error);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/sbuf.h>
|
#include <sys/sbuf.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <sys/taskqueue.h>
|
|
||||||
#include <sys/devicestat.h>
|
#include <sys/devicestat.h>
|
||||||
#include <machine/md_var.h>
|
#include <machine/md_var.h>
|
||||||
|
|
||||||
@ -66,7 +65,6 @@ struct g_disk_softc {
|
|||||||
struct sysctl_oid *sysctl_tree;
|
struct sysctl_oid *sysctl_tree;
|
||||||
char led[64];
|
char led[64];
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
struct task resize_task;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mtx g_disk_done_mtx;
|
static struct mtx g_disk_done_mtx;
|
||||||
@ -443,17 +441,22 @@ g_disk_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_disk_resize_task(void *context, int pending)
|
g_disk_resize(void *ptr, int flag)
|
||||||
{
|
{
|
||||||
|
struct disk *dp;
|
||||||
struct g_geom *gp;
|
struct g_geom *gp;
|
||||||
struct g_provider *pp;
|
struct g_provider *pp;
|
||||||
struct disk *dp;
|
|
||||||
struct g_disk_softc *sc;
|
|
||||||
|
|
||||||
sc = (struct g_disk_softc *)context;
|
if (flag == EV_CANCEL)
|
||||||
dp = sc->dp;
|
return;
|
||||||
|
g_topology_assert();
|
||||||
|
|
||||||
|
dp = ptr;
|
||||||
gp = dp->d_geom;
|
gp = dp->d_geom;
|
||||||
|
|
||||||
|
if (dp->d_destroyed || gp == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
LIST_FOREACH(pp, &gp->provider, provider) {
|
LIST_FOREACH(pp, &gp->provider, provider) {
|
||||||
if (pp->sectorsize != 0 &&
|
if (pp->sectorsize != 0 &&
|
||||||
pp->sectorsize != dp->d_sectorsize)
|
pp->sectorsize != dp->d_sectorsize)
|
||||||
@ -501,7 +504,6 @@ g_disk_create(void *arg, int flag)
|
|||||||
CTLFLAG_RW | CTLFLAG_TUN, sc->led, sizeof(sc->led),
|
CTLFLAG_RW | CTLFLAG_TUN, sc->led, sizeof(sc->led),
|
||||||
"LED name");
|
"LED name");
|
||||||
}
|
}
|
||||||
TASK_INIT(&sc->resize_task, 0, g_disk_resize_task, sc);
|
|
||||||
pp->private = sc;
|
pp->private = sc;
|
||||||
dp->d_geom = gp;
|
dp->d_geom = gp;
|
||||||
g_error_provider(pp, 0);
|
g_error_provider(pp, 0);
|
||||||
@ -684,22 +686,14 @@ disk_media_gone(struct disk *dp, int flag)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
disk_resize(struct disk *dp)
|
disk_resize(struct disk *dp, int flag)
|
||||||
{
|
{
|
||||||
struct g_geom *gp;
|
|
||||||
struct g_disk_softc *sc;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
gp = dp->d_geom;
|
if (dp->d_destroyed || dp->d_geom == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
if (gp == NULL)
|
return (g_post_event(g_disk_resize, dp, flag, NULL));
|
||||||
return;
|
|
||||||
|
|
||||||
sc = gp->softc;
|
|
||||||
|
|
||||||
error = taskqueue_enqueue(taskqueue_thread, &sc->resize_task);
|
|
||||||
KASSERT(error == 0, ("taskqueue_enqueue(9) failed."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -111,7 +111,7 @@ void disk_gone(struct disk *disk);
|
|||||||
void disk_attr_changed(struct disk *dp, const char *attr, int flag);
|
void disk_attr_changed(struct disk *dp, const char *attr, int flag);
|
||||||
void disk_media_changed(struct disk *dp, int flag);
|
void disk_media_changed(struct disk *dp, int flag);
|
||||||
void disk_media_gone(struct disk *dp, int flag);
|
void disk_media_gone(struct disk *dp, int flag);
|
||||||
void disk_resize(struct disk *dp);
|
int disk_resize(struct disk *dp, int flag);
|
||||||
|
|
||||||
#define DISK_VERSION_00 0x58561059
|
#define DISK_VERSION_00 0x58561059
|
||||||
#define DISK_VERSION_01 0x5856105a
|
#define DISK_VERSION_01 0x5856105a
|
||||||
|
Loading…
Reference in New Issue
Block a user