summaryrefslogtreecommitdiffstats
path: root/sys/geom/part
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2009-02-15 22:18:16 +0000
committermarcel <marcel@FreeBSD.org>2009-02-15 22:18:16 +0000
commite6f532ab6f4817606ad510d637a48b0f022a729d (patch)
tree8a7d026a995a0c217189ebfece17974389cf09df /sys/geom/part
parent19b1b2f405eb019be397a5920527ac26ecc07624 (diff)
downloadFreeBSD-src-e6f532ab6f4817606ad510d637a48b0f022a729d.zip
FreeBSD-src-e6f532ab6f4817606ad510d637a48b0f022a729d.tar.gz
Add method precheck to the g_part interface. The precheck
method allows schemes to reject the ctl request, pre-check the parameters and/or modify/set parameters. There are 2 use cases that triggered the addition: 1. When implementing a R/O scheme, deletes will still happen to the in-memory representation. The scheme is not involved in that operation. The pre-check method can be used to fail the delete up-front. Without this the write to disk will typically fail, but at that time the delete already happened. 2. The EBR scheme uses a linked list to record slices. There's no index. The EBR scheme defines the index as a function of the start LBA of the partition. The add verb picks an index for the range and then invokes the add method of the scheme to fill in the blanks. It is too late for the add method to change the index. The pre-check is used to set the index up-front. This also (silently) overrides/nullifies any (pointless) user-specified index value.
Diffstat (limited to 'sys/geom/part')
-rw-r--r--sys/geom/part/g_part.c33
-rw-r--r--sys/geom/part/g_part.h17
-rw-r--r--sys/geom/part/g_part_if.m13
3 files changed, 43 insertions, 20 deletions
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index 9a345bb..7982945 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2005-2008 Marcel Moolenaar
+ * Copyright (c) 2002, 2005-2009 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -110,23 +110,6 @@ static struct g_class g_part_class = {
DECLARE_GEOM_CLASS(g_part_class, g_part);
-enum g_part_ctl {
- G_PART_CTL_NONE,
- G_PART_CTL_ADD,
- G_PART_CTL_BOOTCODE,
- G_PART_CTL_COMMIT,
- G_PART_CTL_CREATE,
- G_PART_CTL_DELETE,
- G_PART_CTL_DESTROY,
- G_PART_CTL_MODIFY,
- G_PART_CTL_MOVE,
- G_PART_CTL_RECOVER,
- G_PART_CTL_RESIZE,
- G_PART_CTL_SET,
- G_PART_CTL_UNDO,
- G_PART_CTL_UNSET
-};
-
/*
* Support functions.
*/
@@ -1349,7 +1332,7 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
/* Obtain permissions if possible/necessary. */
close_on_error = 0;
- table = NULL; /* Suppress uninit. warning. */
+ table = NULL;
if (modifies && (gpp.gpp_parms & G_PART_PARM_GEOM)) {
table = gpp.gpp_geom->softc;
if (table != NULL && !table->gpt_opened) {
@@ -1365,7 +1348,16 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
}
}
- error = EDOOFUS; /* Prevent bogus uninit. warning. */
+ /* Allow the scheme to check or modify the parameters. */
+ if (table != NULL) {
+ error = G_PART_PRECHECK(table, ctlreq, &gpp);
+ if (error) {
+ gctl_error(req, "%d pre-check failed", error);
+ goto out;
+ }
+ } else
+ error = EDOOFUS; /* Prevent bogus uninit. warning. */
+
switch (ctlreq) {
case G_PART_CTL_NONE:
panic("%s", __func__);
@@ -1421,6 +1413,7 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
}
}
+ out:
if (error && close_on_error) {
g_access(LIST_FIRST(&gpp.gpp_geom->consumer), -1, -1, -1);
table->gpt_opened = 0;
diff --git a/sys/geom/part/g_part.h b/sys/geom/part/g_part.h
index cfc048d..353063b6 100644
--- a/sys/geom/part/g_part.h
+++ b/sys/geom/part/g_part.h
@@ -123,6 +123,23 @@ struct g_part_table {
struct g_part_entry *g_part_new_entry(struct g_part_table *, int, quad_t,
quad_t);
+enum g_part_ctl {
+ G_PART_CTL_NONE,
+ G_PART_CTL_ADD,
+ G_PART_CTL_BOOTCODE,
+ G_PART_CTL_COMMIT,
+ G_PART_CTL_CREATE,
+ G_PART_CTL_DELETE,
+ G_PART_CTL_DESTROY,
+ G_PART_CTL_MODIFY,
+ G_PART_CTL_MOVE,
+ G_PART_CTL_RECOVER,
+ G_PART_CTL_RESIZE,
+ G_PART_CTL_SET,
+ G_PART_CTL_UNDO,
+ G_PART_CTL_UNSET
+};
+
/* G_PART ctlreq parameters. */
#define G_PART_PARM_ENTRIES 0x0001
#define G_PART_PARM_FLAGS 0x0002
diff --git a/sys/geom/part/g_part_if.m b/sys/geom/part/g_part_if.m
index 2a0a182..4993db1 100644
--- a/sys/geom/part/g_part_if.m
+++ b/sys/geom/part/g_part_if.m
@@ -95,6 +95,19 @@ METHOD const char * name {
size_t bufsz;
};
+# precheck() - method to allow schemes to check the parameters given
+# to the mentioned ctl request. This only applies to the requests that
+# operate on a GEOM. In other words, it does not apply to the create
+# request.
+# It is allowed (intended actually) to change the parameters according
+# to the schemes needs before they are used. Returning an error will
+# terminate the request immediately.
+METHOD int precheck {
+ struct g_part_table *table;
+ enum g_part_ctl req;
+ struct g_part_parms *gpp;
+};
+
# probe() - probe the provider attached to the given consumer for the
# existence of the scheme implemented by the G_PART interface handler.
METHOD int probe {
OpenPOWER on IntegriCloud