1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-20 11:11:24 +00:00

o Implement automatic commit. It's enabled when the flags parameter

exists and contains the 'C' flag.
o  The partition label can be the empty string. It's how labels are
   cleared.
o  When an action fails, lower permissions when they were raised
   in order to allow the action. A failed action will not result
   in any uncommitted changes.
o  Allow the flags paremeter to be present but empty. It's the
   equivalent of not being present.
This commit is contained in:
Marcel Moolenaar 2007-05-15 20:14:55 +00:00
parent e2a77bb8b7
commit 35fe9df032
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169585

View File

@ -592,6 +592,13 @@ g_part_ctl_create(struct gctl_req *req, struct g_part_parms *gpp)
if (null != NULL)
kobj_delete((kobj_t)null, M_GEOM);
/*
* Support automatic commit by filling in the gpp_geom
* parameter.
*/
gpp->gpp_parms |= G_PART_PARM_GEOM;
gpp->gpp_geom = gp;
/* Provide feedback if so requested. */
if (gpp->gpp_parms & G_PART_PARM_OUTPUT) {
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
@ -899,20 +906,20 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
const char *p;
enum g_part_ctl ctlreq;
unsigned int i, mparms, oparms, parm;
int auto_commit, close_on_error;
int error, modifies;
G_PART_TRACE((G_T_TOPOLOGY, "%s(%s,%s)", __func__, mp->name, verb));
g_topology_assert();
ctlreq = G_PART_CTL_NONE;
modifies = 0;
modifies = 1;
mparms = 0;
oparms = G_PART_PARM_FLAGS | G_PART_PARM_OUTPUT | G_PART_PARM_VERSION;
switch (*verb) {
case 'a':
if (!strcmp(verb, "add")) {
ctlreq = G_PART_CTL_ADD;
modifies = 1;
mparms |= G_PART_PARM_GEOM | G_PART_PARM_SIZE |
G_PART_PARM_START | G_PART_PARM_TYPE;
oparms |= G_PART_PARM_INDEX | G_PART_PARM_LABEL;
@ -922,9 +929,9 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
if (!strcmp(verb, "commit")) {
ctlreq = G_PART_CTL_COMMIT;
mparms |= G_PART_PARM_GEOM;
modifies = 0;
} else if (!strcmp(verb, "create")) {
ctlreq = G_PART_CTL_CREATE;
modifies = 1;
mparms |= G_PART_PARM_PROVIDER | G_PART_PARM_SCHEME;
oparms |= G_PART_PARM_ENTRIES;
}
@ -932,34 +939,28 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
case 'd':
if (!strcmp(verb, "delete")) {
ctlreq = G_PART_CTL_DELETE;
modifies = 1;
mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
} else if (!strcmp(verb, "destroy")) {
ctlreq = G_PART_CTL_DESTROY;
modifies = 1;
mparms |= G_PART_PARM_GEOM;
}
break;
case 'm':
if (!strcmp(verb, "modify")) {
ctlreq = G_PART_CTL_MODIFY;
modifies = 1;
mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
oparms |= G_PART_PARM_LABEL | G_PART_PARM_TYPE;
} else if (!strcmp(verb, "move")) {
ctlreq = G_PART_CTL_MOVE;
modifies = 1;
mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
}
break;
case 'r':
if (!strcmp(verb, "recover")) {
ctlreq = G_PART_CTL_RECOVER;
modifies = 1;
mparms |= G_PART_PARM_GEOM;
} else if (!strcmp(verb, "resize")) {
ctlreq = G_PART_CTL_RESIZE;
modifies = 1;
mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
}
break;
@ -967,6 +968,7 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
if (!strcmp(verb, "undo")) {
ctlreq = G_PART_CTL_UNDO;
mparms |= G_PART_PARM_GEOM;
modifies = 0;
}
break;
}
@ -1045,6 +1047,8 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
error = g_part_parm_uint(p, &gpp.gpp_entries);
break;
case G_PART_PARM_FLAGS:
if (p[0] == '\0')
continue;
error = g_part_parm_str(p, &gpp.gpp_flags);
break;
case G_PART_PARM_GEOM:
@ -1054,7 +1058,9 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
error = g_part_parm_uint(p, &gpp.gpp_index);
break;
case G_PART_PARM_LABEL:
error = g_part_parm_str(p, &gpp.gpp_label);
/* An empty label is always valid. */
gpp.gpp_label = p;
error = 0;
break;
case G_PART_PARM_OUTPUT:
error = 0; /* Write-only parameter */
@ -1094,6 +1100,8 @@ 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. */
if (modifies && (gpp.gpp_parms & G_PART_PARM_GEOM)) {
table = gpp.gpp_geom->softc;
if (table != NULL && !table->gpt_opened) {
@ -1105,6 +1113,7 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
return;
}
table->gpt_opened = 1;
close_on_error = 1;
}
}
@ -1143,6 +1152,22 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
error = g_part_ctl_undo(req, &gpp);
break;
}
/* Implement automatic commit. */
if (!error) {
auto_commit = (modifies &&
(gpp.gpp_parms & G_PART_PARM_FLAGS) &&
strchr(gpp.gpp_flags, 'C') != NULL) ? 1 : 0;
if (auto_commit) {
KASSERT(gpp->gpp_parms & G_PART_PARM_GEOM, (__func__));
error = g_part_ctl_commit(req, &gpp);
}
}
if (error && close_on_error) {
g_access(LIST_FIRST(&gpp.gpp_geom->consumer), -1, -1, -1);
table->gpt_opened = 0;
}
}
static int