summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2011-05-12 14:01:40 +0000
committerattilio <attilio@FreeBSD.org>2011-05-12 14:01:40 +0000
commit99e65551b9bcfa3dd0f837068d871552f6501af3 (patch)
tree47746a5cf787e85809af7176101c6cbcef1c23d8 /sys/geom
parent22bfcf5b903832f985a3d630fdad61b72a9d1763 (diff)
parentaed257e3d8840e7e4ae6a445d46b4ec5a02ef330 (diff)
downloadFreeBSD-src-99e65551b9bcfa3dd0f837068d871552f6501af3.zip
FreeBSD-src-99e65551b9bcfa3dd0f837068d871552f6501af3.tar.gz
MFC
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/geom_kern.c71
-rw-r--r--sys/geom/part/g_part.c49
2 files changed, 73 insertions, 47 deletions
diff --git a/sys/geom/geom_kern.c b/sys/geom/geom_kern.c
index 5e7e274..1744d17 100644
--- a/sys/geom/geom_kern.c
+++ b/sys/geom/geom_kern.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bio.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
+#include <sys/unistd.h>
#include <sys/kthread.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -57,7 +58,10 @@ MALLOC_DEFINE(M_GEOM, "GEOM", "Geom data structures");
struct sx topology_lock;
-static struct proc *g_up_proc;
+static struct proc *g_proc;
+static struct thread *g_up_td;
+static struct thread *g_down_td;
+static struct thread *g_event_td;
int g_debugflags;
int g_collectstats = 1;
@@ -82,71 +86,43 @@ int g_shutdown;
*/
static void
-g_up_procbody(void)
+g_up_procbody(void *arg)
{
- struct proc *p = g_up_proc;
- struct thread *tp = FIRST_THREAD_IN_PROC(p);
mtx_assert(&Giant, MA_NOTOWNED);
- thread_lock(tp);
- sched_prio(tp, PRIBIO);
- thread_unlock(tp);
+ thread_lock(g_up_td);
+ sched_prio(g_up_td, PRIBIO);
+ thread_unlock(g_up_td);
for(;;) {
- g_io_schedule_up(tp);
+ g_io_schedule_up(g_up_td);
}
}
-static struct kproc_desc g_up_kp = {
- "g_up",
- g_up_procbody,
- &g_up_proc,
-};
-
-static struct proc *g_down_proc;
-
static void
-g_down_procbody(void)
+g_down_procbody(void *arg)
{
- struct proc *p = g_down_proc;
- struct thread *tp = FIRST_THREAD_IN_PROC(p);
mtx_assert(&Giant, MA_NOTOWNED);
- thread_lock(tp);
- sched_prio(tp, PRIBIO);
- thread_unlock(tp);
+ thread_lock(g_down_td);
+ sched_prio(g_down_td, PRIBIO);
+ thread_unlock(g_down_td);
for(;;) {
- g_io_schedule_down(tp);
+ g_io_schedule_down(g_down_td);
}
}
-static struct kproc_desc g_down_kp = {
- "g_down",
- g_down_procbody,
- &g_down_proc,
-};
-
-static struct proc *g_event_proc;
-
static void
-g_event_procbody(void)
+g_event_procbody(void *arg)
{
- struct proc *p = g_event_proc;
- struct thread *tp = FIRST_THREAD_IN_PROC(p);
mtx_assert(&Giant, MA_NOTOWNED);
- thread_lock(tp);
- sched_prio(tp, PRIBIO);
- thread_unlock(tp);
+ thread_lock(g_event_td);
+ sched_prio(g_event_td, PRIBIO);
+ thread_unlock(g_event_td);
g_run_events();
/* NOTREACHED */
}
-static struct kproc_desc g_event_kp = {
- "g_event",
- g_event_procbody,
- &g_event_proc,
-};
-
static void
geom_shutdown(void *foo __unused)
{
@@ -164,9 +140,12 @@ g_init(void)
g_event_init();
g_ctl_init();
mtx_lock(&Giant);
- kproc_start(&g_event_kp);
- kproc_start(&g_up_kp);
- kproc_start(&g_down_kp);
+ kproc_kthread_add(g_event_procbody, NULL, &g_proc, &g_event_td,
+ RFHIGHPID, 0, "geom", "g_event");
+ kproc_kthread_add(g_up_procbody, NULL, &g_proc, &g_up_td,
+ RFHIGHPID, 0, "geom", "g_up");
+ kproc_kthread_add(g_down_procbody, NULL, &g_proc, &g_down_td,
+ RFHIGHPID, 0, "geom", "g_down");
mtx_unlock(&Giant);
EVENTHANDLER_REGISTER(shutdown_pre_sync, geom_shutdown, NULL,
SHUTDOWN_PRI_FIRST);
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index 437914a..aa5444e 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -231,6 +231,48 @@ g_part_geometry(struct g_part_table *table, struct g_consumer *cp,
}
}
+static int
+g_part_check_integrity(struct g_part_table *table, struct g_consumer *cp)
+{
+ struct g_part_entry *e1, *e2;
+ struct g_provider *pp;
+
+ pp = cp->provider;
+ if (table->gpt_first > table->gpt_last ||
+ table->gpt_last > pp->mediasize / pp->sectorsize - 1)
+ goto fail;
+
+ LIST_FOREACH(e1, &table->gpt_entry, gpe_entry) {
+ if (e1->gpe_deleted || e1->gpe_internal)
+ continue;
+ if (e1->gpe_start < table->gpt_first ||
+ e1->gpe_start > table->gpt_last ||
+ e1->gpe_end < e1->gpe_start ||
+ e1->gpe_end > table->gpt_last)
+ goto fail;
+ e2 = e1;
+ while ((e2 = LIST_NEXT(e2, gpe_entry)) != NULL) {
+ if (e2->gpe_deleted || e2->gpe_internal)
+ continue;
+ if (e1->gpe_start >= e2->gpe_start &&
+ e1->gpe_start <= e2->gpe_end)
+ goto fail;
+ if (e1->gpe_end >= e2->gpe_start &&
+ e1->gpe_end <= e2->gpe_end)
+ goto fail;
+ if (e1->gpe_start < e2->gpe_start &&
+ e1->gpe_end > e2->gpe_end)
+ goto fail;
+ }
+ }
+ return (0);
+fail:
+ if (bootverbose)
+ printf("GEOM_PART: integrity check failed (%s, %s)\n",
+ pp->name, table->gpt_scheme->name);
+ return (EINVAL);
+}
+
struct g_part_entry *
g_part_new_entry(struct g_part_table *table, int index, quad_t start,
quad_t end)
@@ -1310,9 +1352,11 @@ g_part_ctl_undo(struct gctl_req *req, struct g_part_parms *gpp)
error = G_PART_READ(table, cp);
if (error)
goto fail;
+ error = g_part_check_integrity(table, cp);
+ if (error)
+ goto fail;
g_topology_lock();
-
LIST_FOREACH(entry, &table->gpt_entry, gpe_entry) {
if (!entry->gpe_internal)
g_part_new_provider(gp, table, entry);
@@ -1773,6 +1817,9 @@ g_part_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
error = G_PART_READ(table, cp);
if (error)
goto fail;
+ error = g_part_check_integrity(table, cp);
+ if (error)
+ goto fail;
g_topology_lock();
LIST_FOREACH(entry, &table->gpt_entry, gpe_entry) {
OpenPOWER on IntegriCloud