Commit 2b120b0b authored by Josh Kunz's avatar Josh Kunz

Add insert callback

parent 3e09a664
Pipeline #622 passed with stage
......@@ -554,6 +554,46 @@ int cap_cnode_verify(struct cspace *cspace, cptr_t c)
cptr_t cap_cnode_cptr(struct cnode *cnode) { return cnode->cptr; }
/* Get the type ops for the given cnode. If no type ops can be found,
* an error message is printed and NULL is returned. */
static struct cap_type_ops * __cap_cnode_type_ops(struct cnode *cnode) {
if (cnode->type < CAP_TYPE_FIRST_NONBUILTIN || cnode->type >= CAP_TYPE_MAX) {
CAP_ERR("invalid object type %d -- BUG!", cnode->type);
return NULL;
}
struct cap_type_ops * ops = &cnode->cspace->ts->types[cnode->type];
if (! ops->name) {
CAP_ERR("invalid object type %d -- BUG!", cnode->type);
return NULL;
}
return ops;
}
static int __cap_notify_insert(struct cnode *c) {
struct cap_type_ops *ops = __cap_cnode_type_ops(c);
if (ops && ops->insert) { return ops->insert(c); }
return 0;
}
/*
* Mark cnode as free, null out fields.
*
* XXX: We could possibly free up the cnode table if all of its cnodes
* are free. For now, they just hang around and will be freed when
* the whole cspace is torn down.
*/
static void __cap_cnode_mark_free(struct cnode * cnode) {
cnode->type = CAP_TYPE_FREE;
cnode->object = NULL;
cnode->cdt_root = NULL;
cnode->metadata = NULL;
}
int cap_insert(struct cspace *cspace, cptr_t c, void *object, cap_type_t type)
{
struct cnode *cnode;
......@@ -584,36 +624,28 @@ int cap_insert(struct cspace *cspace, cptr_t c, void *object, cap_type_t type)
* Set up cdt
*/
cnode->cdt_root = __cap_cdt_root_create();
if (cnode->cdt_root == NULL) {
// XXX: Not sure if this is correct
return -1;
}
if (cnode->cdt_root == NULL) { goto fail; }
__cap_cdt_root_incref(cnode->cdt_root);
ret = __cap_notify_insert(cnode);
if (ret < 0) { goto fail1; }
finish:
/*
* Release cnode
*/
cap_cnode_put(cnode);
return 0;
}
/* Get the type ops for the given cnode. If no type ops can be found,
* an error message is printed and NULL is returned. */
static struct cap_type_ops * __cap_cnode_type_ops(struct cnode *cnode) {
if (cnode->type < CAP_TYPE_FIRST_NONBUILTIN || cnode->type >= CAP_TYPE_MAX) {
CAP_ERR("invalid object type %d -- BUG!", cnode->type);
return NULL;
}
struct cap_type_ops * ops = &cnode->cspace->ts->types[cnode->type];
if (! ops->name) {
CAP_ERR("invalid object type %d -- BUG!", cnode->type);
return NULL;
}
return ret;
return ops;
fail1:
__cap_cdt_root_decref_no_unlock(cnode->cdt_root);
fail:
__cap_cnode_mark_free(cnode);
ret = -1;
goto finish;
}
static int __cap_notify_delete(struct cnode *cnode) {
......@@ -892,20 +924,6 @@ fail:
return ret;
}
/*
* Mark cnode as free, null out fields.
*
* XXX: We could possibly free up the cnode table if all of its cnodes
* are free. For now, they just hang around and will be freed when
* the whole cspace is torn down.
*/
static void __cap_cnode_mark_free(struct cnode * cnode) {
cnode->type = CAP_TYPE_FREE;
cnode->object = NULL;
cnode->cdt_root = NULL;
cnode->metadata = NULL;
}
/**
* Tries to lock cdt and remove cnode from it. Returns non-zero if
* cnode successfully deleted.
......
......@@ -9,10 +9,10 @@
#define CAP_TYPE_NUM_BUILTIN CAP_TYPE_FIRST_NONBUILTIN
static struct cap_type_ops builtin_cap_types[CAP_TYPE_NUM_BUILTIN] = {
{"none", NULL, NULL, NULL, NULL},
{"invalid", NULL, NULL, NULL, NULL},
{"free", NULL, NULL, NULL, NULL},
{"cnode", NULL, NULL, NULL, NULL},
{"none", NULL, NULL, NULL, NULL, NULL},
{"invalid", NULL, NULL, NULL, NULL, NULL},
{"free", NULL, NULL, NULL, NULL, NULL},
{"cnode", NULL, NULL, NULL, NULL, NULL},
};
int cap_type_system_alloc(struct cap_type_system **ts)
......@@ -91,6 +91,7 @@ cap_type_t cap_register_private_type(struct cap_type_system *ts,
goto out;
} else {
ts->types[i].name = strdup(ops->name);
ts->types[i].insert = ops->insert;
ts->types[i].delete = ops->delete;
ts->types[i].grant = ops->grant;
ts->types[i].derive_src = ops->derive_src;
......
......@@ -73,6 +73,10 @@ struct cnode;
struct cap_type_ops {
char *name;
/* invoked when a new object is inserted into a c-space. The operation
* can be aborted by returning a negative exit status. That status will
* be returned from the cap_X call. Be careful not to overlap exit codes */
int (*insert)(struct cnode *cnode);
/* Invoked when a cnode is deleted. The cptr, cspace, and object associated
* with this cnode can obtained using the cnode accessor functions.
* The operation can be aborted by returning a negative exit status which
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment